Chapter 11. Unix Defense

Unix is the operating system that was reborn from the ashes of MULTICS OS toward the end of the 1960s. Ken Thompson and Dennis Ritchie (the creators of the C programming language) wrote the first version for a spare PDP-7 computer they had found. Unlike the failed MULTICS, which ARPA in part paid for and which as a result incorporated many novel security features (including a multilevel security design), Unix, as a hobby project, had no security features whatsoever. MULTICS was designed as a B2-rated system according to TCSEC evaluation (now known as Common Criteria), whereas Unix was originally designed to run a Star Trek game. It is well known that Unix was not designed for security. Unix soon became a multiuser system, and the designers were forced to introduce mechanisms to maintain the appropriate separation between users. We discuss most Unix security features in this chapter. However, please note that these features serve other useful purposes as well. As with a skilled fighter who can use any object as a weapon (e.g., chopsticks), Unix technology has many “dual-use” features that can also perform peaceful tasks, such as performance tuning or hardware troubleshooting, as well as attack detection. We first present a high-level overview of Unix security, and then dive into specific enforcement mechanisms.

For the purpose of this book, Unix refers to many types of Unix, including Linux, Solaris, SunOS, IRIX, AIX, HP-UX, FreeBSD, NetBSD, OpenBSD, and any of the other less well-known flavors. In this chapter, we cover security features common to most (if not all) Unix flavors. Later in this chapter, we discuss specific security features of some of the more popular flavors.

Unix Passwords

Where does Unix begin? At the password prompt, of course:

pua:~$telnet host.example.edu
Trying 111.11.1.1...
Connected to host.example.edu
Escape character is '^]'.

SunOS 5.8

login: user
Password:

This example demonstrates the password prompt for remote connection via telnet. Of course, you almost never use plain-text telnet nowadays, due to the threat of sniffing and session injection; Secure Shell (SSH) is a must-have. We did not even type the password while producing the above example, since we do not want the confidential information transmitted across the Internet or even the LAN in plain text. As this example shows, interaction with the Unix console begins with entering the username—“user” in this instance—and the password, which is never shown (for security reasons). However, this might not be exactly the case for remote connections, since public key cryptography can be used instead of a password. With SSH, for example, you can use regular password authentication: the password is transmitted over the wire in encrypted form and then verified by the server. The user who is trying to connect might need to enter a password in order for the client’s SSH software to decrypt the private key. In the latter case, the password is never transmitted anywhere (even in the encrypted form) and is only used locally, to decrypt the private key from its encrypted storage.

The username identifies a separate environment (home directory) given to every authorized user and tracks objects (usually files) owned by the users. The system employs several usernames. “nobody” is typically used to run various processes, such as web servers, with as few privileges as possible. " root” in Unix is a privileged account with total control over a standard Unix system. Functions such as direct memory access, hardware access, process termination, and kernel patching are all within root’s powers. In Unix, the username and password pair is used as a form of authentication. After a user enters a password, it is encrypted and compared to a string stored in a special file. In older versions of the operating system, the password was stored in the /etc/passwd file; in modern Unix systems, it’s in /etc/shadow (or /etc/master.passwd and /etc/passwd, for NetBSD, FreeBSD, and OpenBSD). Consider the following example excerpted from a Solaris password file:

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:
daemon:x:2:2:daemon:/sbin:
adm:x:3:4:adm:/var/adm:
lp:x:4:7:lp:/var/spool/lpd:
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:
uucp:x:10:14:uucp:/var/spool/uucp:
operator:x:11:0:operator:/root:
games:x:12:100:games:/usr/games:
gopher:x:13:30:gopher:/usr/lib/gopher-data:
ftp:x:14:50:FTP User:/var/ftp:
nobody:x:99:99:Nobody:/:
user:x:500:500:Some User:/home/user:/bin/sh

As you can see, the file stores the username, encrypted[1] password or placeholder (in case shadow passwords are used), numeric user ID and group ID, user’s real name, home directory, and preferred command interpreter (shell). This user ID gives the root user its superpowers: an account with UID = 0 is a superuser no matter what it is called on a particular computer.

The following example is a sample /etc/shadow file:

root:$1$Z/s45h83hduq9562jgpwj486nf83nr0:11481:0:99999:7:::
bin:*:11348:0:99999:7:::
daemon:*:11348:0:99999:7:::
adm:*:11348:0:99999:7:::
lp:*:11348:0:99999:7:::
sync:*:11348:0:99999:7:::
shutdown:*:11348:0:99999:7:::
halt:*:11348:0:99999:7:::

It is important to note the presence of a password for root and the absence of such for other accounts. Accounts such as “daemon”, “adm”, and others are used not by real users, but rather by the system. The numbers after the usernames are related to password expiration and complexity policy.

The main difference between using /etc/passwd with encrypted passwords versus using a combination of /etc/passwd and /etc/shadow is that /etc/passwd must be readable for all users on a Unix system. Many programs use /etc/passwd to map usernames into numeric user IDs, determine real-life names based on username, and perform many other functions. Many of the programs that need access to /etc/passwd do not run with root privileges. Having the /etc/passwd file open can allow attackers to acquire the encrypted passwords and use a brute force attack to derive the plain-text versions.

The encrypted string in the previous example of the /etc/passwd file excerpt (in the “root” line) is not the actual encrypted password; rather, it is a block of data encrypted using a special encryption algorithm with the password as an encryption key. Classic Unix uses the DES algorithm, while several newer flavors, such as Linux, use MD5. The main difference between these algorithms is the strength of the cipher and the resulting length of the password. Since DES is a 56-bit cipher, the maximum useful key length does not exceed 8 characters. The password encryption program takes the lowest 7 bits of each of the first 8 characters of your password to construct a 56-bit key, which is used repeatedly in order to encrypt a string of zeros into a 14-character string present in the /etc/passwd file. Two random characters, or salt , are added to each password to increase randomness and confound a brute force attack that uses precomputed lists of encrypted strings. Thus, standard Unix passwords can only be eight characters or less. MD5, on the other hand, can theoretically support unlimited length. Some implementations of MD5 Unix passwords use 256 characters as a maximum length.

MD5 is known as a hash algorithm . It uses a one-way function, which results in theoretically undecipherable passwords, since the information is lost in the hashing process. These passwords can only be brute forced by trying various password strings and comparing them with the string obtained from the password file. It should also be noted that MD5 is more computation-intense than DES. Thus, brute force attacks take longer. However, the strength of the encrypted password depends on the choice of the unencrypted password. Since attackers possess huge lists of dictionary words in many languages (for some reason Unix passwords seem very susceptible to Star Trek word lists), it is dangerous to use a common word as a password.

In fact, using a dictionary word even as a part of your password is unwise. Several cracking programs, such as the classic tool known as John the Ripper, can transform a dictionary word by adding one or two numbers or special characters. Password-cracking libraries that can be used to stress-test the passwords (such as cracklib) also exist and might be integrated with Linux pluggable authentication modules. For example, after trying “dog”, the program will try “dog12”, “do!?g”, and so on. This process usually finds a password much faster than simply trying random combinations of characters.

Conversely, if the system administrator enforces use of passwords like “jhf/i3:26g?w70f”, users will invariably write them on Post-it notes stuck to their monitors, thus totally defeating the security of the password authentication. The best password is easy to remember, but difficult to guess. And even the best passwords need to be changed regularly. Some Unix systems (AIX, Linux, Solaris) use dubious proprietary extensions that enforce the length and the expiration time for all passwords and even keep a history of used passwords to prevent users from switching between two favorites. However, these extensions are not standard Unix and are not covered here.

Another file related to the user environment is /etc/group. This file defines users who belong to various groups. Here is an example of such a file from a modern Linux system:

root:x:0:root
bin:x:1:root,bin,daemon
daemon:x:2:root,bin,daemon
sys:x:3:root,bin,adm
adm:x:4:root,adm,daemon
tty:x:5:
disk:x:6:root
lp:x:7:daemon,lp
mem:x:8:
kmem:x:9:
wheel:x:10:root
mail:x:12:mail,postfix

The file contains group names and passwords (which are almost never used, so “x” serves as a placeholder) and lists group members.

Grouping users makes access control more flexible by allowing specific access levels (read, write, and execute) to the owner, group members, and other users. Grouping can also be used for authorization and in order to simplify system security administration.

Different Unix flavors use different files for storing such information. Table 11-1 provides a summary.

Table 11-1. Password files used by different Unix flavors

Unix variant

Password files

Linux

/etc/passwd, /etc/shadow

Solaris

/etc/passwd, /etc/shadow

FreeBSD

/etc/master.passwd, /etc/passwd

NetBSD

/etc/master.passwd, /etc/passwd

OpenBSD

/etc/master.passwd, /etc/passwd

HP-UX

/etc/passwd, /etc/shadow

RIX

/etc/passwd, /etc/shadow

File Permissions

Some files are readable by all users, while others are restricted. This is achieved by a system of permissions known as discretionary access control (DAC).[2] Unix flavors use different filesystems (ufs, ext2, and several others), and they all implement the file permissions as follows:

drwx------   2 user 19449        512 Mar 23  2000 bin
-rw-r--r--   1 user 19449      34040 Jun 18 03:10 bookmark.htm

In this example, the directory bin is readable and searchable exclusively by the owner, and only the owner can create new files there. On the other hand, the file bookmark.htm is readable by all users.

The following example shows all possible permissions:

d  rwxt rwx rwx
- type 
   ---- owner
        --- group
             --- others

In this example, “d” is the type of object (“-” is used to denote files, “d” indicates directories, “l” means links, “s” indicates sockets). Permissions are intuitive for files (the owner, group, or others can read, write, and execute a file), but for directories, things can be cryptic. For example, the execute bit for directories means that it is possible to access files in the directory, but not to see the directory listing itself. The latter is controlled by the read bit. In contrast, the write bit allows the creation and removal of files in the directory. To set these permissions, use the Unix command chmod . The typical chmod command line may be in one of two forms: numeric or alphabetic characters. The numeric mode is determined by the 3-digit number (consisting of octal digits),[3] and the individual access rights (0 = none, 1 = execute, 2 = write, 4 = read) are combined: 764, for instance, means that read, execute, and write functions are allowed for the owner, read and write are allowed for the group members, and only read is allowed for others. The following chmod commands are equivalent (assuming file permissions were set to 000, which is almost never the case):

chmod 600 test.txt  
chmod u=rw test.txt

The default permissions for all newly created files are set by the umask command. The umask is set to a 3-digit number, such as 077. The umask number is subtracted from the default permissions; thus, if the umask is set to 177, all new files are created with read and write rights for the owner and no rights for others (which is a good idea when using umask).

The SUID bit is another attribute that you can set on files. For executable files, it simply means that when the file is executed, the resulting process will run with the owner’s permissions and not with the permissions of the person launching the file. The SGID bit is similar: it modifies the running file’s group permissions. It is sometimes used by the mail daemon to add mail to user mail spools, which are owned by individual users; the group ownership is “mail”. SUID root files are considered a great security risk. Further, if they are abused by one of several methods, the attacker may obtain a root-owned shell or gain the ability to execute a command as root. SUID shell scripts are an even greater risk, because they are much easier to abuse. In fact, some Unix flavors prohibit setting the SUID bit on shell scripts.

The sticky bit set on a directory usually modifies the particular behavior of a file in the directory (some Unix flavors deviate here). When the directory sticky bit is set, users are able to create and modify files within this directory, but they can only delete files that they themselves created. This is used on the /tmp directory, where this kind of behavior is required.

On some Unix systems, the default file and directory permissions are insecure. In other words, some files are accessible by a wider audience than necessary. Historically, this behavior has been severe enough to be considered a bug. For example, on early SunOS systems, logfiles were writable for all users. This characteristic allowed malicious hackers to clean up all traces of their attacks. In addition, vendors often ship programs with an unnecessary SUID root bit set, significantly increasing the risk of abuse. Thus, carefully adjusting default permissions should be part of any system-hardening process.

Attributes and Capabilities

File permissions for users, groups, and others authorize access to objects. Access to files and directories can thus be given to certain users (group members only) and withdrawn from others. While this method of access control can be very effective, such granularity is only achieved by making users members of many groups. Managing such a system quickly becomes nightmarish. However, granular access control is sometimes needed. Unlike with Windows (which has Active Directory), there is no universal Unix method to implement this level of control, but since this security feature is important, we briefly touch upon Solaris. The capabilities of Solaris, AIX, and other Unix flavors differ greatly from vendor to vendor. It is possible to make a file readable by “user1” and “user2” and writable by “user3”.

On Solaris 8, the getfacl and setfacl commands are used to enable and set extended permissions. They are implemented as a complicated list of access control rules called an access control list (ACL). We can see a detailed picture of standard Unix permissions, since capabilities are implemented as an extension of the permissions.

$ getfacl bookmark.htm
# file: bookmark.htm
# owner: user
# group: 19449
user::rw-
group::r--              #effective:r--
mask:r--
other:r--

Now, let’s apply the new access control list, as follows:

$ setfacl -m user:friend:rwx /usr/local/bin/nmap

This command gives the user “friend” the ability to read, write, and execute the file /usr/local/bin/nmap. The modified extended permissions are:

$ getfacl /usr/local/bin/nmap
# file: /usr/local/bin/nmap
# owner: user
# group: 19449
user::rw-
user:friend:rwx               #effective:r--
group::r--                    #effective:r--
mask:r--
other:r--

The standard Unix permissions are as follows:

-rw-r--r--+  1 anton 19449      34040 Jun 18 03:10 /usr/local/bin/nmap

The plus sign (+) indicates that enhanced permissions are in use.

Linux supports another system (called file attributes ) that can block even root from accessing the file. Files can be designated as unchangeable, undeletable, and append-only, along with other unusual properties. This feature has been available since Version 2.2 of the Linux kernel. For more details on these capabilities, see Section 11.7 at the end of the chapter.

System Logging

Unix acquired a system-logging function early in its development. System logging is implemented as a syslog daemon[4] that receives messages sent by various programs running on the system. In addition, other computer and network devices, such as routers, can send log messages to the logging server. System logging is extremely valuable for many purposes, from troubleshooting hardware to tracking malicious attacks—provided somebody is actually reading the system logfiles. Here’s an excerpt showing several messages received by a syslog daemon on the machine “examhost”. The logfile records the date and time of the message, the name of the computer that sent it, the program that produced the message, and the text itself:

Dec 13 10:19:10 examhost sshd[470]: Generating new 768 bit RSA key.
Dec 13 10:19:11 examhost sshd[470]: RSA key generation complete.
Dec 13 10:20:19 examhost named[773]: sysquery: findns error (NXDOMAIN) on dns.
example.edu?
Dec 13 10:21:01 examhost last message repeated 4 times
Dec 13 10:26:17 examhost sshd[20505]: Accepted password for user from 24.147.219.231 
port 1048 ssh2
Dec 13 10:26:17 examhost PAM_unix[20505]: (system-auth) session opened for user anton 
by (uid=0)
Dec 13 10:30:28 examhost PAM_unix[20562]: (system-auth) session opened for user root 
by anton(uid=501)
Dec 13 10:35:10 examhost2 sshd[456]: Generating new 768 bit RSA key.

In this example, you can see there was a login via SSH. In addition, you can see some problems with the DNS server, and you can see that the syslog is configured to receive messages from other hosts (note the message from “examhost2”).

The syslog daemon is configured by the /etc/syslog.conf file, as follows:

# Log all kernel messages to the console.
kern.*                                                 /dev/console
# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
*.info;mail.none;authpriv.none                       /var/log/messages
# The authpriv file has restricted access.
authpriv.*                                              /var/log/secure
# Log all the mail messages in one place.
mail.*                                               /var/log/maillog
# Log cron stuff
cron.*                                                  /var/log/cron
# Everybody gets emergency messages, plus log them on another
# machine.
*.emerg                                                 *
# Save mail and news errors of level err and higher in a
# special file.
uucp,news.crit                                         /var/log/spooler
#send everything to loghost
*.*                            @loghost.example.edu

In this case, the Linux syslog.conf daemon sorts messages by priority and facility. Possible priority values, in order of increasing importance, include: debug, info, notice, warning (warn), error (err), crit, alert, emerg (panic). The facility parameter differs according to the flavor of Unix. Linux supports the following values for facility: auth, authpriv, cron, daemon, kern, lpr, mail, mark, news, syslog, user, uucp, and local0 through local7. Based on comments in the file (lines denoted by the leading “#” character), you can see how the messages are sorted. All log messages are sent to a different machine (loghost.example.edu) via the last line in the file. This excerpt also demonstrates the typical location for logfiles on the system: /var/log, or sometimes /var/adm.

Remote logging is implemented via UDP. As we discussed in Chapter 6, UDP over IP is an unreliable and connectionless protocol, which means that log messages can be lost or faked. In spite of these drawbacks, setting up a dedicated logging server with no other network services increases security; it is difficult for attackers to avoid being logged, because they are forced to attack a discrete machine with few entry points. Attackers can flood the logging server so it starts dropping messages, but you can configure certain Unix systems to shut down in such a situation. Moreover, you can configure syslog to log to an IP-less machine via a serial link, which makes it very difficult to attack the logging server. To avoid faked messages, you can configure some versions of syslog to accept log messages only from designated machines, via command-line options to syslog. While attackers can also bypass this defense using spoofed packets, it is still an important security measure. There are even some experimental syslog implementations (such as CORE-SDI) with cryptographic support and TCP/IP reliable network logging. Unfortunately, they have not yet been integrated into mainstream Unix.

Some Unix logs are binary logs, such as that generated by a login program. This file is typically called /var/log/wtmp. To produce human-readable output, you can use commands such as w (shows currently logged-in users based on /var/log/utmp) or last (shows recently logged-in users), as follows:

user    pts/0        ne.isp.net Fri Dec 14 19:11   still logged in   
user    pts/0        ne2.isp.net Fri Dec 14 18:19 - 18:23  (00:03)    
user    pts/0        ne3.isp.net Fri Dec 14 16:03 - 16:10  (00:06)    
friend   pts/0        ool.provider.net Fri Dec 14 09:32 - 12:58 (03:26)

This excerpt shows that users “user” and “friend” have logged in remotely from certain machines at certain times. “user” is still logged in to the server on the terminal “pts/0”. These logfiles are difficult to manage due to their binary nature. It is also difficult for attackers to modify them; however, multiple tools exist to do just that. Nevertheless, these files are very useful for high-level user monitoring.

Overall, logs comprise a vital part of Unix security—provided, of course, that somebody actually reads them. If hundreds of machines log to the same server, the amount of syslog information quickly becomes unmanageable. Fortunately, most of the Unix logfiles are plain-text files that can be parsed by programs or scripts to condense the information and increase its usefulness. Log monitoring programs such as logwatch and host-based intrusion detection systems such as Symantec ITA and Dragon Squire automate and simplify log monitoring.

Some other utilities also leave an audit trail on Unix systems. Process accounting is one of these. It is very useful for security purposes and general system accounting. Some readers may be old enough to remember that process accounting has its roots in the age when people were charged based on the CPU time that they used. Process accounting is implemented as a kernel feature that is controlled by a user-space program. It records all processes started by the system in a binary file (called /var/log/pacct on Linux and /var/account/pacct on BSD versions of Unix). To bring the data to userland, the lastcomm command may be used as follows:

sendmail          SF    root     ??         0.06 secs Thu Dec 13 10:30
egrep                   root     stdin      0.01 secs Thu Dec 13 10:30
grep              S     root     stdin      0.01 secs Thu Dec 13 10:30
dircolors               root     stdin      0.00 secs Thu Dec 13 10:30
stty                    root     stdin      0.00 secs Thu Dec 13 10:30
bash              SF    root     stdin      0.00 secs Thu Dec 13 10:30

This example shows the process name, username under which the process runs, controlling terminal (if any), amount of CPU time used by the process, and the date and time the process exited. It is possible for malicious attackers to fake the process name in accounting records, but not the username. Unfortunately, the full command line is not recorded. Other tools come to the rescue here.

Many modern Unix shells (tcsh, bash, and others) record a history that can be viewed as a sort of log and can be used to track an intruder. For example, just typing history at the shell prompt displays something similar to the following:

  999  less sent-mail
 1000  clear
 1001  ls -l
 1002  cat /etc/hosts.*
 1003  h| tail -10

This snippet shows several commands that the user has run. They aren’t timed or dated, but simple correlation with process accounting records will reveal the missing details.

Unix logging provides a wealth of information about system behavior. If reviewed by a competent administrator, the logfiles, accounting records, and shell histories reveal meticulous details about attackers. Clever hackers will try to erase the evidence, so you should make an effort to safeguard the logs.

Network Access in Unix

This section briefly reviews Unix network security. We cover TCP wrappers, NFS/NIS, backups, and X Windows, building the foundation for the section that follows (“Unix Hardening”).

TCP Wrappers

While not standard for all flavors of Unix, TCP wrappers , written by Wietse Venema and Dan Farmer, are shipped with many distributions. TCP wrappers provide a versatile network access control facility. This security mechanism consists of the executable file (usually /usr/bin/tcpd) and a shared library. The tcpd is started by the Internet superserver inetd (the standard for most Unix variants). If TCP wrappers are used, /etc/inetd.conf looks like this:

pop-3    stream tcp    nowait root    /usr/sbin/tcpd    qpopper
telnet stream tcp    nowait root    /usr/sbin/tcpd    in.telnetd
auth stream tcp    nowait nobody /usr/sbin/in.identd in.identd -l -e -o
inetd.conf example

In this case, access to POP3 and telnet is controlled by TCP wrappers (tcpd present) and access to the ident daemon is not (unless it can be compiled with the TCP wrapper library). The library allows the programs to be built with TCP wrapper support. For example, sendmail is often built this way. In either case, the program or the tcpd checks the configuration files /etc/hosts.allow and /etc/hosts.deny for permissions before starting. TCP wrappers also increase the amount of useful logging information by recording the failed and successful attempts to log in to the system, even via services that normally do not create logfile records (such as POP3). Examples of this are as follows:

ALL:ALL

This file denies access to everybody for all services that check the file. “Default-deny” is always the best network access control policy. The next file (hosts.allow) is checked first:

sshd: 127.0.0.1 .example.edu  111.11.
popper: .example.edu .others.edu machine.yetanother.edu
in.ftpd: [email protected]

This excerpt shows that access to SSH is allowed from localhost (IP address 127.0.0.1), from all machines in a particular domain (all machines from “example.edu”), and from all machines with an IP address in a particular class B (111.11.0.0 to 111.11.255.255). Users from example.edu and other University domains can check their email via the POP3 protocol (popper daemon). Finally, FTP is only allowed for a single user (local username “trustuser”) and from a single host (host cs.example.edu).

TCP wrappers should always be configured (even if a firewall is used), since they provide another layer of defense.

TCP wrappers run on most variants of Unix and are included by default (in the form of a binary or a libwrap library) in Linux and some others. While newer Red Hat Linux flavors run xinetd and there is no obvious relation to TCP wrappers in the files, they do all the work in the form of the libwrap library.

NFS/NIS

Network Filesystem (NFS) and Network Information Services (NIS) are present in many Unix environments. NFS is a network-aware filesystem developed by Sun Microsystems. It is used for sharing disks across the network. Older versions of NFS (still in wide use) use UDP; the newer NFSv3 can use TCP.

NFS has many security implications. First, attackers using a sniffer can capture files transmitted over NFS. A dedicated NFS sniffer is a part of the dsniff toolkit by Dug Song. This “filesnarf” tool saves files transmitted over NFS on a local disk of the machine running the tool.

There are more NFS security tricks related to unsecured file shares exposed to the Internet and some privilege escalation attempts (usually due to NFS misconfiguration). NIS also has a history of security problems. The most significant of these is the ability of attackers to capture login credentials (such as usernames and encrypted passwords) even when they know only the NIS domain name.

Backups

Why are backups considered a security mechanism? Because they are the last line of defense against security breaches. Even the SANS/FBI Top 20 Vulnerabilities (http://www.sans.org/top20.htm) lists inadequate backups as one of the most common problems. When a system is violated, filesystems are corrupted and firewalls are breached; if you have backups, you can simply pop the trusted tape into the drive and everything goes back to normal, as if by magic (note that you must perform forensics at once, or you’ll have to keep pulling out that backup tape). Of course, the process is likely to be a bit more complicated. The disks might need to be formatted, the operating system must be installed from the vendor media, patches have to be applied, and then the data must be restored from the backup. Additionally, it is worth checking that the problem that caused the incident is not being restored, as has reportedly happened with recent viruses in some organizations. Reinfection by your own tape is an unpleasant thing to happen to a security administrator. It makes sense to first check at least the executable and system configuration files (if any) about to be restored. Such checks may be performed by comparing the files with known good copies or by using integrity-checking software such as Tripwire or AIDE.

Choice of media for backups is a complicated question that is beyond the scope of this book. Hard disk drives, CD-ROMs, Zip and Jazz drives, and various tapes all have their uses as backups. Network backup using rsync-like tools also can be valuable for your environment.

Unix backups are easy to do. Many tools in the system provide backups. We briefly touch upon tar, cpio, dump, and dd.

tar is an old Unix archival tool. It has a vast number of command-line options. The minimum functionality allows you to archive a chosen directory, optionally compress the archive, and write it to disk or tape.

First, create a compressed archive of /home and write it to /backup as home.tar.gz:

tar czf /backup/home.tar.gz /home

Then unpack the archive with the above file in place:

tar xzf  /backup/home.tar.gz

afio (a modern version of a classic cpio) allows you to archive a predefined list of files. The main advantage of afio over tar is that the tar archive can only be compressed as a whole. If a media error occurs, the entire archive is destroyed. afio allows you to compress files individually before they are archived. Thus, an error only damages one compressed file.

dump is another old favorite. It can be used to back up the whole partition on tape or disk and then to restore it via a restore command.

Here’s an example of dump:

dump 0d /dev/rmt0 /home

Restore the above dump in the current directory (Linux):

restore xf /dev/rmt0

In addition to the full mode used in the example, dump and restore have an incremental mode that allows you to back up only the data that has changed since the previous backup.

dd is not strictly a backup tool. It allows disk-to-disk copying in order to create mirrors of the current disks. If you have two identical disks, the command allows you to create an exact copy, which is useful for cold-swapping the disk in case of failure. Simply replace the disk with a copy produced by dd, and the system should boot and run as before. It creates identical partitions and boot sectors, which requires that the disk drives be of identical make and size.

Here is how to create a mirror copy on the identical disk:

dd if=/dev/hda of=/dev/hdb bs=1024k

Obviously, the target partition needs to be unmounted before running the dd command, and all its data will be replaced.

Even though backing up is easy, all backup media should be verified. Do not become the subject of the famous Unix joke: “Backups are just fine, it’s the restores we have problems with.” Many Unix horror stories involve missing or inadequate backups. Look for the document called “Unix Administration Horror Story Summary” in your favorite search engine for some vivid lessons on the importance of backup procedures. Verifying backups is a crucial step. Just thinking that you have a backup does not protect you from damage.

Backups must be done often in order to minimize data loss. Even though frequent, full backups are often impossible, the important Unix files (such as those located in the /etc directory) should be saved as frequently as possible. Backups and restores should also be done intelligently. Don’t restore with a virus-infected backup. You can sometimes prevent such a thing from happening by using tools such as Tripwire, or by not restoring anything that might cause reinfection (i.e., restore the data, but not the programs). That is, unless you are good enough to disinfect your drive manually.

X Window System

Although the X Window system (also known as X Windows) is a part of a graphical user interface (GUI), it is tightly related to networking—X Windows was designed to provide a universal method of accessing system resources from the localhost as well as across networks. The X Window system usually has a port (6000 TCP) or a set of ports (6000 and up) open. While no recent remote exploits for popular X implementations have surfaced at the time of this writing, several denial-of-service application crash attacks against X have been reported. Other X components (such as an XFS font server) can also be listening to ports and could be vulnerable to network intrusions.

Additionally, the X protocol is clear text-based and thus subject to eavesdropping. Attackers can sometimes capture keypresses and mouse movements and can even display X contents. Fortunately, X traffic may be forwarded using SSH. In fact, if the SSH connection is established to a server, all X connections are forwarded over the secure tunnel (provided the configuration option is set). Note that bugs in this functionality have enabled certain attacks against SSH to succeed in an older version of OpenSSH.

Unix Hardening

Is Unix secure?

The question is unanswerable. You might as well ask, “Is Windows secure?” The real question is, “Can Unix be made relatively secure by applying a clearly defined sequence of steps that always produces the same result and can be automated and applied to existing systems?” The answer to this is definitely “Yes.” But can a typical network administrator, without formal security training, achieve such security? The answer to this question is “Yes” as well, but it does take a measure of perseverance.

Unfortunately, every time you acquire a Unix system it will have to be “made secure,” since vendors chronically neglect to integrate tight security when they ship their systems. The reason is simple: security does not sell (at least, not yet), whereas bells and whistles do. Experience with Microsoft shows that features sell. Security, on the other hand, rarely sells, even in times when it is brought to people’s attention by catastrophic accidents and other events. In addition, very few users call vendors asking how to turn off a specific feature, rather than how to enable it. Thus, shipping a system with everything “on” was the default choice of many Unix vendors for years. And few people, even Unix users, actually make a conscious effort to secure their systems. Thus, until recently vendors have simply sold what most customers wanted. Even if a preponderance of customers suddenly starts to demand security, system hardening will still be needed. Various installations have vastly different security requirements, even though they all use the same Unix system from the same vendor. As a result, the amount of system and application hardening that you should apply to a given system will vary.

Unix can be made secure. Years of history have proven this to be true. To what degree can Unix be made secure? For an objective (if somewhat debatable) classification of security rating, we turn to the traditional “Orange Book.” Note that the original TCSEC[5] requirements have evolved into the Common Criteria. The old TCSEC ratings went from A1 (the most secure) to B3, B2, B1, C2, C1, and D (the least secure). For example, versions of Unix-like systems (such as those made by Wang Government Services) are known to achieve a B3 rating. Most commercially used systems are at either a D or a C2. Few of the commonly used products ever attain a B1 rating. Thus, Unix can be made very secure, but it takes work. The tightest security is only possible by writing most of the system code from scratch using a verified security design. Such systems are beyond the scope of this book; we instead focus on common installations.

The Common Criteria definitions of security are generally not used in business. Nevertheless, traditional Unix can be made secure for many business purposes. For example, Unix-based web servers are known to operate in hostile environments for years with no compromise. What makes those machines stay alive? Expensive firewalls and intrusion prevention systems? No—their longevity is achieved through a hardened system and a few common-sense security practices.

Ensconced within firewalls and screening routers, organizations sometimes choose to create what has been described as a “hard shell with a soft chewy center.” This means that once the protected perimeter (such as the firewall) is breached, the system is ripe for the picking by intruders—the opposite of “defense in depth.” This strategy holds only until a compromise occurs, since the internal systems are usually easy to violate. Hardening comes to the rescue. If a network perimeter is breached, hardened systems have a much higher chance of surviving an attack. Hardening the system, or configuring and upgrading the system in order to increase its security level and to make it harder to penetrate, is considered the last line of defense.

Imagine you have deployed a system for remote shell access by untrusted users. (If you say it should never be done, you haven’t been to a major university lately.) In this case, network access controls are useless and administrative controls are weakened (it’s difficult to fire somebody for violating a policy in this situation). Hardening is the only security measure on which you can rely.

Hardening is required because various operating system components and application software have bugs that undermine the security of your system. Moreover, many people believe that software will always have bugs. Bugs make systems exploitable by malicious hackers and insiders. Another reason to harden your systems is in order to correct insecure defaults shipped by system vendors. Hardening minimizes the number of points at which an attacker can enter a system and discourages application exploits.

Hardening Areas

Every Unix system and application has areas that can and must be hardened before the computer is connected to a network. We say network and not the Internet, since insiders from the local area network (LAN) can initiate attacks as well.

Checking installed software

Before we start to harden, we have to first limit the amount of software installed on the Unix system, with a particular focus on network-aware software such as network daemons. It is a good idea to lock down a system with the minimum necessary features installed. The principle is simple: just uninstall what you or your users do not use.

It is understandable that some users might be tempted to just install everything and then use whatever they want. Please fight this urge, since it can put your system at risk from random scanning by malicious hackers. Even though you might not have anything valuable on the system, your machine could be used as a base for launching hacking attempts, password cracking efforts, or denial-of-service (DoS) attacks.

Let’s start with network services. If you do not use the X Window system (for example, on a web or email server), remove all X-related software. The detailed uninstallation procedure varies greatly between Unix vendors. For example, Red Hat Linux and several other Linux vendors use the RPM (Red Hat Package Manager) system, which allows easy software removal. Solaris uses another packaging tool that also enables clean installs and removals.

Patching the system

With any luck, your system vendor has taken some steps to make your systems secure by providing critical security updates. Go to your Unix vendor’s web site and look for update packages for your OS version. Upgrade to the latest software version available from your vendor. It’s wise to take this step after an initial system installation from CD-ROMs or other media. However, the process becomes infinitely more useful if it’s repeated frequently: new bugs are discovered daily, and vendors usually make patches available on their web sites (some faster than others). If your vendor has any sort of automated patch notification system, sign up for it. Doing so reduces the cost of keeping informed about security developments.

Warning

Sometimes updates break the functionality of existing applications. Try all vendor updates on a test system before applying them to your production systems.

Table 11-2 lists the web sites of some popular Unix vendors.

Table 11-2. Some Unix vendors’ web sites

Unix version

Vendor

Web site

Solaris, SunOS

Sun

http://www.sun.com

AIX

IBM

http://www.ibm.com

HP-UX

Hewlett-Packard

http://www.hp.com

Red Hat Linux

Red Hat

http://www.redhat.com

OpenBSD

OpenBSD

http://www.openbsd.com

FreeBSD

FreeBSD

http://www.freebsd.org

NetBSD

NetBSD

http://www.netbsd.org

Tru64 Unix

Compaq

http://www.compaq.com

IRIX

SGI

http://www.sgi.com

Filesystem permissions

Now, let’s maximize the efficiency of the most basic Unix security control: filesystem permissions . Many Unix vendors ship systems with excessive permissions on many files and directories. Infamous examples include logfiles writable for everyone and an /etc/shadow file (which contains encrypted passwords likely vulnerable to brute force attacks) readable for everyone. Both of these examples have actually occurred in the past. The Unix filesystem is a complicated structure, and knowing correct permissions is not trivial. This particular task is better left for a hardening script.

While it is unusual for modern Unix installations to be deployed with major filesystem permission blunders, it makes sense to check several important places. This is especially true if you are hardening a running system that was installed a long time ago by other admins. Consider the following:

  1. No file in /etc and /usr should be writable for everyone.

  2. Logfiles in /var/log or /var/adm should not be readable for everyone.

  3. /tmp should have proper permissions (discussed below). Also, check /var/tmp and /usr/tmp, which are sometimes used for the same purpose.

  4. Look for files to which anybody on the system can write using the following:

    find / -perm -2 ! -type l -ls

    Evaluate whether these loose permissions are really justified.

Another important issue in hardening filesystems is handling Set User ID (SUID) and Set Group ID (SGID) binaries. Many of the programs that are shipped with the SUID bit and are owned by the root user contain bugs that can lead to a root-level compromise in various attacks (e.g., buffer overflows, as described in Chapter 5). Even programs that are not SUID “root” but rather SGID “mail” or “man” groups can be abused, leading to system compromise (such as reading root mail).

To locate all SUID binaries, issue the following command:

find / -type f ( -perm -04000 -o -perm -02000 )

For platforms other than Linux (those not running the GNU version of find), another option, -print, needs to be added at the end. Now, evaluate the list and remove the SUID bit from selected files by giving the command chmod a-s filename. For example:

# ls -l  /tmp/bash
-rwsr-sr-x    1 root     root       512540 Jan 23 23:55 /tmp/bash
# chmod a-s /tmp/bash
# ls -l  /tmp/bash
-rwxr-xr-x    1 root     root       512540 Jan 23 23:55 /tmp/bash

Since a typical system has many SUID and SGID programs, the task of determining the location of the SUID/SGID bit might be difficult. It is easier if you do not install excessive software (recommended above). Many Unix hardening tools automate the task by using their own criteria for SUID and SGID bit removal.

The temporary directory (usually /tmp) on Unix systems is another well-known source of risk. Many programs need write permission for the /tmp directory. Typical /tmp permissions may look as follows:

drwxrwxrwt    4 root     root         1024 Dec 28 00:03 tmp

These permissions can be tightened; however, doing so might break some functionality. For example, X Windows does function without a writable /tmp. Some people recommend not eliminating a global /tmp directory; rather, they prefer user-specific tmp directories in the home directories. Many applications read the name of the temporary directory from the environment variable TMPDIR, while others, mostly old programs, unfortunately will try to use /tmp no matter what.

Login security

System login security is a primary bastion protecting your Unix system. How do you make it more defensible? Everyone has to enter a password for console login, but how secure are those passwords? If your Unix variant permits it, you should set rules for minimum password complexity and expiration period. In addition, a few Unix systems provide a facility to record password history, in order to prevent users from alternating between two passwords.

There is no standard way to enforce password complexity. There are several /bin/passwd (the program used to change users’ passwords) replacement programs that check passwords against a database of known bad passwords, such as dictionary words, usernames, or some modification of them. For some Unix versions, there are system libraries—such as cracklib—that /bin/passwd calls to verify the strength of chosen passwords. This step is very important: if your passwords are well encrypted but your users tend to use such infamous passwords as “password”, “root”, or someone’s first name, your security is nonexistent.

To keep a password history, use a third-party tool such as npasswd, which is the excellent replacement for the standard Unix passwd command. npasswd adds many security enhancements, including complexity checks, dictionary checks, and password history support.

As we discussed previously, shadow passwords are standard on most modern Unix systems. If you use an older system and for some reason cannot upgrade, convert your regular world-readable /etc/passwds file to a shadowed version, if your Unix supports it. Shadow Password Suite can convert regular Unix passwords to shadow format. Install the software using your vendor-supplied version. Shadow Password Suite replaces many important system files (such as login, passwd, newgrp, chfn, chsh, and id); thus, using the vendor-approved version is best. Next, the pwconv command converts the /etc/passwd file and creates /etc/shadow for all existing user accounts. In Linux, you might want to make use of some of the excellent documentation available online, such as the “Linux Shadow Password HOWTO.” All Linux HOWTOs are posted at http://www.tldp.org. In order to further increase your defenses, MD5-hashed passwords are recommended. We covered the advantages of MD5 passwords previously in this chapter. If your system supports MD5 passwords, you should convert to this format.

Your system might come preinstalled with more system accounts than you could ever use. You have regular user accounts belonging to humans, a root account with administrative privileges, and several system accounts (news, nobody, sync, and many others), which vary for different Unix flavors. Removing these system accounts serves the same purpose as removing extra software: it reduces the number of entry points and makes it easier to harden the system.

User security

After you have made passwords more difficult to access (by shadowing them) and to crack (by enabling MD5 passwords), it is time to clamp down on your users. This might sound cruel, but that’s part of the fun of being a Unix administrator, and has been for decades. In addition, according to cybercrime statistics from the Computer Security Institute and Federal Bureau of Investigation CSI/FBI Cybercrime Survey, insiders—such as your legitimate users, contractors, or people who simply have access to the computer equipment—commit most successful computer crimes. Securing your system from your own users is actually more important than securing against outside network intruders. The idea is to follow a “need-to-know” or “need-to-do” principle. For example, if ordinary users are not supposed to perform system administrator duties (hopefully they are not), they should not be able to run the su command. A vendor often implements this policy by creating a special “wheel” group of users who can access system administration commands. If it is not implemented on your system, the following directions show you how to do it:

  1. Create a group called “wheel” by adding it to the /etc/group file (follow the format of the file).

  2. Add trusted users to the group by further editing the /etc/group file.

  3. Find the binaries you want accessible only to members of the group: /bin/su is the main candidate.

  4. Execute the following commands:

    #/bin/chgrp wheel /bin/su 
    # /bin/chmod 4750 /bin/su
  5. Check the resulting permissions on /bin/su by issuing an ls -l command. You should see the following:

    -rwsr-x---    1 root     wheel       14184 Jul 12  2000 su

No users apart from those listed in /etc/group as members of “wheel” will be able to change their user IDs or to become the superuser (root). If they attempt to execute the su command, they will see something to the effect of the following:

bash: /bin/su: Permission denied

Linux also allows you to restrict the properties of user processes and files by size and other attributes, using Pluggable Authentication Module (PAM) resource limits. The standard Unix method for restricting resources is a quota facility. It is implemented somewhat differently in various Unix flavors, but the basic functionality is the same. Two limits for filesystem usage are imposed upon the user: a hard limit and a soft limit. If the user exceeds the soft limit, he is issued a warning; if he exceeds the hard limit, the disk write is blocked. In addition, a quota facility can impose limits upon the number of files. In order to enable quotas, you have to mount the partition with quota support. On Solaris, this is achieved by adding “rq” to the mount options (usually located in the /etc/fstab or /etc/vfstab configuration file), while on Linux the option is “quota”. An excerpt from the Solaris /etc/vfstab file with quota support is shown below:

#device         device          mount           FS      fsck    mount   mount
#to mount       to fsck         point           type    pass    at boot options
/dev/vx/dsk/Hme1   /dev/vx/rdsk/Hme1  /export/home1   ufs 3   yes  logging,rq
/dev/vx/dsk/Hme2   /dev/vx/rdsk/Hme2  /export/home2   ufs 3   yes  logging,rq

There is one more trick to make user behavior safer. We do not want users performing passwordless authentication for their Secure Shell access, unless authorized. Passwordless authentication seems more secure, but it represents a severe security hole if a hacker compromises the account (and gains access to many other systems without a password, as in the long-gone days of rsh and rlogin). Of course, it is possible to set the local password, locking the private key, but this step introduces the same password problem. Often, a system administrator locks an account by changing the password string to “*” or some other string that does not correspond to any unencrypted password. The admin thinks that the user is then not able to log in, either from the console or remotely. However, nothing is further from the truth. Using SSH, a user can allow RSA key authenticated logins. By default, the Secure Shell daemon does not check the password file at all. Thus, the user gains backdoor access to the system without installing any new software; meanwhile, the administrator thinks the user has been locked out of the system. To prevent this from happening, remove the user’s ability to create certain files. Depending upon the SSH version, the commands are as follows:

#cd ~user
# cd .ssh
# touch authorized_keys
# chown root.root authorized_keys
# chmod 000 authorized_keys

or in the case of SSH2:

#cd ~user
# cd .ssh2
# touch authorization
# chown root.root authorization
# chmod 000 authorization

This prevents the user from setting up passwordless SSH access. Note that we are not locking the account, but rather preventing the use of passwordless SSH. We cover Secure Shell attacks in greater depth later in this chapter.

Physical security

What if an attacker has access to your system console? That’s impossible—you have a secure environment, protected by access cards, armed guards, and alarms—or so it seems. What about that sketchy junior system administrator you just hired without a background check? Or the shifty new janitor with a 100-MB Zip disk in his pocket, ready to copy your secret data? As we described in the previous section, attackers are often insiders. It is often said that all bets are off if the attacker has access to your hardware, since she can just clone the entire system for further analysis. Although this is strictly correct, you can make local attacks more difficult and complicated.

If you are using a system based on an Intel x86 processor, it usually has a BIOS password to lock the BIOS settings. This option helps prevent the attacker from booting with her own boot media, such as a DOS floppy with tools for your Linux system or a Linux disk for your BSD system. Admittedly, this protection is not absolute: if an attacker already has some level of access to your system, she can erase the BIOS password. Sun Solaris SPARC hardware also has a ROM password protection similar to that of an Intel-based BIOS. On the other hand, recovering from a lost BIOS password might be painful (and in rare cases might even involve sending the system to the manufacturer). Some Unix variants (such as Linux and Solaris) allow you to set the boot password to prevent unauthorized booting.

As always, adding depth to your defenses is the goal. For instance, if your system boot loader (such as Linux’s LILO) allows for password-protecting the boot sequence, set this up as well. It prevents the attacker from modifying the system boot sequence.

Network security

Unix network defense is covered separately, since it is a large realm with many implications. Briefly, however, be sure to strengthen Unix network access controls during system hardening. TCP wrappers, discussed earlier, can help protect compatible services. While implementing TCP wrapper protection, inspect the Internet superserver configuration file (/etc/inetd.conf ) for services that are not used. (See above for more details on this file format.) Only those programs you actually use should be present and listening to the network. Ideally, a host-based firewall similar to Windows’s personal firewall programs should guard the stack. Many Unix variants, such as Linux, BSD, and Solaris, have built-in packet filtering that can be used for this purpose.

Daemon security

Now that you have hardened Unix itself, consider application hardening. We cannot cover all possible Unix applications in this book; we can’t even cover all the hardening tips for major network programs. For example, securing Apache is beyond the scope of this book, since the software is very flexible and complicated.

In general, if you cannot remove an application completely, you have to tighten it down. Network daemons such as BIND (DNS), sendmail (email), httpd (web server), IMAP, or a POP3 server are a portcullis into your Unix kingdom. We briefly review some basic Unix daemon-hardening tips.

Telnet

Do not spend time hardening telnet; instead, remove it. Secure Shell provides an excellent replacement for telnet, with more features (including file transfer support) and dramatically increased security. Although “kerberized” (i.e., authenticated through a Kerberos system), telnet is not vulnerable to sniffing; unlike SSH, it requires deploying and maintaining the complete Kerberos infrastructure.

FTP

FTP is a risk primarily due to its use of plain-text passwords and file contents transmitted over the Net; if you can do without it, remove it and use Secure Copy (part of Secure Shell) instead. If you have to use FTP, TCP wrappers can control access, as described previously. If your version of Unix uses /etc/inetd.conf , it should include a line similar to the following:

ftpd stream tcp    nowait root    /usr/sbin/tcpd    in.ftpd

This makes your system check the /etc/hosts.allow and /etc/hosts.deny files before allowing logins via FTP.

Anonymous FTP is a risk, since you cannot assign accountability to users. Allowing write access to your disk to anonymous users is a grave risk and should be avoided at all costs. Try connecting to your system via FTP using the username “anonymous” or “ftp” with any password: if it works, you have anonymous FTP. Disable it by consulting your FTP daemon’s configuration files. There is no standard FTP daemon; thus, the details are left for the reader to investigate. If you have many FTP users on your system, consider using an /etc/ftpusers file. Only usernames added to the file are allowed logins via FTP.

Apache

Apache (http://www.apache.org) is the most widely known web server in the world. If you use Unix for serving web pages, most likely you use Apache. (It also runs flawlessly on Windows and is gaining market share on that platform.) Securing Apache is a large project, due to its complexity and its modular structure. However, the defaults are usually good enough for sites that do not have stringent requirements. Also, remember that most Unix web servers are compromised via some third-party software (such as a CGI script), rather than a bug in a web server itself. Carefully inspect all CGI scripts and other executable content that you place on your web server.

DNS

Bastille (a hardening script for Linux) suggests using the DNS daemon in a chroot environment. That means the daemon runs in its own virtual filesystem compartment. A Unix DNS server most likely uses BIND software to handle DNS. BIND has a vast code base and a terrible security history, including the notoriety of being the most widely exploited service in 1999. Thus, relegating BIND to a chroot jail makes sense. The configuration is ubiquitous. In addition, another important step is to stop information from leaking through BIND. Disable DNS zone transfers to unauthorized parties, since they can disclose your network structure to attackers.

Mail

Securing mail servers is another vast field. The most commonly used Unix mail server is sendmail. It has had a long history of security problems (unlike qmail), but it has stabilized. More importantly, sendmail needs to be secured from spam, or unsolicited commercial email could be sent through your server. sendmail should deny mail relaying—i.e., sending email from third parties to others not inside your organization via your mail server. In order to increase your security level even more, sendmail can be compiled with TCP wrapper support. In this case, you can completely block access to your mail server from certain hosts or domains. sendmail is also a source of information leaks: an attacker can use SMTP commands such as EXPN and VRFY to map your existing users. Remove these commands in your configuration files using the following configuration option in your sendmail.cf file:

O PrivacyOptions=noexpn,novrfy
SSH

Secure Shell communication is secure from eavesdropping, but the daemon itself might be providing a hole into your network. All versions of SSH (SSH1, SSH2, and openSSH) have a checkered security history. Run SSH with TCP wrappers (the support is usually compiled in via a libwrap library) or use its own access control facility (implemented in a file such as /etc/ssh/sshd_config). Several SSH features are dangerous and should be disabled. Nowadays, they are usually off by default, but checking never hurts: make sure there are no root logins, no null passwords, and no rsh fallback. For more information on Secure Shell, look at Section 11.7.

System logging and accounting

Improving logging and system accounting does not make your system harder to attack, but it makes security accidents easier to investigate. Unix logging and BSD-style accounting were described earlier in this chapter. While performing system hardening, you should confirm that logging is enabled. This is done by checking that the /etc/syslog.conf file exists and that it contains sensible information. Also, check to make sure the syslog daemon is running. To perform the last check, issue the following commands for Linux:

%ps -ax | grep syslog
350 ?        S     41:47 syslogd -m 0

Issue these commands for Solaris:

% ps -el | grep syslog
8 S  0   497  1  0  41 20 7551cea8  475 7210eab2 ?      11:22 syslogd

If they produce output similar to that shown above, the syslog daemon is indeed running. Also, saving logs to a remote server is highly recommended for security. In Linux, that requires changing the syslog configuration by enabling remote log reception (using the command-line option -r).

Automated Hardening via Scripts

Several scripts and programs exist to harden Unix systems. These scripts range from simple post-installation checks to full-blown programs with graphic interfaces that verify and secure many aspects of your system. Here, we discuss several of the popular tools for Unix (namely, Linux and Solaris).

Linux Bastille

Bastille is a program to harden Red Hat and Mandrake Linux, with support for Debian, SuSE, TurboLinux, and HP-UX in various stages of development. Bastille is designed to not only comprehensively secure the Linux system but also to educate the administrator on many issues that may arise during the operation of a Linux server, such as daemon security and network access controls. The project coordinators combined their own Linux expertise with many other security information sources. Originally, Bastille was designed to run only on a freshly installed system, but it was later upgraded to handle systems with changes to the default configuration files. To use the program, download the RPM packages (for Red Hat or Mandrake) or source code (for other supported systems) from http://www.bastille-linux.org and install them. Then run the program as root, answer the questions asked by the GUI, and reboot your computer. Figure 11-1 shows a Bastille screen.

An example Bastille screen

Figure 11-1. An example Bastille screen

As you can see on the left, there are areas of system hardening that Bastille handles. They include filesystem permissions, user account security, system boot security, tool disabling, PAM configuration (a Linux-specific security mechanism described later), system logging, and other features. On the right, there are user controls for enabling specific security enhancements. In addition, Bastille can enable a host-based firewall on your machine to further protect it from network attacks.

Bastille is included in Mandrake and there’s a plan to include it in the standard Red Hat distribution at the time of this writing. With vendor support, Bastille might become a standard Linux hardening tool, used by a wide audience of Linux server and desktop users.

Internally, Bastille is a set of Perl scripts that use the Perl Tk (a popular graphical toolkit) interface to create a GUI for the X Window system. The Perl scripts parse various Linux configuration files and then implement changes as approved by the user. This architecture allows users to write Bastille modules to implement custom security improvements.

Kernel-level hardening

If you have access to your Unix source code, you have the ability to make your system much more secure. In an extreme scenario, you could even replace the entire operating system with another one using a verified security design (although it would no longer be called Unix, due to its different architecture). A more realistic approach is to tweak the system kernel (the most important component of any Unix system) and system utilities to produce more stringent, refined, and flexible security controls. Thus, in kernel-level hardening we increase the security of a standard Unix system by making slight (or sometimes more drastic) adjustments to the system kernel.

Unix was born as an open system based on universal standards and not chained to a single vendor. In fact, even though your flavor might not be released under an open source license (like Linux, FreeBSD, OpenBSD, or NetBSD), getting access to the source code might be possible under a special license agreement, as is the case with Solaris. However, it is much more likely that users of open source systems will perform kernel hardening, because these systems have better kernel documentation, more active development cycles, and superior support for tricky programming issues. (To verify this, simply join a kernel development mailing list and ask a question.) We focus on Linux kernel hardening in this section.

The simplest kernel hardening procedure is disabling support for modular kernels. To begin with, most modern Unix systems run a modular kernel. That is, a user is allowed to insert specially written programs (called kernel modules) into the running kernel and have them execute in kernel space. These modules usually handle new hardware or support filesystems and other tasks. However, malicious and stealth kernel modules are becoming the tool of choice for attackers trying to retain access to a hacked system. After an attacker gains access, he might choose to install a rootkit (usually a set of Trojaned programs that allow backdoor access to the system, as described in Chapter 10). However, system administrators using integrity-checking tools such as Tripwire or chkrootkit can sometimes discover rootkits (unless they use more advanced kernel-hiding techniques). Thus, to hide from an integrity check, malicious hackers might choose a kernel-level rootkit that completely bypasses a standard filesystem-checking routine. The answer to this is to compile the Unix kernel with no module support. In this case, all the hardware drivers will be compiled into one monolithic kernel. This significantly complicates attempts to attack by kernel code insertion, but it also complicates system administration, since all major hardware changes will require kernel recompilation. Unfortunately, as with many security controls, it can still be bypassed.

Pitbull

Pitbull, by Argus Systems (http://www.argus-systems.com), makes a commercial security patch (called the Secure Application Environment) for Linux, Solaris, and AIX. It allows for the compartmentalization of applications, adds granular domain-based access control (DBAC) to standard Unix, and limits the havoc that root can wreak upon the system. Pitbull is implemented as a set of kernel modules and system utilities.

Openwall kernel patch

The Openwall security patch is a well-known enhancement for Linux kernel Versions 2.0 and 2.2. While not providing any drastic security improvements or new capabilities, it helps to solve several of the important security flaws inherent to Linux. The Openwall patch offers the following features:

Nonexecutable user stack area

Makes running buffer overflow exploits more difficult. Only the more advanced exploits work under this protection. Such a feature has long existed on Solaris.

Secured /tmp

Several attacks (see Chapter 9) work by creating a symbolic link to an existing but unwritable file (such as /etc/passwd) and then abusing some SUID root program into writing to the file. The secured /tmp feature stops such attacks. It also prevents users from creating hard links to files they do not own.

Restricted writes into untrusted FIFOs (named pipes)

Makes certain data spoofing attacks more difficult.

Secure /proc

Prevents users from gleaning information on processes that they do not own.

Special handling of default files descriptors for SUID binaries

Helps prevent some attacks against the data handled by SUID programs.

In addition, there are several security improvements related to process memory space handling, such as deallocating shared memory segments not associated with any process. However, the patch breaks some functionality in applications such as databases. It should be deployed with great care and only after testing on similar machines.

LIDS

If you are really serious about system hardening, deploy the Linux Intrusion Detection System (LIDS). LIDS has a somewhat misleading name, since its focus is on the prevention rather than the detection of system problems and intrusions. LIDS is a patch to a standard Linux kernel source that provides mandatory access control (MAC) support for Linux. MAC is more secure than the standard Unix discretionary access control (DAC); it allows for more fine-grained protection and protects files from the owner and superuser. In fact, the superuser loses a large portion of its powers on a MAC-based system. LIDS protects and hides files and processes and grants access privileges on an individual basis (unlike standard Unix permissions). In addition, it has a built-in kernel port scan detector.

“Secure Unix”

Many efforts have attempted to use the name “secure Unix.” We’ll briefly mention several Unix variants that incorporate increased security based on various models, or that perform some of the hardening measures we have described. NSA Secure Linux is one attempt to add capabilities and MAC support to the Linux kernel. The main purpose of the project is to make Linux usable in an environment where multilevel security is required. OpenBSD’s focus is code audit and secure defaults that lead to a secure system right after installation. TrustedBSD is a combination of the FreeBSD code base with several formal security enhancements. Trusted Solaris is Sun’s secure version of their standard Solaris Unix; it is rated above B1 on the TCSEC criteria. HP Vault is a similar effort by Sun’s competitor, Hewlett-Packard, based on HP-UX. Immunix by WireX is another approach to secure Unix. In Immunix, the company chose to recompile the entire Red Hat Linux distribution using a special compiler in order to protect against buffer overflow attacks, format string attacks, and others. It also implements many hardening measures similar to those described in this chapter.

Encrypted filesystems

Many of the security safeguards we described previously fail if an attacker has full access to your machine for an extended period. Is there a way to harden your system so that it resists even the ultimate attack—i.e., the theft of the hard drive? It is possible: using the encrypted filesystem, you can protect the data on your machine from such attacks. Swap space may also be encrypted.

Encrypted filesystems have not made it into standard Unix, mostly due to various government restrictions on cryptography. However, there are many third-party tools for Unix that provide filesystem-level encryption or even a full steganographic (information-hiding) filesystem.

The oldest Unix encrypted filesystem is CFS. It was written in 1996 and is compatible with several Unix flavors (AIX, HP-UX, IRIX, Linux, Solaris, and Ultrix). The features of CFS include DES encryption of all files on the disk. It works by creating a virtual NFS server, which is accessed by the user.

Overall, encrypted filesystems have not found wide use. Encryption on that level incurs measurable performance implications, and few people seem to need the added security. Also, there is a risk of losing data if the encryption key is not available. Another aspect that hinders the wide use of such filesystems is the lack of a single “favorite” one.

Unix Network Defense

While insiders such as disgruntled employees commit most successful computer crimes, outsiders perpetrate the vast preponderance of attacks. Since the advent of modems in the 1970s—and more significantly, since the broadband explosion of the late 1990s—remote attacks have escalated.

For attackers, remote access offers many advantages over local hacking; not least, with remote access you cannot be physically identified and arrested on the spot. Perceived anonymity, jurisdictional restraints, and complex foreign laws make network attacks an attractive choice.

Unix integrated TCP/IP networking stacks early in its lifecycle. From the venerable r-commands (rsh, rlogin, rexec) that were used to access Unix system resources across TCP-based networks, to modern Virtual Private Networks (VPNs) and Secure Shell (SSH), the world of remote connectivity is rich in protocols and standards. Hence, it is also rich in complexity and inherent vulnerability.

Unix systems are reasonably well protected from network attacks, at least when they are configured by a capable network administrator. Network access controls should be enabled as a part of system hardening. Many Unix systems exposed to the Internet have withstood attacks for years, with no firewall protection, simply by relying on built-in commands (such as TCP wrappers) and minimal configuration.

In the following sections, we show you how to guard Unix systems from network attacks with methods such as network access controls, Unix built-in host firewalls, popular Unix application access controls, and other network security techniques. We cover standard Unix access control programs, examine application-specific access controls, address configuration issues, touch upon sniffing techniques, and then delve into the world of Unix host-based firewalls. This information may constitute a review for experienced Unix administrators.

Keeping your systems up to date with security patches is a fundamental aspect of network defense. For example, if you have to run an exposed FTP server, no amount of firewalling can keep attackers away: the FTP service has to be available to the world. In this circumstance, keeping the daemon updated is of paramount importance.

Advanced TCP Wrappers

TCP wrappers were covered earlier, in Section 11.4. Here, we demonstrate the advanced use of TCP wrappers to help you fine-tune their features for more security.

TCP wrappers can be used in two forms: as a binary (usually /usr/bin/tcpd, or anywhere else binaries are stored on a Unix system, such as /usr/ucb on Sun) or as a shared library (/usr/lib/libwrap.so).

tcpd

The binary form of TCP wrappers is used to “wrap” around network applications started from the Internet superdaemon inetd. In this case, the applications are configured in the /etc/inetd.conf file. The superdaemon starts the correct network application upon client connection to a specified port. The following is an excerpt from an /etc/inetd.conf file before TCP wrappers are added:

ftp     stream    tcp    nowait    root    /usr/bin/in.ftpd     in.ftpd -l -a
telnet  stream    tcp    nowait    root    /usr/bin/in.telnetd    in.telnetd

shell   stream    tcp    nowait   root    /usr/bin/in.rshd    in.rshd
talk     dgram    udp    wait     root    /usr/bin/in.talkd   in.talkd
pop-3   stream    tcp    nowait   root    /usr/bin/ipop3d     ipop3d
auth    stream    tcp     nowait   nobody    /usr/bin/in.identd    in.identd -l -e -o

Next we see the same file, with the added protection of TCP wrappers:

ftp    stream    tcp    nowait    root    /usr/sbin/tcpd    in.ftpd -l -a
telnet stream    tcp    nowait    root    /usr/sbin/tcpd    in.telnetd

shell  stream    tcp    nowait    root    /usr/sbin/tcpd    in.rshd
talk    dgram    udp    wait      root    /usr/sbin/tcpd    in.talkd
pop-3  stream    tcp    nowait    root    /usr/sbin/tcpd    ipop3d
auth   stream    tcp    nowait    nobody  /usr/sbin/tcpd    in.identd -l -e -o

TCP wrappers added two important benefits to the network services: security and improved logging. However, our TCP wrapper configuration is not yet complete. The files that define the denied and allowed hosts (/etc/hosts.deny and /etc/hosts.allow ) need to be created. The simplest configuration that provides useful security is as follows (/etc/hosts.deny is shown):

ALL:ALL

This file denies access from all hosts (the second ALL) to all services on our server (the first ALL). Who can use the machine? To define permissions, use /etc/hosts.allow:

ALL: 127.0.0.1 LOCAL
in.telnetd: [email protected]
sshd: manager.example.edu
in.ftpd: .example.edu 10.10.10.
in.pop3d: .com .org .net EXCEPT msn.com

You can even set TCP wrappers to alert you in real time when connections from particular ports occur. The old TCP wrapper manpages provide the following example (/etc/hosts.deny):

in.tftpd: ALL: (/some/where/safe_finger -l @%h | 
           /usr/ucb/mail -s %d-%h root) &

or even:

sshd 
  : [email protected] ALL@calph ALL@insti 
  : spawn (safe_finger -l @%h | mail -s 'SSHED FROM INTERNET %d-%c!!' anton) & 
  : ALLOW

The last example shows an alternative format for the hosts.allow file in which the action (allow or deny) is specified on a per-command-line basis, rather than a per-file basis.

One potential weakness with this setup is that it can subject you to email flooding—even to the point of disk overflow. Chapter 12 addresses this issue in the section on Unix denial-of-service attacks.

libwrap

The libwrap.so system library provides the same functionality as a tcpd wrapper. If you have access to the application source code, you can streamline the access control process and incorporate access control file checking by the library. However, this requires significant changes to the application code base. This method is used in OpenSSH and in sendmail. If compiled with the libwrap.so library, the application itself will check the configuration files (/etc/hosts.allow and /etc/hosts.deny) to determine whether to allow or deny access. An example implementation is to control spam.

In addition, the inetd daemon has been rewritten to become xinetd, with advanced access control features. xinetd is used by some popular Linux distributions, including Red Hat. xinetd is controlled by its configuration file (usually /etc/xinetd.conf) or sometimes via a configuration directory containing service-specific files. The configuration files below (similar to those used by Red Hat Linux) use a global configuration file and directory.

# Simple configuration file for xinetd
#
# Some defaults, and include /etc/xinetd.d/
defaults
{
        instances               = 60
        log_type                = SYSLOG authpriv
        log_on_success          = HOST PID DURATION
        log_on_failure          = HOST RECORD USERID 
}
includedir /etc/xinetd.d

This configuration file shows service defaults and logging defaults, and it refers to the configuration directory for details (/etc/xinetd.d). The file also provides some protection from resource exhaustion by limiting the number of child processes (FTP, email, or other network programs) started by xinetd.

The following example entry configures the popular File Transfer Protocol (FTP) implementation written by Washington University (WU-FTPD). This file lists protocol options similar to inetd.conf (such as type of service), server arguments, priority (keyword nice), and system-logging options, but it also lists options for more granular access control.

service ftp
{
        socket_type             = stream
        wait                    = no
        user                    = root
        server                  = /usr/sbin/in.ftpd
        server_args             = -l -a -i -o
        log_on_success          += DURATION USERID
        log_on_failure          += USERID
        nice                    = 10
}

The above file can contain the following access control options:

only_from

Specifies hosts that are allowed to have connections (adds another layer to TCP wrappers). The option can use IP addresses, hostnames, network names, or wildcards.

access_times

Lists the times when access is allowed in the format hour:min-hour:min, such as 10:00-18:00. At other times the “access denied” message is returned.

xinetd provides improvements to the classic inetd for enhanced flexibility and granularity in access controls. Unfortunately, it is standard on Linux only, and therefore you must compile and deploy it on other Unix flavors.

Application-Specific Access Controls

What if an application is not started from /etc/inetd.conf or /etc/xinetd.conf and its code cannot be modified to support libwrap? In this case, you can hope that the application has its own access control facility. Let’s consider some known applications with their own network access controls.

BIND (DNS daemon)

BIND (Berkeley Internet Name Domain) DNS daemon software provides domain name resolution services for the majority of Internet hosts. Historically, BIND has passed through some major revisions (Versions 4, 8, and 9). While early versions had no network access controls due to their origin in the small and trusted Internet of the 1970s and 1980s, modern versions have an advanced granular access control facility.

General BIND configuration is a complex subject. In this section, we focus on the access control features to illustrate possible solutions for this problem.

The BIND configuration file is located in the /etc directory and is usually called /etc/named.conf. In this file, the administrator can specify which machines or domains can query the server for DNS information (keyword allow-query), which can update the DNS zone status change (keyword allow-notify), and which can perform DNS zone transfers (keyword allow-transfer). Using the above keywords, the DNS daemon can be shielded from malicious attempts to update information or to map an organization’s network (using complete DNS zone transfers).

The DNS daemon has a history of security bugs, and access control will help to increase your confidence in this mission-critical software.

sendmail (some versions)

sendmail can be compiled with TCP wrapper support. In addition, sendmail can use one of several built-in access control facilities. It’s important to have reliable access controls for sendmail, since the SMTP protocol can be abused in many ways.

The purpose of sendmail access controls is to restrict mail-sending capability to authorized users only. The SMTP protocol currently used to send mail lacks a standard accepted authentication method. While some proposals exist (see RFC 2554 and RFC 2222), vendor support is lacking. As a result, network access control is the only solution.

As in the case of the BIND daemon, sendmail configuration is not for the weak of heart. The main sendmail configuration file (/etc/sendmail.cf) presents a confusing mess of regular expressions and unfriendly options. In fact, an additional directory is usually allocated (/etc/mail) to hold additional configuration files, including those used for access control. While simpler methods of configuring sendmail exist (such as by using the m4 macros for common options in sendmail.mc and then converting to sendmail.cf automatically), they are still less than intuitive.

sendmail can refer to an access database (not to be confused with a Microsoft Access database) in order to determine the privileges of the connected host. The connection can be refused if /etc/mail/access contains a REJECT keyword for the connected host or for the entire domain. Hosts can also be granted additional privileges, such as the ability to RELAY mail (i.e., send email to a third party). Such configuration files might look like:

evilhacker.org    REJECT
.edu        RELAY

To make matters worse, the sendmail daemon does not check the /etc/mail/access file, but rather checks the binary database version of it. To convert the file from its plain-text human-editable form to the form readable by sendmail, execute the following command:

makemap hash /etc/mail/access < /etc/mail/access

Overall, compiling sendmail with TCP wrappers might be easier than sorting out the intricacies of the proprietary access control facilities of your software.

SSH daemon (sshd)

A commercial Secure Shell daemon, as well as the free OpenSSH, can be compiled with TCP wrappers. The SSH daemon also has a built-in access control. Both major versions of Secure Shell can be configured to block connections from specific hosts or even users.

The commercial SSH configuration file (usually /etc/sshd/sshd_config or /etc/sshd2/sshd2_config) can contain keywords such as AllowUsers (DenyUsers) or AllowHosts (DenyHosts). The keywords work as follows: the configuration file can only contain one of the “Allow” or “Deny” keywords. If, for example, AllowHosts is present, all the hosts not explicitly mentioned in the AllowHosts directive are denied. On the other hand, if DenyHosts is in the configuration file, all the other hosts will be allowed to access the server.

Here’s a sample directive:

AllowHosts      localhost, example.edu

In the case of commercial SSH2, you can use built-in regular expression syntax to create fairly complicated rules for host access. For example, the configuration setting:

AllowHosts      go..example...*

allows only specific hosts to access the server.

Apache web server

The most popular web server in the world is the open source Apache web server by the Apache Software Foundation. While web servers are primarily used to provide public access to resources over the Web, the need for access control often arises. In this section, we describe some of the ways of restricting access to web resources using Apache controls.

Apache has two main types of access control: username/password-based (basic or digest authentication) and host-based authentication.

The simplest form of access control is host or domain restriction. Various Apache configuration files (such as the main configuration file, usually located in /etc/httpd and called httpd.conf) can contain directives to limit accesses from various hosts and domains. “Allow from” and “Deny from” are used for this purpose. Both can appear within the same file. To avoid confusion, the recommended method is to configure one directive with the target of “all” and use the second directive to grant or take away privileges.

An example of such a configuration is as follows:

Order Deny, Allow
Deny from all
Allow from goodbox.example.org example.edu

These lines allow access only to a certain web resource (such as a directory on a web server) from a single machine (“goodbox”) within example.org and from the entire example.edu domain.

On the other hand, if certain “bad” hosts should be disallowed to access web resources, the following configuration may be used:

Order Allow, Deny
Allow from all
Deny from badbox.example.org

In this case, the machine “badbox” from the domain example.org is not allowed to access the pages.

More advanced access controls make use of usernames and passwords. These are well covered in the existing literature and on the Apache web server web site (http://httpd.apache.org/docs/howto/auth.html).

System Configuration Changes

This section deals with network-related OS hardening. There are many hacks aimed at increasing Unix system resistance to network attacks, including both denial-of-service attacks and unauthorized accesses.

To begin with, let us examine Linux SYN cookies. A SYN cookie is an ingenious method for mitigating the SYN-flood type of denial-of-service attack. Briefly, a SYN flood causes the exhaustion of machine resources by requesting too many TCP connections. For each connection, the receiving box allocates an entry in a special kernel table. If the table is exhausted, no more new connections can be established. While it is possible to make the table larger, an attacker can always cause the larger table to overflow by sending more packets. SYN cookies encode some connection information in the packet itself, thus avoiding the server-side storage requirement.

While it is more effective to block TCP/IP directed broadcasts at the network perimeter (such as on the router or the firewall), you can accomplish the same task at the host level to provide in-depth defense. Be sure to disable packet forwarding on all hosts not used for routing.

Routing protocols can be abused in several ways. Source routing is the most dangerous, albeit rarely seen on modern networks. Source routing IP options allow you to specify the exact path the packet should take to get to its destination. Most firewalls can be configured to block such packets, as they never serve a benign purpose.

Security from eavesdropping

Network attacks through eavesdropping are as common as ever. While telnet has lost a lot of ground as the Unix remote access protocol of choice, it is not yet dead. Secure Shell has made a lot of progress since its inception in the mid-1990s, but it has not become as ubiquitous as the encrypted web protocol HTTPS (SSL or TLS-based).

A sniffer is a part of every cracker’s rootkit. Successful attackers leave hidden sniffers to collect unencrypted telnet, FTP, and POP3 passwords. Fortunately, protection against such network eavesdropping is trivial using encryption. However, as with many other security measures, it is often easier said than done. For example, replacing telnet with SSH on a large network is a process with many challenges, not the least of which is user compliance. While it might seem that typing “ssh hostname.example.edu” is simpler than “telnet hostname.example.edu”, the three saved keystrokes might take a long time to actually implement in a large environment of users accustomed to unsafe computing habits. Unix vendors who do not include or enable Secure Shell exacerbate the difficulty. All Linux distributions are shipped with SSH ready for operation, but some commercial Unix vendors are lagging behind.

In this section, we look at protection from sniffers using freely available open source tools. Table 11-3 shows a list of common protocols used in Unix networking and their vulnerability to sniffing.

Table 11-3. Unix network protocols

Protocol or network application

Purpose

Plain-text communication

Plain-text authentication

FTP

File transfer

Yes

Yes

telnet

Remote access

Yes

Yes

POP3

Remote email retrieval

Yes

Yes, with no security enhancements

IMAP

Remote email box access

Yes

Yes

SMTP

Sending email

Yes

None needed

HTTP

Web page access

Yes

Yes, if basic authentication is used

r-commands (rsh, rlogin, rcp)

Remote access

Yes

Yes or no authentication

TFTP

File transfer

Yes

None provided

talk

Chat

Yes

None needed

syslog

Remote logfile transfer

Yes

None needed

NIS

Distributed authentication data

Yes

None provided

NFS

Remote filesystem

Yes

Yes or none provided

X11

Remote GUI access

Yes

Yes, with no security add-ons

A cursory glance at this list is startling. All classic Unix protocols are vulnerable to sniffing. What is available to protect Unix networks from sniffers? Encryption comes to the rescue. The Secure Sockets Layer (SSL) protects web connections, various authentication schemes (KPOP, APOP) shield email passwords, and SSH replaces telnet and FTP. SSL wrappers and SSH can be used to tunnel almost any TCP-based network protocol. X11 connections can be protected by SSH as well. Next, we consider SSH in more detail.

Secure Shell

SSH is one of the most flexible network security measures available today. It can be used to secure many network operations, such as remote access, email sending and retrieval, X Windows traffic, and web connections. SSH was promoted as a replacement for Unix telnet and rlogin/rsh remote-access protocols (which use plain-text communications vulnerable to sniffing and traffic analysis), but it now reaches far beyond Unix remote access.

SSH consists of client software, server software, and a protocol for their interaction. The interaction protocol includes authentication, key exchange, encryption, passphrase caching, as well as other components.

Currently, there are two major versions of the SSH protocol in use. SSH Version 1 has more supported platforms and probably even more users. However, SSH1 is known to have security problems (which will be described later), so you should avoid it. Significant differences between Versions 1 and 2 arise in their respective session-encryption protocols. SSH1 supports DES, 3DES, IDEA, and Blowfish, while SSH2 uses 3DES, Blowfish, Twofish, CAST128, and RC4. For authentication algorithms, SSH1 utilizes RSA, while SSH2 relies on the open-standard DSA. There are also other major implementation differences that cause these two protocol versions to be incompatible. However, OpenSSH (the open source version of the protocol) implements both protocols in one piece of software.

SSH uses several authentication options: regular passwords, RSA (for SSH1) or DSA (for SSH2) cryptographic keys for host or user authentication, and host or user trust files (such as the hosts.equiv and .rhosts that gave r-commands a bad name and were dropped in SSH2). Plug-in modules with other authentication methods, such as RSA SecurID card, Kerberos, or one-time passwords, can be used as well. Secure Shell can also compress all data for faster access on slow links.

There are several popular implementations of the SSH protocol. The most famous are SSH, by SSH Communications Security, and OpenSSH, by the OpenBSD development team. Many Linux distributions ship with SSH configured to run at startup. All you need are a valid user account and login.

Let’s review how SSH can be used to secure other plain-text protocols. Suppose you have a POP3 (or IMAP) email server from which you read your messages. You are already aware that whenever you connect to a server to read email, your exposed username and password are transmitted in plain text over the Internet. Fortunately, SSH allows you to set up your mail client (such as the infamous Outlook Express, which spread the email worms of recent years) to connect only to the local machine. In this case, no information is leaked to the outside network. All the connections between your computer and the server are encrypted with Secure Shell.

The process is as follows: the SSH client software first establishes a regular connection to an SSH daemon running on the server machine. Next, it requests a connection to a required server port (port 110, in the case of POP3) from a remote machine. Then the SSH client starts to listen on the local client port. As a result, the tunnel from a local machine email port to a remote machine email port is set.

Password-less authentication is also of great value for POP3 tunneling, since you won’t have to enter the password every time the email program wants to check for new email on the server.

On a Unix client, perform the following:

$ssh -f -L 1100:localhost:110 [email protected] 

This command establishes a secure tunnel. Now, point your email client to retrieve mail from “localhost”, port 1100 (instead of “pop3.mail.server.com”, port 110). A higher-numbered port is used to avoid the need for root privileges. Usually, the email program has a configuration section that provides a space to enter incoming and outgoing mail servers. When using tunneling, your incoming mail server will be set to “localhost” or an IP address of 127.0.0.1. The -f option causes the ssh to fork in the background.

If you want to prevent anyone from eavesdropping on your outgoing email traffic on its way to a remote machine, do the same for an SMTP connection:

$ssh -f -L 25:smtp.mail.server.com:25 [email protected]

Although no passwords are transmitted in the case of SMTP, it still might be useful to tunnel SMTP mail by sending the connection over Secure Shell (as shown above).

Tunneling FTP is a bit more complicated, since FTP uses two pairs of TCP ports with dynamic allocation of port numbers. However, you can still implement it by using passive mode FTP and forwarding the data (port 20) and command (port 21) channels separately. scp (part of Secure Shell) can be used to provide the same functionality.

Tip

SSH can also be set to never send passwords over the network, even in the encrypted form, and this is highly recommended. The local password still needs to be set to protect the private key.

SSH uses a public key encryption scheme to authenticate users and hosts. To make use of this public key encryption, a user should create a key pair for authentication. The public key is then uploaded to the SSH server, and the private key is kept on the user’s client machine.

To create a key pair in Unix/Linux, perform the following steps:

  1. Run ssh-keygen (in the case of SSH1) or ssh-keygen2 (SSH2).

  2. The program creates two files containing the private and public RSA keys from the pair and informs you what files they were written in (depending on the SSH version).

  3. You are prompted for a password during private key creation. This password is used to encrypt your private key. It is not required, but in the case of empty passwords, all the responsibility for safeguarding the private key rests on your shoulders. Use empty passwords only if your machine is very secure and you are sure nobody else is using it. This practice is highly discouraged on public machines, since anybody who takes over your account will be able to connect to other machines for which you have created keys.

  4. Next, upload the public key (usually found in the file identity.pub for SSH1) to the server in a secure manner. Either use scp or a floppy disk to transfer the key.

  5. On the server, the key should be copied into the authorized_keys file located in your home directory (~/.ssh/ authorized_keys). Note that other versions of SSH use different file locations (check the manpage for more information).

  6. Attempt the connection to the server. You should not be prompted for a password. If you are still prompted for a password, check the filenames and locations, then confirm that the server allows the public key authentication of the correct type (SSH1 and SSH2 keys are not compatible). To troubleshoot, use SSH with a debugging flag (-v), which causes SSH to show the details of the connection and the protocol handshake.

From the very beginnings of SSH, the protocol was designed for secure file transfer as well as remote access. Since SSH was developed as a replacement for the Unix r-commands, the remote copy command (rcp) was replaced by secure copy (scp). scp can be used to copy files from one machine running SSH to another.

To use SSH for secure file copying on Unix/Linux, execute the following command:

$ scp [email protected]:~/data.tar . 

This command copies the data.tar file located in the home directory of the user “rusername” on the machine “server.example.com” to the current directory on the local machine (indicated by a trailing dot). If you have not set up public key authentication, you will be prompted for a password:

$scp /tmp/data.tar [email protected]:~/

The default remote directory is your home directory, so “~” is redundant. It is shown for demonstration purposes only. Also, the trailing slash is required for some SSH versions. This command copies the data.tar file from the /tmp directory on the current machine to the home directory of the user “rusername” on the machine “server.example.com”. If you have not set up a public key authentication, you will be prompted for a password. You can also specify multiple filenames, as long as your last entry on the command line is a directory (indicated by a slash).

Learning to use Secure Shell is a good investment of your time, since it is vital to maintaining a secure network.

Host-Based Firewalls

In this section, we examine the quintessential host protection from network attacks: the host-based firewall . Analogous to Windows “personal firewalls,” this tool shields workstations and servers from network attacks that penetrate company firewalls. Host-based firewalls are also extremely useful for Unix workstation users connected to the Net via broadband connections.

This section is structured around an example of a simple, one-host firewall setup for Linux and OpenBSD. Most free Unix flavors (Linux, *BSD, etc.) include ready-to-use firewalling code, whereas most commercial Unix flavors do not. An exhaustive description of Linux and OpenBSD firewalls would take an entire book (in fact, such a book exists; please see Section 11.7 at the end of this chapter for more information). Here, we cover only an example of effective host-based protection.

Linux iptables and ipchains

Packet-filtering firewalls work by restricting the free flow of network traffic according to predefined rules to allow or deny TCP/IP packets. iptables are an example of packet-filtering firewalls with some stateful features and some content-inspection features. iptables provide a set of rules (organized into groups called chains) that handle incoming and outgoing network traffic.

Linux firewalling code has come a long way since ipfwadm was introduced in kernel 1.2. Recent changes in Linux firewalling code include the netfilter architecture, which was introduced in kernel 2.4. netfilter/iptables are a reimplementation of Linux’s firewalling code that remains fully backward compatible, due to the use of ipchains and ipfwadm loadable kernel modules. iptables offer the benefits of stateful firewalls: i.e., the firewall has a memory of each connection that passes through. This mode is essential for effective configuration of FTP (especially active FTP) and DNS, as well as many other network services. In the case of DNS, the firewall keeps track of the requests and only allows responses to those requests, not other DNS packets. iptables can also filter packets based on any combination of TCP flags and based on MAC (i.e., hardware) addresses. In addition, iptables help block some DoS attacks by using rate limiting for user-defined packet types.

Below is a simple setup for a home firewall, inspired by the “Iptables HOWTO” document. The comment lines (marked with the “#” symbol) within the script provide explanation:

#!/bin/bash
#cleanup - remove all rules that were active before we run the script
iptables -F
iptables -X
#new chain to block incoming
iptables -N allinput

#NOW WE ALLOW SOME TRAFFIC
#packets returning to connections initiated from inside are accepted
iptables -A allinput -m state --state ESTABLISHED,RELATED -j ACCEPT

#allow ssh incoming for management - we allow secure shell for remote server management
iptables -A allinput --source 10.11.12.13 --protocol tcp --destination-port 22  -j 
ACCEPT

#this machine serves as a system log server - thus we allow UDP for systlog
iptables -A allinput --source 10.11.12.0/24 --protocol udp --destination-port 514  -j 
ACCEPT

#allow X Windows connection for remote GUI
iptables -A allinput --source 10.11.12.13 --protocol tcp --destination-port 6000  -j 
ACCEPT

#web server is public - but we do not like some people from 168 subnet (so they are 
 denied)
iptables -A allinput --source ! 168.10.11.12 --protocol tcp  --destination-port 80 -j 
ACCEPT

#allow incoming from 127.0.0.1 BUT only if the interface is local (not the Ethernet card)
iptables -A allinput --source 127.0.0.1 -i lo -j ACCEPT

#DENY - all the rest are denied QUIETLY (with no reject message)
iptables -A allinput -j DROP

#these important lines control the flow of packets that enter our machine from outside
#we send them to our control chain 
iptables -A INPUT -j allinput
iptables -A FORWARD -j allinput

#test - display the rules that were enforeced
iptables -nL

Running the code produces the following output:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
allinput   all  --  0.0.0.0/0            0.0.0.0/0          

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
allinput   all  --  0.0.0.0/0            0.0.0.0/0          

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain allinput (2 references)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0          state RELATED,ESTABLISHED 
ACCEPT     tcp  --  10.11.12.13          0.0.0.0/0          tcp dpt:22 
ACCEPT     udp  --  10.11.12.0/24        0.0.0.0/0          udp dpt:514 
ACCEPT     tcp  --  10.11.12.13          0.0.0.0/0          tcp dpt:6000 
ACCEPT     tcp  -- !168.10.11.12         0.0.0.0/0          tcp dpt:80 
ACCEPT     all  --  127.0.0.1            0.0.0.0/0          
DROP       all  --  0.0.0.0/0            0.0.0.0/0

While a simpler setup is possible, this one is easier to manage, since you can always see what is allowed, from where and on which port/protocol. It also makes the default deny policy more visible.

Detailed iptables configuration is complicated. The standard Unix reference (the manpage) gives information on options, and online guides (such as those located at http://www.netfilter.org) provide more than enough information about the internal structure of iptables (user-space and kernel code) and proposed usage.

The example setup is very restricted. As the comments above point out, we only accepted the connection for a limited number of services. The rest are silently dropped. The remote attackers will not even be able to fingerprint the OS remotely using tools such as nmap, since all packets from hosts other than those allowed are dropped. As a result, our Linux machine is now well protected from network attacks.

References



[1] This password is not really encrypted. It stores a block of data encrypted using the password as the key.

[2] In the terminology hailing from the famous Rainbow Series (http://www.radium.ncsc.mil/tpep/library/rainbow/), discretionary access control is a method of access control where the owner of the object (such as a file) assigns who can use it and how (such as read and write permissions).

[3] That leads to 1 + 7 = 10 in the octal system.

[4] A daemon is a program that listens on the network port. Sometimes a daemon is also called a server or even a service.

[5] Trusted Computer System Evaluation Criteria is an old (1985) document defining standards for computer system security, published by the National Computer Security Center.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset