To continue this trend I am interested in what steps people take to harden Linux servers. As in what steps do people always take when setting up a new server, that are not application specific. Such as setting the tmp partition to be noexec, uninstalling / disabling certain services, e.t.c.
Identify required applications and processes and apply a checklist to either avoid installing them, or worst case uninstall them after the initial build.
Here I'm thinking those common culprits which still seem to go on to far too many distros by default!
- NFS services: nfsd, lockd, mountd, statd, portmapper
- telnet server and ftp server
- R services: rlogin, rsh, rcp, rexec
- BIND and DNS server unless needed
- mail servers such as sendmail
- X11 (unless desktop needed)
- finger daemon etc
Next step up is go through the potential weak services and limit access to them
- use at.allow and cron.allow to restrict access to crontab
- Ensure all devices are unreadable and unwriteable by ordinary users (excluding those such as /dev/tty and /dev/null etc)
- Key files - permissions on these should be owned by root: /etc/fstab, /etc/password, /etc/shadow
- Carefully check hosts.equiv - a great source of access here :-)
- Similarly, NFS config is locked down if it is required
- Disable unneeded system accounts.
- Look at filesystem - sticky bits for all executables and public directories.
- Check all root requirements (PATH environment variable, no remote access as root, group membership, password requirements)
- Check all user requirements (membership in privileged groups, valid shells, umask, SUID, SGID requirements
- and of course the SANS guide is a really good source!
The "Linux Server" space includes a huge range of distributions, each with their own default configuration update strategy, package management toolchain, and approach to default services and open ports. There is also a wide range of deployment scenarios: hardening a web server is quite different than hardening a linux-based router. You may get better advice by asking about the distributions and use cases you most care about.
In that vein, I'll just address Ubuntu security here by pointing to some relevant sources, though much of this will be useful for other situations.
A good introduction is here: http://www.andrewault.net/2010/05/17/securing-an-ubuntu-server/
The community has described some stricter defaults and hardening tips here that lean more towards security even if usability is affected: https://help.ubuntu.com/community/StricterDefaults
Here is a matrix and summary of Ubuntu security features, to help folks research checklists you find elsewhere: https://wiki.ubuntu.com/Security/Features
To see how you can do some of the tests yourself, check out the transcript in http://people.canonical.com/~kees/demo/ec2-session.log driven by the demo code in http://people.canonical.com/~kees/demo/
A summary of what it takes to do what is at: https://wiki.ubuntu.com/Security/Privileges
The security team for Ubuntu has some other useful stuff on their wiki: https://wiki.ubuntu.com/Security/
Point in time system hardening is a beneficial feat, but what really defines deploying a server securely is what is done to maintain that state.
Pick any of the quality checklists (see links below) that detail the recommended configuration modifications to make to strengthen the security of your servers and apply those changes that make sense for your setup. Better yet, codify the recommendations via Puppet (http://www.puppetlabs.com/): this is a win-win, you’ll deploy safer and you’ll give yourself a fighting chance of sustaining the hardened configurations over time.
Bonus: Do attack modeling/threat modeling (http://taosecurity.blogspot.com/2007/06/threat-model-vs-attack-model.html) to focus your defensive efforts. For example, ask yourself questions like:
How could an attacker gain access to these servers?
What are things I can do to reduce their chances of succeeding?
Translate your answer to the second question to specific configuration changes (hardening) or by implementing additional controls. The game, of course, is to minimize the likelihood of any one threat’s success. This takes time, but you’ll feel better about the changes you’ve made and why versus haphazardly making changes because someone said it was good to do.
Get great at logging and reviewing. Prevention always fails – to counter this reality you want to boost logging so you can identify and react faster to incidents and recover quicker. My favorite tool to boost defenses and enhance logging on Linux is OSSEC (http://www.ossec.net/). Spending extra time customizing the rules included with OSSEC to watch for things you’re more concerned about is a worthwhile activity (e.g. listing additional directories and files to be alerted on if they are modified, adding rules or elevating the severity of existing rules to alert you to authentication anomalies, adding rules to watch for changes to the mysql user table (http://blog.rootshell.be/2011/01/07/auditing-mysql-db-integrity-with-ossec/), ad infinitum). Richard Bejtlich just posted a timely blog entry titled Seven cool open source projects for defenders (http://taosecurity.blogspot.com/2011/01/seven-cool-open-source-projects-for.html)
To support the continual verification of your server defenses you can run Nessus (http://www.nessus.org/nessus/) on an on-going basis with the Center for Internet Security (CIS) Linux audit templates. Use the results as a baseline, watch for changes, and remediate discovered weaknesses.
1) Draw on existing respected security hardening checklists to help you draft a custom one that works for your environment (hopefully after performing attack/threat modeling activities and choosing a configuration management framework)
2) Boost observation capabilities: enhance logging (i.e. tune the system to generate sufficient logs for the activities you want to observe), deploy HIDS (e.g. OSSEC), deploy log analysis tools (e.g. logwatch - http://sourceforge.net/projects/logwatch/), maybe capture network flows (e.g. via softflowd)
3) Make it someone’s responsibility to be an assiduous defender of the systems
4) Continually audit and test to verify what you think is being done is being done
http://cisecurity.org/ The Center for Internet Security (CIS) is a non-profit enterprise whose Benchmarking and Metrics Division helps organizations reduce the risk of business and e-commerce disruptions resulting from inadequate technical security controls. The Division provides enterprises with consensus best practice standards for security configurations, as well as resources for measuring information security status and for making rational decisions about security investments.
http://iase.disa.mil/stigs/checklist/ Defense Information Systems Agency (DISA)
The National Checklist Program (NCP), defined by the NIST SP 800-70 Rev. 1, is the U.S. government repository of publicly available security checklists (or benchmarks) that provide detailed low level guidance on setting the security configuration of operating systems and applications.
You could do a lot worse than starting with the Sans checklist.
My only criticism of this is that it does not place enough emphasis on managing the security of a deployed system - particularly ensuring vendor patches are up to date, planning a good permissions model, managing IDS exception reporting etc.
First, you have to figure out the purpose of the server and the threat model you are trying to defend against. Is it a single-use server? Do multiple users have access? If multiple users have access, do you trust them all, or not?
Let me assume that this server is used only for network services, and you do not have to deal with the threat of attacks from someone who has an account on your machine. Here are the steps I take:
Enable a firewall. I use
iptablesto set up a local firewall. I use a default-deny policy: all incoming connections are blocked by default, unless explicitly allowed in the firewall policy. I enable incoming connections to the services that are intended to be exported to the world (e.g., port 25 if this is a mail server, ports 80/443 if this is a web server, and so on).
iptableshas excellent support for stateful filtering, so that once a connection is established, all packets are associated with that connection are allowed.
Upgrade all packages, and enable automatic updates. I update my Linux distribution to the latest version of all packages (
yum upgradeon Fedora, but use whatever is appropriate for your configuration). I also set up a cron script to automatically grab and install updates once a day (
yum -y upgradeon Fedora). I realize that some experienced sysadmins might recommend against automatic updates, because there is the risk that an update breaks some service; you'll have to weigh that risk against the risk of a security breach due to an out-of-date package. Personally, I find the ease-of-mind and convenience of automatic updates to be worth the risk of broken services, but this might not be the right answer in all operational settings.
Enable SELinux. SELinux provides a second layer of defense against attacks on exposed services. It can occasionally be a bit of a pain (it has occasionally caused problems for me, breaking a service in a hard-to-debug way), but for a security-critical setting, I think it's worth it.
Set up SSH for remote administration. You should set up SSH, so that you can remotely administer the machine. I recommend that you generate a DSA private key on the client side, encrypt it with a passphrase, install the corresponding public key in the authorized_keys file on the server, and log in using the private key. You may want to customize the
sshd_configconfiguration file on the server, too. Consider disabling PasswordAuthentication and requiring that people log in using a public key. Password authentication can be a useful fallback in case something goes wrong with your private key, but it's also a greater risk, because humans often choose guessable passwords. If you have other users on your system who you can't rely upon to choose very-high-quality passwords, you might disable PasswordAuthentication. If it's just you and you have very high confidence in all your passwords, you might leave it enabled. I don't prevent root from logging in via SSH, but you might feel differently.
If you have multiple sysadmins, set up accounts for them. Either give each of them
sudoaccess, or set up a separate root account for each sysadmin.
Enable DNSSEC. I configure my servers to run a local caching DNS server that validates hostnames with DNSSEC wherever possible, to reduce the risk of DNS spoofing.
Then, for each service that is exposed to the world, I take precautions to secure that service. For instance, I enable cryptography (e.g., STARTTLS for mail servers) and chroot or sandbox servers wherever possible. However, the specifics will vary from service to service. Therefore, I suggest submitting a separate question for each service that you intend to run, asking for advice on how to lock down that service.
If you're looking for a Linux distribution that already has a great deal of hardening applied, I can highly recommend Openwall Linux.
(Comment: If you give untrusted users on your server, then it becomes much more challenging to tighten down the security: the attack surface is much greater. If that's a concern for you, I suggest asking a separate question about how to lock down your server to protect against attacks by local users with accounts on your server, as the set of techniques for doing so is quite different.)
And what about the grsecurity/PaX kernel patches, these include very nice features for hardening the server at kernel level.
- Protect heap and stack overflows
- Hide other users processes
- Role based access control list
- Chroot hardening
- /proc, FIFO and dmesg restrictions
- Advanced logging capabilities
For Red Hat, NSA has advice on hardening. See Configuration guidance for Red Hat Enterprise Linux 5 - NSA/CSS.
They should be helpful for CentOS and other derivatives also.
If you are trying to secure your system by uninstalling unneeded packages/services than you already have a bigger problem. These packages should not have been installed in the first place.
You should install a minimalistic system and only add packages which you really need. The same applies to your kernel. Compile your own kernel with only the features you need. Don't use your distribution kernel with support for everything (you will not need 95% of it anyway)