12.6. Communications Commands

Certain of the following commands find use in chasing spammers, as well as in network data transfer and analysis.

Information and Statistics

host

Searches for information about an Internet host by name or IP address, using DNS.

 bash$ host surfacemail.com
 surfacemail.com. has address 202.92.42.236
 	      

ipcalc

Displays IP information for a host. With the -h option, ipcalc does a reverse DNS lookup, finding the name of the host (server) from the IP address.

 bash$ ipcalc -h 202.92.42.236
 HOSTNAME=surfacemail.com
 	      

nslookup

Do an Internet "name server lookup" on a host by IP address. This is essentially equivalent to ipcalc -h or dig -x . The command may be run either interactively or noninteractively, i.e., from within a script.

The nslookup command has allegedly been "deprecated," but it still has its uses.

 bash$ nslookup -sil 66.97.104.180
 nslookup kuhleersparnis.ch
 Server:         135.116.137.2
 Address:        135.116.137.2#53

 Non-authoritative answer:
 Name:   kuhleersparnis.ch
 	      

dig

Domain Information Groper. Similar to nslookup, dig does an Internet "name server lookup" on a host. May be run either interactively or noninteractively, i.e., from within a script.

Some interesting options to dig are +time=N for setting a query timeout to N seconds, +nofail for continuing to query servers until a reply is received, and -x for doing a reverse address lookup.

Compare the output of dig -x with ipcalc -h and nslookup.

 bash$ dig -x 81.9.6.2
 ;; Got answer:
 ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 11649
 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0

 ;; QUESTION SECTION:
 ;2.6.9.81.in-addr.arpa.         IN      PTR

 ;; AUTHORITY SECTION:
 6.9.81.in-addr.arpa.    3600    IN      SOA     ns.eltel.net. noc.eltel.net.
 2002031705 900 600 86400 3600

 ;; Query time: 537 msec
 ;; SERVER: 135.116.137.2#53(135.116.137.2)
 ;; WHEN: Wed Jun 26 08:35:24 2002
 ;; MSG SIZE  rcvd: 91
 	      


Example 12-35. Checking a spam domain

   1 #! /bin/bash
   2 # is-spammer.sh: Identifying spam domains
   3 
   4 # $Id: is-spammer, v 1.4 2004/09/01 19:37:52 mszick Exp $
   5 # Above line is RCS ID info.
   6 #
   7 #  This is a simplified version of the "is_spammer.bash
   8 #+ script in the Contributed Scripts appendix.
   9 
  10 # is-spammer <domain.name>
  11 
  12 # Uses an external program: 'dig'
  13 # Tested with version: 9.2.4rc5
  14 
  15 # Uses functions.
  16 # Uses IFS to parse strings by assignment into arrays.
  17 # And even does something useful: checks e-mail blacklists.
  18 
  19 # Use the domain.name(s) from the text body:
  20 # http://www.good_stuff.spammer.biz/just_ignore_everything_else
  21 #                       ^^^^^^^^^^^
  22 # Or the domain.name(s) from any e-mail address:
  23 # Really_Good_Offer@spammer.biz
  24 #                   ^^^^^^^^^^^
  25 # as the only argument to this script.
  26 #(PS: have your Inet connection running)
  27 #
  28 # So, to invoke this script in the above two instances:
  29 #       is-spammer.sh spammer.biz
  30 
  31 
  32 # Whitespace == :Space:Tab:Line Feed:Carriage Return:
  33 WSP_IFS=$'\x20'$'\x09'$'\x0A'$'\x0D'
  34 
  35 # No Whitespace == Line Feed:Carriage Return
  36 No_WSP=$'\x0A'$'\x0D'
  37 
  38 # Field separator for dotted decimal ip addresses
  39 ADR_IFS=${No_WSP}'.'
  40 
  41 # Get the dns text resource record
  42 # get_txt <error_code> <list_query>
  43 get_txt() {
  44 
  45     # parse $1 by assignment at the dots
  46     local -a dns
  47     IFS=$ADR_IFS
  48     dns=( $1 )
  49     IFS=$WSP_IFS
  50     if [ "${dns[0]}" == '127' ]
  51     then
  52         # see if there is a reason
  53         echo $(dig +short $2 -t txt)
  54     fi
  55 }
  56 
  57 # Get the dns address resource record
  58 # chk_adr <rev_dns> <list_server>
  59 chk_adr() {
  60     local reply
  61     local server
  62     local reason
  63 
  64     server=${1}${2}
  65     reply=$( dig +short ${server} )
  66 
  67     # if reply might be an error code . . .
  68     if [ ${#reply} -gt 6 ]
  69     then
  70         reason=$(get_txt ${reply} ${server} )
  71         reason=${reason:-${reply}}
  72     fi
  73     echo ${reason:-' not blacklisted.'}
  74 }
  75 
  76 # Need to get the IP address from the name.
  77 echo 'Get address of: '$1
  78 ip_adr=$(dig +short $1)
  79 dns_reply=${ip_adr:-' no answer '}
  80 echo ' Found address: '${dns_reply}
  81 
  82 # A valid reply is at least 4 digits plus 3 dots.
  83 if [ ${#ip_adr} -gt 6 ]
  84 then
  85     echo
  86     declare query
  87 
  88     # Parse by assignment at the dots.
  89     declare -a dns
  90     IFS=$ADR_IFS
  91     dns=( ${ip_adr} )
  92     IFS=$WSP_IFS
  93 
  94     # Reorder octets into dns query order.
  95     rev_dns="${dns[3]}"'.'"${dns[2]}"'.'"${dns[1]}"'.'"${dns[0]}"'.'
  96 
  97 # See: http://www.spamhaus.org (Conservative, well maintained)
  98     echo -n 'spamhaus.org says: '
  99     echo $(chk_adr ${rev_dns} 'sbl-xbl.spamhaus.org')
 100 
 101 # See: http://ordb.org (Open mail relays)
 102     echo -n '   ordb.org  says: '
 103     echo $(chk_adr ${rev_dns} 'relays.ordb.org')
 104 
 105 # See: http://www.spamcop.net/ (You can report spammers here)
 106     echo -n ' spamcop.net says: '
 107     echo $(chk_adr ${rev_dns} 'bl.spamcop.net')
 108 
 109 # # # other blacklist operations # # #
 110 
 111 # See: http://cbl.abuseat.org.
 112     echo -n ' abuseat.org says: '
 113     echo $(chk_adr ${rev_dns} 'cbl.abuseat.org')
 114 
 115 # See: http://dsbl.org/usage (Various mail relays)
 116     echo
 117     echo 'Distributed Server Listings'
 118     echo -n '       list.dsbl.org says: '
 119     echo $(chk_adr ${rev_dns} 'list.dsbl.org')
 120 
 121     echo -n '   multihop.dsbl.org says: '
 122     echo $(chk_adr ${rev_dns} 'multihop.dsbl.org')
 123 
 124     echo -n 'unconfirmed.dsbl.org says: '
 125     echo $(chk_adr ${rev_dns} 'unconfirmed.dsbl.org')
 126 
 127 else
 128     echo
 129     echo 'Could not use that address.'
 130 fi
 131 
 132 exit 0
 133 
 134 # Exercises:
 135 # --------
 136 
 137 # 1) Check arguments to script,
 138 #    and exit with appropriate error message if necessary.
 139 
 140 # 2) Check if on-line at invocation of script,
 141 #    and exit with appropriate error message if necessary.
 142 
 143 # 3) Substitute generic variables for "hard-coded" BHL domains.
 144 
 145 # 4) Set a time-out for the script using the "+time=" option
 146      to the 'dig' command.

For a much more elaborate version of the above script, see Example A-25.

traceroute

Trace the route taken by packets sent to a remote host. This command works within a LAN, WAN, or over the Internet. The remote host may be specified by an IP address. The output of this command may be filtered by grep or sed in a pipe.

 bash$ traceroute 81.9.6.2
 traceroute to 81.9.6.2 (81.9.6.2), 30 hops max, 38 byte packets
 1  tc43.xjbnnbrb.com (136.30.178.8)  191.303 ms  179.400 ms  179.767 ms
 2  or0.xjbnnbrb.com (136.30.178.1)  179.536 ms  179.534 ms  169.685 ms
 3  192.168.11.101 (192.168.11.101)  189.471 ms  189.556 ms *
 ...
 	      

ping

Broadcast an "ICMP ECHO_REQUEST" packet to another machine, either on a local or remote network. This is a diagnostic tool for testing network connections, and it should be used with caution.

A successful ping returns an exit status of 0. This can be tested for in a script.

 bash$ ping localhost
 PING localhost.localdomain (127.0.0.1) from 127.0.0.1 : 56(84) bytes of data.
 Warning: time of day goes back, taking countermeasures.
 64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=0 ttl=255 time=709 usec
 64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=1 ttl=255 time=286 usec

 --- localhost.localdomain ping statistics ---
 2 packets transmitted, 2 packets received, 0% packet loss
 round-trip min/avg/max/mdev = 0.286/0.497/0.709/0.212 ms
 	      

whois

Perform a DNS (Domain Name System) lookup. The -h option permits specifying which particular whois server to query. See Example 4-6.

finger

Retrieve information about users on a network. Optionally, this command can display a user's ~/.plan, ~/.project, and ~/.forward files, if present.

 bash$ finger
 Login  Name           Tty      Idle  Login Time   Office     Office Phone
 bozo   Bozo Bozeman   tty1        8  Jun 25 16:59
 bozo   Bozo Bozeman   ttyp0          Jun 25 16:59
 bozo   Bozo Bozeman   ttyp1          Jun 25 17:07
 
 
 
 bash$ finger bozo
 Login: bozo                             Name: Bozo Bozeman
 Directory: /home/bozo                   Shell: /bin/bash
 Office: 2355 Clown St., 543-1234
 On since Fri Aug 31 20:13 (MST) on tty1    1 hour 38 minutes idle
 On since Fri Aug 31 20:13 (MST) on pts/0   12 seconds idle
 On since Fri Aug 31 20:13 (MST) on pts/1
 On since Fri Aug 31 20:31 (MST) on pts/2   1 hour 16 minutes idle
 No mail.
 No Plan.
 	      

Out of security considerations, many networks disable finger and its associated daemon. [1]

chfn

Change information disclosed by the finger command.

vrfy

Verify an Internet e-mail address.

Remote Host Access

sx, rx

The sx and rx command set serves to transfer files to and from a remote host using the xmodem protocol. These are generally part of a communications package, such as minicom.

sz, rz

The sz and rz command set serves to transfer files to and from a remote host using the zmodem protocol. Zmodem has certain advantages over xmodem, such as faster transmission rate and resumption of interrupted file transfers. Like sx and rx, these are generally part of a communications package.

ftp

Utility and protocol for uploading / downloading files to or from a remote host. An ftp session can be automated in a script (see Example 17-6, Example A-4, and Example A-13).

uucp

UNIX to UNIX copy. This is a communications package for transferring files between UNIX servers. A shell script is an effective way to handle a uucp command sequence.

Since the advent of the Internet and e-mail, uucp seems to have faded into obscurity, but it still exists and remains perfectly workable in situations where an Internet connection is not available or appropriate.

cu

Call Up a remote system and connect as a simple terminal. This command is part of the uucp package. It is a sort of dumbed-down version of telnet.

telnet

Utility and protocol for connecting to a remote host.

Caution

The telnet protocol contains security holes and should therefore probably be avoided.

wget

The wget utility non-interactively retrieves or downloads files from a Web or ftp site. It works well in a script.
   1 wget -p http://www.xyz23.com/file01.html
   2 wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE


Example 12-36. Getting a stock quote

   1 #!/bin/bash
   2 # quote-fetch.sh: Download a stock quote.
   3 
   4 
   5 E_NOPARAMS=66
   6 
   7 if [ -z "$1" ]  # Must specify a stock (symbol) to fetch.
   8   then echo "Usage: `basename $0` stock-symbol"
   9   exit $E_NOPARAMS
  10 fi
  11 
  12 stock_symbol=$1
  13 
  14 file_suffix=.html
  15 # Fetches an HTML file, so name it appropriately.
  16 URL='http://finance.yahoo.com/q?s='
  17 # Yahoo finance board, with stock query suffix.
  18 
  19 # -----------------------------------------------------------
  20 wget -O ${stock_symbol}${file_suffix} "${URL}${stock_symbol}"
  21 # -----------------------------------------------------------
  22 
  23 exit $?
  24 
  25 # Exercises:
  26 # ---------
  27 #
  28 # 1) Add a test to ensure the user running the script is on-line.
  29 #    (Hint: parse the output of 'ps -ax' for "ppp" or "connect."
  30 #
  31 # 2) Modify this script to fetch the local weather report,
  32 #+   taking the user's zip code as an argument.

lynx

The lynx Web and file browser can be used inside a script (with the -dump option) to retrieve a file from a Web or ftp site non-interactively.
   1 lynx -dump http://www.xyz23.com/file01.html >$SAVEFILE

rlogin

Remote login, initates a session on a remote host. This command has security issues, so use ssh instead.

rsh

Remote shell, executes command(s) on a remote host. This has security issues, so use ssh instead.

rcp

Remote copy, copies files between two different networked machines. Using rcp and similar utilities with security implications in a shell script may not be advisable. Consider, instead, using ssh or an expect script.

ssh

Secure shell, logs onto a remote host and executes commands there. This secure replacement for telnet, rlogin, rcp, and rsh uses identity authentication and encryption. See its manpage for details.


Example 12-37. Using ssh

   1 #!/bin/bash
   2 # remote.bash: Using ssh.
   3 
   4 # This example by Michael Zick.
   5 # Used with permission.
   6 
   7 
   8 #   Presumptions:
   9 #   ------------
  10 #   fd-2 isn't being captured ( '2>/dev/null' ).
  11 #   ssh/sshd presumes stderr ('2') will display to user.
  12 #
  13 #   sshd is running on your machine.
  14 #   For any 'standard' distribution, it probably is,
  15 #+  and without any funky ssh-keygen having been done.
  16 
  17 # Try ssh to your machine from the command line:
  18 #
  19 # $ ssh $HOSTNAME
  20 # Without extra set-up you'll be asked for your password.
  21 #   enter password
  22 #   when done,  $ exit
  23 #
  24 # Did that work? If so, you're ready for more fun.
  25 
  26 # Try ssh to your machine as 'root':
  27 #
  28 #   $  ssh -l root $HOSTNAME
  29 #   When asked for password, enter root's, not yours.
  30 #          Last login: Tue Aug 10 20:25:49 2004 from localhost.localdomain
  31 #   Enter 'exit' when done.
  32 
  33 #  The above gives you an interactive shell.
  34 #  It is possible for sshd to be set up in a 'single command' mode,
  35 #+ but that is beyond the scope of this example.
  36 #  The only thing to note is that the following will work in
  37 #+ 'single command' mode.
  38 
  39 
  40 # A basic, write stdout (local) command.
  41 
  42 ls -l
  43 
  44 # Now the same basic command on a remote machine.
  45 # Pass a different 'USERNAME' 'HOSTNAME' if desired:
  46 USER=${USERNAME:-$(whoami)}
  47 HOST=${HOSTNAME:-$(hostname)}
  48 
  49 #  Now excute the above command line on the remote host,
  50 #+ with all transmissions encrypted.
  51 
  52 ssh -l ${USER} ${HOST} " ls -l "
  53 
  54 #  The expected result is a listing of your username's home
  55 #+ directory on the remote machine.
  56 #  To see any difference, run this script from somewhere
  57 #+ other than your home directory.
  58 
  59 #  In other words, the Bash command is passed as a quoted line
  60 #+ to the remote shell, which executes it on the remote machine.
  61 #  In this case, sshd does  ' bash -c "ls -l" '   on your behalf.
  62 
  63 #  For information on topics such as not having to enter a
  64 #+ password/passphrase for every command line, see
  65 #+    man ssh
  66 #+    man ssh-keygen
  67 #+    man sshd_config.
  68 
  69 exit 0

Local Network

write

This is a utility for terminal-to-terminal communication. It allows sending lines from your terminal (console or xterm) to that of another user. The mesg command may, of course, be used to disable write access to a terminal

Since write is interactive, it would not normally find use in a script.

Mail

mail

Send or read e-mail messages.

This stripped-down command-line mail client works fine as a command embedded in a script.


Example 12-38. A script that mails itself

   1 #!/bin/sh
   2 # self-mailer.sh: Self-mailing script
   3 
   4 adr=${1:-`whoami`}     # Default to current user, if not specified.
   5 #  Typing 'self-mailer.sh wiseguy@superdupergenius.com'
   6 #+ sends this script to that addressee.
   7 #  Just 'self-mailer.sh' (no argument) sends the script
   8 #+ to the person invoking it, for example, bozo@localhost.localdomain.
   9 #
  10 #  For more on the ${parameter:-default} construct,
  11 #+ see the "Parameter Substitution" section
  12 #+ of the "Variables Revisited" chapter.
  13 
  14 # ============================================================================
  15   cat $0 | mail -s "Script \"`basename $0`\" has mailed itself to you." "$adr"
  16 # ============================================================================
  17 
  18 # --------------------------------------------
  19 #  Greetings from the self-mailing script.
  20 #  A mischievous person has run this script,
  21 #+ which has caused it to mail itself to you.
  22 #  Apparently, some people have nothing better
  23 #+ to do with their time.
  24 # --------------------------------------------
  25 
  26 echo "At `date`, script \"`basename $0`\" mailed to "$adr"."
  27 
  28 exit 0

mailto

Similar to the mail command, mailto sends e-mail messages from the command line or in a script. However, mailto also permits sending MIME (multimedia) messages.

vacation

This utility automatically replies to e-mails that the intended recipient is on vacation and temporarily unavailable. This runs on a network, in conjunction with sendmail, and is not applicable to a dial-up POPmail account.

Notes

[1]

A daemon is a background process not attached to a terminal session. Daemons perform designated services either at specified times or explicitly triggered by certain events.

The word "daemon" means ghost in Greek, and there is certainly something mysterious, almost supernatural, about the way UNIX daemons silently wander about behind the scenes, carrying out their appointed tasks.