home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Previous Section Next Section

12.5 Putting It All Together: An Example

The following examples use DNS hostnames for clarity. However, in general, it is more secure to use TCP Wrappers with explicit IP addresses.

Suppose that you want to allow all connections to your computer, except those from the computers in the domain pirate.net, with a simple /etc/hosts.allow file. Specify:

#
# /etc/hosts.allow:
#
# Allow anybody to connect to our machine except people from pirate.net.
#
all : .pirate.net : deny
all : all         : allow

Suppose that you want to modify your rules to allow the use of finger from any of your internal machines, but you want to have external finger requests met with a canned message. You might try this configuration file:

#
# /etc/hosts.allow:
#
# Allow finger from internal machines; give banner to others.
# Otherwise, allow anybody to connect except people from pirate.net.
#
#
in.fingerd : LOCAL : allow
in.fingerd : all : twist /usr/local/bin/external_fingerd_message
all : .pirate.net : deny
all : all : allow

If you don't want to allow pirate.net hosts to finger at all, reverse the order of the second and third rule so that the rules denying pirate.net hosts would match first.

If you discover repeated break-in attempts through telnet and rlogin from all over the world, but you have a particular user who needs to telnet into your computer from the host sleepy.com, you could accomplish this somewhat more complex security requirement with the following configuration file:

#
# /etc/hosts.allow:
#
# Allow email from pirate.net, but nothing else.
# Allow telnet and rlogin from sleepy.com, but nowhere else.
#
telnetd,rlogind : sleepy.com : allow
telnetd,rlogind : all : deny
in.fingerd : LOCAL : allow
in.fingerd : all : twist /usr/local/bin/external_fingerd_message
all : .pirate.net : deny
all : all : allow

Better yet, teach that user to use ssh instead of telnet or rlogin, and disable the telnet and rlogin daemons entirely in /etc/inetd.conf:

#
# /etc/hosts.allow:
#
# Allow email from pirate.net, but nothing else.
# Allow ssh from sleepy.com, but nowhere else.
# telnetd and rlogind are disabled in /etc/inetd.conf, but we list them
# here anyway in case someone accidentally re-enables them. This may cause
# tcpdchk to produce a warning, though.
#
sshd : sleepy.com : allow
sshd : all : deny
in.fingerd : LOCAL : allow
in.fingerd : all : twist /usr/local/bin/external_fingerd_message
all : .pirate.net : deny
telnetd,rlogind : all : deny
all : all : allow

Here's an example that combines two possible options:

#
# /etc/hosts.deny:
#
# Don't allow logins from pirate.net and log attempts.
#
telnetd,rlogind,sshd : pirate.net : \
    spawn=(/security/logit %d deny %c %p %a %h %u)&\ 
        : linger 10 : banners /security/banners

In the file /security/banners/telnetd, you would have the following text:

This machine is owned and operated by the Big Whammix Corporation for the exclusive use of Big Whammix Corporation employees. Your attempt to access this machine is not allowed.

Access to Big Whammix Corporation computers is logged and monitored. If you use or attempt to use a Big Whammix computer system, you consent to such monitoring and to adhere to Big Whammix Corporation policies about appropriate use. If you do not agree, then do not attempt use of these systems. Unauthorized use of Big Whammix Corporation computers may be in violation of state or federal law, and may be prosecuted.

If you have any questions about this message or policy, contact <security@bwammix.com> or call during EST business hours: 1-800-555-3662.

The file should also be linked to /security/banners/rlogind and /security/banners/sshd. The banner will be displayed if anyone from pirate.net tries to log in over the Internet. The system will pause 10 seconds for the message to be fully displayed before disconnecting.

In the /security/logit shell file, you could have something similar to the script in Example 12-5. This script puts an entry into the syslog about the event, and attempts to raise a very visible alert window on the screen of the security administrator's workstation. Furthermore, it does a reverse finger on the calling host, and for good measure does a netstat and ps on the local machine. This process is done in the event that some mischief is already occurring that hasn't triggered an alarm.

Example 12-5. alert script
#!/bin/ksh

set -o nolog -u -h +a +o bgnice +e -m

#  Capture some information about whatever site is twisting my doorknob.
#  It is probably higher overhead than I need,
#  but...

export PATH=/usr/ucb:/usr/bin:/bin:/usr/etc:/etc

mkdir /tmp/root; chown root /tmp/root; chmod 700 /tmp/root

# Create /tmp/root in case it doesn't exist (chown it in case it does).

print "Subject: Notice\nFrom: operator\n\n$@" | /usr/lib/sendmail security

typeset daemon="$1" status="$2" client="$3" pid=$4 addr=$5 host=$6 user=$7

# For most things, we simply want a notice.
# Unsuccessful attempts are warnings.
# Unsuccessful attempts on special accounts merit an alert.

typeset level=notice

[[ $status != allow ]] && level=warning
[[ $daemon = in.@(rshd|rlogind) && $user = @(root|security) ]] && level=alert

/usr/ucb/logger -t tcpd -p auth.$level "$*" &

umask 037

function mktemp {
    typeset temp=/security/log.$$
    typeset -Z3 suffix=0


    while [[ -a $temp.$suffix ]]
    do
    let suffix+=1
    done

    logfile=$temp.$suffix
    chgrp security $logfile
}

function Indent {
    sed -e 's/^//' >> $logfile
}


exec 3>&1 >>$logfile 2>&1

date
print "Remote host: $host   Remote user: $user"

print ""
print "Local processes:"
ps axg | Indent

print ""
print "Local network connections:"
netstat -n -a -f inet | Indent

print ""
print "Finger of $host"
safe_finger -s @$host|Indent
print ""
[[ $user != unknown ]] && safe_finger -h -p -m $user@$host | Indent


exec >> /netc/log/$daemon.log 2>&1
print "-----------------------"
print "\npid=$pid client=$client addr=$addr user=$user"
print Details in $logfile
date
print ""


# Now bring up an alert box on the admin's workstation.

{
  print "\ndaemon=$daemon client=$client addr=$addr user=$user"
  print Details in $logfile
  date
  print ""
  print -n "(press return to close window.)" >> /tmp/root/alert.$$ 
} > /tmp/root/alert.$$

integer lines=$(wc -l < /tmp/root/alert.$$ | tr -d ' ')

xterm -display security:0  -fg white -bg red -fn 9x15 -T "ALERT" -fn 9x15B\
   -geom 60x$lines+20+20 -e sh -c "cat /tmp/root/alert.$$;read nothing"
/bin/rm /tmp/root/alert.$$

Note the -n option to the netstat command in the script. This is specified because DNS can be slow to resolve all the IP numbers to names. You want the command to complete before the connection is dropped; it is always possible to look up the hostnames later from the log file. In addition, reverse DNS servers under the control of the attacker might be gimmicked to give misleading information.

    Previous Section Next Section