The first thing to realise when installing a Linux system is that most distributions are not 100% secure out of the box. Most Linux distributions will helpfully set up systems such that they will happily accept incoming connections for many services: telnet, ftp, rsh, rlogin, imap, pop-3, nntp. While this is great from an "install it and it just works" point-of-view, it is less than helpful from the "I need a secure system" approach.
While securing a system can be a pain, and will obviously involve the expenditure of some time, it is an investment well made. Consider the amount of time you will need to expend in the following scenarios:
One of the problems with Linux is that it is free. While the average hacker would not have access to their own Sun/SGI/HP system to work out how to crack it, most will have access to a PC to experiment on. There are also a number of "rootkits" available for the "script-kiddies" who don't actually have the technical knowledge to hack a system from first principles, but are quite capable of running an executable which does the hard work for them. With systems that are not bolted down security-wise, or that are running older known-to-be-vulnerable software, it can be trivially easy to find machines to hack into.
So, what steps do you need to take to prevent yourself being hacked and to monitor where possible hack attempts are originating from? In the rest of this paper, I will highlight the following:
All users with accounts should have passwords set. In particular, you need to have a strong, unguessable password for root.
Ensure that root can only login from the console of the machine itself. Valid terminals are listed in the file /etc/securetty or /etc/login.defs depending on the distribution you are using. You will still be able to access root by using the su command once you have logged in as a normal user. Only login as root when you need to; don't do normal user tasks as root.
Linux distributions vary in the services that they offer by default and of course this will vary depending on what services you yourself choose to install. Hence you should check to see what is enabled.
Bear in mind that network services are offered in two ways; either as standalone daemon processes (usual for things like samba (file sharing), nfs (file sharing), lpd (printing), httpd (Web serving)) or as programs started from inetd.
To disable services that run as standalone daemons, you need to find out where they are started from. Standard places to check are /etc/rc.d/rc3.d and /etc/rc.d/rc.inet2. RedHat provides a utility called ntsysv which gives a friendly interface to this.
Disabling services that run from inetd is more straightforward, since they all have entries in /etc/inetd.conf. To see what is enabled, run the following command:grep -v ^# /etc/inetd.conf
To disable services in /etc/inetd.conf, simply place a # symbol at the beginning of the appropriate line, then run the command:killall -HUP inetd
which will make inetd reread its configuration file.
Once you have decided which services you want to allow, you should then decide where you will allow users to access them from. For example, you may decide that merely restricting them to users within the 137.222.x.y domain (the whole University) will suffice; for others, you may want to restrict access to one or more subnets, or perhaps even down to the individual machine level. As an example, certain machines within the Computer Centre are configured in such a way that only machines within the 137.222.12.y subnet (Computer Centre Staff) are allowed to access them.
Setting up this type of security is fairly straightforward for services provided via inetd. If you look at the entries in /etc/inetd.conf on virtually all Linux distributions, you will see that every entry includes /usr/sbin/tcpd. This is part of the TCPwrappers package, which allows an administrator to restrict access to network services on the basis of the originating machine-name, network, or IP address. (There's quite an interesting article about TCPwrappers in the August 1997 edition of Linux Journal entitled 'Wrap a Security Blanket Around Your Computer').
TCPwrappers use the files /etc/hosts.allow and /etc/hosts.deny for configuration. So, for example, you can set something up like this:
in.ftpd: ALL: twist /bin/echo 421 wwwcache1.bris.ac.uk FTP server. \
Access denied to client %n \(%a\). Your connection attempt has \
been logged.\\r; sleep 5
in.telnetd: ALL: twist /bin/echo Access is not permitted \
from %n \(%a\).\\r; /bin/echo Your connection attempt \
has been logged.\\r; sleep 5
The above combination of files means that:
Note that for protocols which use numeric status codes as part of their interaction (for example ftp, smtp), you should ensure that you send a valid "service not available" reply code so that automated clients don't get confused.
TCPwrappers log what they do via the syslog function; this normally gets written to the file /var/log/secure, although this may vary between distributions.
It is possible to configure TCPwrappers in other ways; see the manpages for hosts_access(5) and hosts_options(5).
Limiting access to network services not started from inetd is more complicated. For NFS, you export filesystems to specific machines (in /etc/exports). For samba, you use a hosts allow entry in the smb.conf file. For lpd, you enter permitted hosts in the /etc/hosts.lpd file.
By default, ftpd will allow anonymous access (that is, login as ftp or anonymous). Most systems that require FTP do not require anonymous access. This can be disabled by editing the file /etc/ftpaccess. Change the line that reads:class all real,guest,anonymous *
toclass all real *
As mentioned above, TCPwrappers log their actions via syslog. It is well worth making sure you know what is being logged where. The file /etc/syslog.conf will tell you where syslog is sending its information. You should check these files on a regular basis; in particular checking for "connection refused" messages from TCPwrappers.
One possible approach to this is to set up a cron job to check these files for you, and mail you interesting details. For example, I use the following:
DATE=`date -d "1 day ago" +%b\ %d | sed -e 's/0\(.\)$/ \1/'`
# A script to monitor the /var/log/messages and /var/log/secure files.
cat /var/log/messages /var/log/messages.1 \
| grep "^$DATE" \
| grep -v 'kernel: Warning: possible SYN flood from ' \
| grep -v 'last message repeated ' \
| mail -s "`hostname -s`: messages" $LOGREADER
cat /var/log/secure /var/log/secure.1 \
| grep "^$DATE" \
| grep -v ': connect from' \
| mail -s "`hostname -s`: secure" $LOGREADER
This script looks through the appropriate files for yesterday's entries, throws away harmless (expected) lines, and mails the rest to me. This runs each night.
This method has the following advantages:
There is the disadvantage that you need to decide what is and is not specific for your particular system. The best thing to is to take a look at the logs you currently get, decide what can be thrown away, then use an appropriate incantation of grep to do it for you.
More security can be gained by actively looking for suspicious activity. Tools such as Tripwire are very helpful in this respect. Tripwire looks for system files where the date, filesize or file permissions have changed from what it expects to see. It also checks for things like a change to a file's checksum. Tripwire is available via anonymous FTP from the Tripwire web page.
On a more mundane level, compromises can be detected by occasionally using the ps command and looking for processes you might not expect to see running. Or by running the last command for people logged in from unusual machines at unusual times. Cross-checking against other machines can also be useful. I spotted a hack once by noticing that a user was recorded as logging into machine B from machine A at 3am. Checking machine A indicated that there was no-one logged in on A at that time.
Note, though, that the first thing a hacker does is to try to erase all traces of having logged in. The paranoid administrator can work around this by directing the output of syslog to another machine over the network, or even a parallel- or serial-port printer. It's difficult to remove traces of hacking when you need to break into a building to steal a physical printout!
The kernels supplied in recent versions of RedHat Linux come preconfigured with IP firewalling support; to check for this, look for the existence of the file /proc/net/ip_input (in 2.0.x kernels) or /proc/net/ip_fwchains (in 2.2.x kernels). If these files don't exist, you'll need to compile a new kernel and enable firewalling.
Now it needs to be said that the configuration of firewalling is not necessarily straightforward. 2.0.x kernels aren't too difficult to do, but the new IPchains interface in 2.2.x is far more flexible (but slightly harder to configure). I won't cover configuration here; you should refer to the man page for ipfwadm(8) on 2.0.x systems and the man page for ipchains(8) on 2.2.x systems. The Firewall HOWTO mentions configuration using ipfwadm amongst other things. Meanwhile, there is a seperate HOWTO for IPchains.
Warning: make sure you have easy access to the system's console while configuring IP firewalling. Certainly with ipfwadm, the first thing you do is set a default policy. If you set that to deny or reject and you're connected over the network, then your network connection will vanish!
There's little point in investing time in securing a system if you don't keep it up-to-date as new vulnerabilities are discovered and new exploits developed.
The best thing to do is to subscribe to appropriate mailing lists for your distribution vendor. We have an online list of vendor web pages available; you will generally find a link to appropriate resources somewhere on their home page.