One of the most common areas in Linux that gets overlooked during a production deployment is overall security. Specifically, the hardening of the operating system against common exploits (and hardening can encompass both policy and configuration for both internal and external use). We are going to talk about some common ways to protect our server from both the inexperienced as well as the malicious users it will be exposed to.
Protect Yourself From Prying Eyes
First and foremost, avoid using all services that allow unencrypted or unobfuscated traffic whenever possible (with HTTP being the notable exception for obvious reasons). This means not installing or configuring (and for goodness sake, not opening the associated ports on the local or enterprise firewall) for the following:
There are perfectly acceptable and much more secure substitutes for each of these options: ssh, sftp, scp, etc. I included vnc in our list because setting it up by itself is just hanging a sign on your server that says, “please break in.” Run vnc over ssh for a secure method of managing your system remotely. Better yet, run it over ssh and connect via VPN to your network so even that is not exposed outside your firewall(s).
Put Your System on a Diet
Just because your repository or installation media comes with 4,123,432 packages does NOT mean you have to install them all. In addition, there are many services that get installed and started that you do not need in a server environment (bluetooth anyone?). The more packages you have, the more services you have running, the more likely something can be exploited.
There was a time when it was necessary (financially) to run multiple network services on a single system (maximizing infrastructure investment). However, with the vast improvements in virtualization, you can now segregate your services better to limit potential compromises per system (i.e. web services can be separated from caching, proxies or databases).
Security by Abstraction
One of the strongest methods of protecting your systems is through abstraction. This consists of maintaining an intelligent firewall zoning configuration (web servers are in an “untrusted” zone that can only communicate one zone down to the application services in a “trusted” zone and finally they communicate directly to the “data” zone where your databases are – each one is restricted to the one directly above and/or below). This type of configuration makes it less likely that a compromised system can be used to attack resources in other zones since another firewall interface would have to be defeated.
Although this should be an obvious place to harden your server, it is an unpopular one. It is sometimes hard to strike a balance between being secure and making access so difficult no one wants to use the system. Your password policy in general should be strong enough that it is barrier to general access, as inconvenient as that may sometimes be.
Enforce a password policy that absolutely requires a password of at least eight characters, one capital letter, one number and one special character. Encourage passwords that are even longer and more complex by setting those passwords to expire less often. You can set the policy in the following location with the following fields:
- Format: [username]:[password]:[lastpasswdchanged]:[minimum days]:[maximum days]:[warn]:[inactive]:[expire]
- Note: you can use the chage command rather than editing the shadow file directly
I also highly recommend that you disable root login completely. All activities that need elevated privileges should be executed using sudo. Finally, don’t disable the password prompting during a sudo command (which can be disabled by adding NOPASSWD: ALL to that user’s entry in the /etc/sudoers file). Yes it is sometimes a pain to retype your password, but it is one final poke by the system that may save you from running something unintentionally.
What Did You Say Again?
Just when you think that you have scaled back on your packages and services, stop and listen, or rather find out what your server is listening for. Many times you will find you missed an unintended application or service that is listening on a port it does not need to. You can get a list of everything your server is listening for by port as follows:
nmap -sT -O localhost
Both commands will let you know what your server is listening for so you can enable it in your firewall(s) or remove it from the the system.
How Did That Happen?
Make sure your system is logging appropriately. Most of the default logs will appear in /var/log and will either have an appropriately named file or subdirectory containing the pertinent logs (/var/log/http for apache for example).
The last thing you want is to be caught flat footed by the boss when he comes by–you really do not want to be in this position and not know what happened.
Use logwatch or logcheck to help you audit those logs or monitor suspicious log activity. You can configure them to send you local system mail or, with exim/sendmail/another mail service, send alerts to one or more email addresses.
This is by no means intended to be a comprehensive list of hardening procedures or tools. This is meant as a beginning, to get you thinking about what you need to do to secure your server and infrastructure. There are a number of other topics we could discuss (system accounting, intrusion detection systems, no owner or world readable files and directories, kerberos, centralized authentication, etc). If the topic is popular enough, we can go into some of those other areas or do a deeper dive in any of the categories above, including specific tutorials. Leave a comment below and let me know!