There’s no way a generic installer can assume what it is to be used for. And, as Linux is generally a cornucopia of software - and as more and more "non-techie" people adopt Linux - this has to add up to bucket loads of web servers, mail servers, ftp servers and more which are running, but aren’t needed. This is particularly true if your system has been running for some time. Modern distros, like Ubuntu, are far more defensive by default - but this doesn't help large and/or busy systems who can't afford to rebuild from scratch each time a new release is available.
There are tools to tighten up and harden your server – and we’ll introduce you to Bastille – but it’s important to understand how to do it manually too.
Disable unused services
The very first step is to seal any ports you aren’t deliberately using. Although Linux is secure by design, vulnerabilities are regularly discovered and it is only sensible to mitigate risk. It's a good idea to use nmap to check the services your computer is exposing. Check this over the Internet using your public IP address too.
The bulk of services provided by a Linux server are controlled by /etc/xinetd.conf. The xinetd process listens for many network requests and palms it off to the appropriate application. There are memory and performance reasons for doing this; instead of having many different listening servers all running from system boot, it is more efficient to launch and run xinetd instead, merely launching instances of the ssh or telnet or ftp or rlogin or other servers on demand.
/etc/xinetd.conf directs requests to configuration files found under /etc/xinetd.d. It’s a doddle to disable (or re-enable, if needed later) services: just comment out the appropriate entry in the configuration files. To disable ftp, for instance, edit /etc/xinetd.d/wu-ftpd. Add a “#” to the beginning of the “service ftp” line to comment it out. Save the file. Then restart xinetd with the command /etc/rc.d/init.d/xinetd restart. If you now try using ftp to connect to your server (from another machine, or ftp localhost on the server itself) you will find the connection fails.
Check out the services xinetd is running on your computer; other candidates you might like to consider removing are rlogin – which bypasses password authentication – and finger – which can give malicious people insight into when your computer is unattended.
If you have an older Linux system and can't find /etc/xinetd.conf then you’ll find the same is achieved by editing the single config file /etc/inetd.conf and commenting out entries as appropriate. Then restart inetd by finding out its process ID, or PID, with ps aux | grep inetd. The second column listed is the PID. Use kill –HUP xxx where xxx is inetd’s PID. However, if you have a Linux system of this age (RedHat Linux prior to version 7.0 for example) then you have an additional safety risk beyond open ports; you should also upgrade your software to be certain you are countering all known vulnerabilities. More on this following, but first it’s time to deal with services that don’t work through xinetd.
As mentioned, xinetd handles services which may only have periodic use and for which it would be wasteful to run independent listening processes for each and every one. The ramification of this is that services which do have anticipated high use are running stand-alone and from system boot, and which are not controlled by xinetd.
An example of this is the Apache web server. It runs as its own service. To disable Apache – or any other server software – you have two basic options. The first is to simply uninstall the application, or to stop it running and then prevent it restarting at boot time. To achieve the first, refer back to your distro’s package management tool. To achieve the second, use its /etc/init.d script followed by the 'stop' parameter. At worst, the brute force method will always work: run ps aux | grep httpd or ps aux | grep apache2, depending on your distro. As above, the second column is the PID. Enter kill -9 xxx where xxx is the PID.
This stops the process running immediately. However, as yet there’s nothing to stop it starting again when you next reboot. To solve this enter the command ntsysv. This is a simple tool to configure Linux runlevels and the services that run at each runlevel. Merely uncheck the box next to Apache, and similarly for any other services that auto-run which you do not use. A text tool to achieve the same thing, albeit with more skill required, is chkconfig.
Patching the OS
An essential requirement to maintaining security is to keep your operating system up-to-date. This ensures you receive updates to fix known exploits and vulnerabilities, as well as bug fixes and performance and feature enhancements.
Most Linux vendors provide information on available updates. For instance, Red Hat publish their list at www.redhat.com/security/updates/notes. (Information on Red Hat’s update and support policies, including how to sign up for automatic notification of errata is at www.redhat.com/security/updates.)
Other distro users can find links at Linux-Sec.net’s list of online security patches and updates by vendor.
With the basics of manual hardening down pat, let’s check out a free open-source tool to automate and simplify the process. Bastille will disable unnecessary services and install operating system updates as well as configure a firewall, enforce password policies, create a second root-level account and more. What’s nice is that Bastille leads the user through a simple series of yes/no questions, giving a detailed explanation of why each question is asked and what will happen if ‘yes’ is chosen. It doesn’t merely expect guesswork, nor does it blindly alter your system – instead, it genuinely hardens your computer and educates on security in the process.
Pleasantly, you’re also not locked in to Bastille’s changes should you decide some of the setting changes weren’t for you. Running RevertBastille automatically restores the state of all config files and settings to just how they were before Bastille made any changes. Obviously, if you make changes to your system manually after running Bastille, you will lose these too so it is best to test changes as soon as possible after applying to ensure you won’t harm anything else if you need to revert.
Unfortunately, Bastille is not for everyone: versions exist for Red Hat, SUSE, Debian, Gentoo and Mandrake (as well as non-Linux UNIX variants HP-UX and MacOS X). If you do run one of those systems, you really are well-advised to run Bastille. You can download the latest version from SourceForge.
Let's give Bastille a run-through.
Launch Bastille by calling up a terminal prompt as root and executing ./InteractiveBastille. You are lead through a series of security steps, as follows.
- Apply a firewall to prevent access to potentially vulnerable services, using iptables. This is a big topic which could not be adequately covered here. Fortunately, Bastille’s explanations do an admirable job. In one sense, this is redundant; if the service has been disabled as we discussed above, there won’t be anything listening on the port which can be exploited. However, you might later restore a service for testing or for internal use. Or it may be restored inadvertently. Whatever the reason, Bastille errs on the side of tougher security by protecting your system from the same exploits via more than one method.
- Retrieve and apply available operating system patches, as discussed above.
- Audit the system tools which have the SUID flag set and which run as the superuser, even for ordinary users. The danger of SUID apps is they perform actions with full superuser powers no matter who executes them. This is essential in some cases: for instance, if the passwd command couldn’t write back to the shadowed password file then nobody could actually change their password. However, you may not want ordinary users running the dump and restore commands, both of which come with SUID status out-of-the-box.
- Tighten up account security. Here, Bastille first asks to create a second account with root-level access. This means you can disable root if desired, or at the very least if you exclusively use the second account, you can tell if someone else is trying to log in as root because you know it won’t be you. This section of Bastille also prompts to enforce password aging and some other items like assigning a restricted or useless shell to non-user accounts. There’s wisdom in this last point. Here’s a true story: back in 1991, I myself gained root access to the Computer Science department SunOS server at the University of Newcastle (which I reported.) It all began because I was casually looking through /etc/passwd for accounts which didn’t have a password. I logged in as sync and came across an exploit.
- Enhance boot security. This helps restrict the computer even if someone can get physical access to it and try starting it up in single-user mode.
- Deactivate or restrict unnecessary services, as discussed above.
From this point, the remaining modules are less significant (though still beneficial) and include disabling program compilation, limiting system usage, increasing logging, installing SSH, tightening up DNS and Apache, disabling printing and a couple of other things.
Bastille now exits, but has not yet made any changes. All your choices have been saved to a configuration file. Run ./BackEnd.pl to actually enforce them. Reboot and test out your hardened server. Any malicious attackers will find far less vulnerabilities and options against your computer.
Security is something we all need to take seriously. Many people may not even be aware that they have possible insecurities. Fortunately, the above steps are easy to understand and simple to implement. You should also check out Linux By Scratch's excellent guide to building a hardened Linux system from scratch.