Linux controls 97% of the server market. As such, any budding hacker ought to know the basic defenses of a modern Linux server. For that reason, we prepared this guide as an intro to basic methods for Linux server hardening. And since the best way to learn is by doing, we’ll walk you through setting up these defenses one command at a time.
Linux security is a deep rabbit hole with plenty of nooks and crannies to explore. But you’ll never become a master unless you take the first steps and start playing around with the many parts of this complex system.
So open up your Linux command line and follow along, as we try to make our box unhackable!
fail2ban: make Linux server hardening easy
If you open the logs of any Linux server with ports exposed to the web, you’ll see a barrage of random attacks of every kind you can imagine. To block these constant scans and simple exploits, deploy fail2ban. This tool works by outright blocking any IP that triggers too many failed login attempts.
As an added bonus, your logs will clear up quite a bit as well. You can set it up on Ubuntu with the commands below.
$ sudo apt install fail2ban
$ sudo echo 'enabled = true' >> /etc/fail2ban/jail.conf
$ systemctl restart fail2ban
That’s all you need! IPs that make excessive login attempts will now receive a prompt ban.
As you can likely guess, fail2ban offers a bevvy of config options. Learn more from these docs: https://www.digitalocean.com/community/tutorials/how-to-protect-ssh-with-fail2ban-on-ubuntu-20-04.
Public key auth
If you allow remote users to connect with a password, you open up the risk of someone guessing the password. For example, a dictionary attack could crack a user account. So it’s better to use public key auth instead. You can create an SSH key using the command ssh-keygen. Then, you should find your SSH public key in the file ~/.ssh/id_rsa.pub. It will look like this:
$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCpsSlljBDrmP1G2rLxSAe8mJMe5y5TEHemFigiFImibkxTtFkVl7HXSbdQ6L4j5UkDTSheOFo7Q5H/dowBeZgak9CicrpExRp61CT8h8NAVSILuNpjsHgUm3gA48uqKM89zUD8amrCRMxPyB83NmkGxsu8pnfd0yu3cpnAra6sci/fctvRQUhuqeWQZB3pUVy+hIEMM3j+b84ZQROzcJlWZJo/WxmOJHhs94lJB93cx5aEFggYxLZJnjXfhYjX/4qP/rXN03rqAoukZoMSAFnSbCGdYpoL4A8NY+RmxP3BMzE+Aj7onnGknSLUYYcTJSlh8oC1n/KqAGPGJCv4PgL6Ma3RLfkxNd0AoXq7QW8nzrR6KFuXJfj+mGCcmKwOc7RaxCKO8VEB02oQa6ys9BeWPcpkjAtLx8FVVALGxRc3u4b6RIQ9r1P0TW4e5cxnvR7/iUB58J45wEtHTVbpLZeGNPBHhtFnnQacTlc9gsrBIfadEc7KiHDWLgx6E90wyWs= author@hackingloops.com
You can enable a user to login with their public key by adding their key to the file ~/.ssh/authorized_keys in the user’s home folder. Then, disallow password auth by adding the line PasswordAuthentication no to /etc/ssh/ssh_config. Voila, auth protected by the power of GPG.
Public key auth provides a pretty big security benefit, despite being easy to setup with minimal configuration. It’s a win-win and there’s really no excuse not to take advantage of it.
Restrict login IPs
You can use a firewall to disallow connections except from known IP addresses. Like most of the configs in this guide, banning all IPs except your own (and other ones you want to allow) needs only a few lines of code. We’ll use the newbie friendly command line tool UFW, which stands for Uncomplicated Firewall.
Watch, you only need one command:
sudo ufw allow from [your IP address here]
Repeat the line above for all of the IP addresses you want to whitelist. That’s all there is to it! Try logging in from another IP address and you’ll get an error. If you want to allow IP addresses for certain services or ports, you’ll need to configure that as well.
By the way, you can learn more about specific UFW configs in this doc: https://www.linode.com/docs/guides/configure-firewall-with-ufw/.
disable root login
Another easy peasy fix – just open the file /etc/ssh/sshd_config and look for the PermitRootLogin directive. If it’s set to yes, change it to no. If it’s commented out, uncomment it.
Once you’re done, you can restart the SSH daemon like using the command below:
$ sudo systemctl restart sshd
After the command finishes, you should try to log in remotely as the root user and see what happens. If the change worked, you should see an error.
SELinux: the Swiss army knife of Linux server hardening
SELinux is an entire suite of security configs for Linux, which can require quite a bit of work to master. To start, install SELinux admin tools like so:
root@linux:~# apt install -y selinux-utils selinux-basics
Now you will be able to query your current SELinux strictness level. By default, SELinux is disabled.
root@linux:~# getenforce
Disabled
Alright, to enable SELinux in the relevant config file, just run this command:
root@linux:~# selinux-config-enforcing
Activating SE Linux
SE Linux is activated. You may need to reboot now.
Just one more step remains: reboot and make sure that SELinux is activated.
root@linux:~# reboot
...
root@linux:~# getenforce
Enforcing
There’s another option we can set it to, called Permissive. If you want to learn more about the various SELinux config options, consult this in-depth guide: Getting started with SELinux.
File system permissions
A big part of Linux server hardening on a multi-user system is making sure that users can’t access each other’s files. If you’ve ever played around on Linux in the past, you likely know what it’s like to have a permissions error. Maybe you even gave up and just ran chmod 777 to make things work.
Just last week, I ran this command on a whole directory tree like so:
chmod -R 777 *
After all, sometimes you need to see if it would make some really old software just work. Certainly, we’ve all been there. On a production system, though, this won’t suffice. You should make sure that users can’t read each other’s files, and that secret files are only readable for users who truly need access.
If you haven’t yet learned about how Linux file permissions work, read this easy tutorial from Red Hat: https://www.redhat.com/sysadmin/linux-file-permissions-explained.
There are more Linux file security tools, such as AppArmour, which boast even more finely grained access controls. But I suggest that you start with basic Unix style permissions and work your way up from there.
Further reading on Linux server hardening
Linux offers a huge array of security features for admins to protect their servers. Learning them takes a lifetime. If you want to dive further into the world of Linux security, I suggest you read some of the following high quality texts.
Once you feel a bit more confident with Linux security concepts, you should move on to tackle some Linux themed CTFs. Because they let you learn through action and explore obscure parts of the system, CTFs are an especially good way to learn Linux. If you need help finding high quality Linux themed CTFs, check out the resources listed below.
- Bandit from OverTheWire
- Gofer from HackTheBox
- CTFLearn
With enough practice, using resources like those listed above, you’ll be well on your way to Linux server hardening mastery. Accordingly, don’t give up, and as always – happy hacking!
Leave a Reply