Recently, prompted by the security course I’m currently taking for my computer science degree, I decided to look into what could be done to improve the security situation of my Linux machines.
This blog post consolidates the results of my research. It lists various command-line tools relevant to the integrity, confidentiality and availablity aspects of security, and categorises them by whether they are most relevant to a public-facing server (“networking”) or to private, personal use (“general”).
Obviously, you can and probably should use all of these utilities, regardless of whether your machine serves web applications or is used solely for watching cat videos on YouTube. However, I found it useful to distinguish networking-specific security tools from other kinds, in order to prioritise my own security measures on different machines.
P.S. Please note that this post is written from the perspective of an Ubuntu user, and as such, all instructions and scripts are Ubuntu-specific. However, many of these tools I learnt about from Linode’s security resources, which provide instructions for other distros as well - I highly recommend checking it out, regardless of whether you’re a Linode customer or not. 99% of their instructions are applicable to any generic Linux installation.
Specify access control for ssh login (whether to enable password login, etc)
If you use SSH to log in to a remote machine, there are some simple steps you can take to make it harder for unauthorised users to gain access.
iptables & iptables-persistent
- ip-tables: Allow or deny network traffic based on IP address, port number/service, protocol etc. - iptables-persistent: Enforce iptables rules at boot time (it baffles me that this has to be implemented in a separate tool...but that's Linux for you)
A firewall filters all network traffic to your device and decides whether to keep it or not depending on certain parameters you set. This is an excellent safeguard against a number of kinds of attack, including malicious attempts to log into your server.
ip-tables is a highly configurable, but not particularly user-friendly, firewall for Linux. There are so many things you can do with it and the settings you need vary so widely depending on your individual circumstances that I can only give a brief overview here.
SSH login whitelist. Drop all SSH connections to your machine except for those originating from specific IP address/es. If you have a remote machine that you access via SSH, this is great for peace of mind - but with power comes great responsibility. Be VERY CAREFUL with IP whitelisting - if you have a dynamic IP address (an IP address which is reallocated on a regular basis) or you do anything wrong, you could lock yourself out of your machine!
- Rejecting all packets from known malicious IPs. This is most useful if there are just a small number of IPs you know are troublesome - if you are the victim of a DDoS attack, it’s just impractical.
- Accepting or rejecting packets to/from particular ports and/or protocols.
Temporarily ban network traffic from IP addresses that exceed x packets in y seconds.
Fail2ban comes in where iptables falls short: dealing with repeated malicious activity from a large number of different sources.
Fail2ban works quite simply. If a certain type of request is made a certain number of times within a certain timeframe, it will temporarily ban requests from that IP address for the duration you specify.
This is useful for dealing with DDoS attacks. In addition, fail2ban can identify repeated incorrect login attempts and ban the IP address initiating them.
If you are currently experiencing an attack, you should probably tweak the default fail2ban configuration. For example, you could set a particularly lengthy ban duration (perhaps several weeks). If your attacker is a) human or a very smart bot, and b) paying any attention, they might be sensible enough to give up at that stage.
Automatically install security updates via apt.
Keeping your operating system up to date is a simple but essential security measure - you are at risk if you don’t have the latest bug fixes and security patches, and attackers are known to target out of date systems.
To save you the trouble of having to remember to update software manually, it’s a good idea to set up automatic updates. You can configure
apt to perform all kinds of updates automatically, but I would advise against this if your system runs anything critical. In some cases, updates conflict with existing configurations and lead to downtime.
For this reason, it’s safest to configure
apt to only perform security updates automatically. This still gives you the greatest security benefits of automatic updates.
Open source antivirus protection.
ClamAV seems to be the go-to antivirus for Linux. It’s open source, and pretty much every other AV solution available for Linux uses it as a basis.
A downside of ClamAV is it has to be run manually. There is a “clamav daemon”, but I could never figure out how it works. I wrote this little script to run ClamAV with my preferred parameters from the terminal (there’s a GUI available, but it’s nearly unusable due to colorscheme mismatching in my distro).
While reading up on how to configure ClamAV, I learnt that there is an option you can supply to take advantage of multiple CPU cores, if you have them. I have an 8-core CPU so I tried running ClamAV with the appropriate option, but bizarrely it actually decreased performance to the point where my computer was barely usable, thrashing the CPUs unnecessarily. Without that parameter, it works just fine, albeit very slow (I guess that’s just the nature of antivirus scanning).
Compress and delete log files on a regular basis.
Logrotate automatically compresses and, eventually, deletes system logs on a regular basis so they don’t stick around forever, chewing up disk space.
This utility is enabled by default on most Linux distros, I believe. But if you find that your logs are taking up more space than you’d like, it’s worth adjusting the default configuration a bit.
I first began looking into logrotate config when I downgraded my Linode server to a smaller hard drive and suddenly had to worry about how much space things took up.
Backup only those files that have changed since the last backup, locally or over SSH.
In the event that some calamity befalls your machine, you need to be able to recover your data. Making manual backups is tedious and error-prone, but thankfully there is a tool which makes it almost effortless.
rsync lets you copy just those files that have changed since the last backup, and is therefore very efficient. You might not want to backup everything on your machine, and
rsync has a solution for that too, albeit one that requires a little once-off effort: you can provide, as an argument, a text file containing a list of all the directories and/or files you want excluded from copying (an ‘exclude-list’). This also works in reverse: you can supply a file listing only those files/directories you want copied (an ‘include-list’).
I wrote a little script to backup all my most important data to an external drive. I also have one for making a backup of my remote server (another awesome thing about rsync: it works over ssh).
I’ve supplied the two scripts - which demonstrate the most basic use of rsync - on gist. Feel free to modify them for your own usage. These scripts just backup any new files and overwrite any old files that have changed since the last backup.
Note that rsync also has a “mirror” mode, which makes the backup EXACTLY match the current data - meaning any files deleted since the last backup will be deleted on the backup, as well. This is an important distinction. I choose not to use mirroring because I like to delete files locally when I’m no longer using them, and keep a backup if I ever need them again.
Encrypt home folder - automatically decrypts on login
When you first install Linux, you’re given the option of encrypting your hard drive. This is a good idea especially if you’re going to be using the machine for work or any similarly sensitive purposes. If an encrypted hard drive is lost or stolen, a thief won’t be able to decrypt its contents.
If, like me, you didn’t choose to encrypt your hard drive while installing Linux, fear not - there is another way! EncryptFS is here to save the day.
EncryptFS lets you specify a particular directory to encrypt, and automatically decrypts the directory when you log in.
It’s actually possible to encrypt your entire home directory, if you have enough disk space - this works by creating a new encrypted directory, copying the contents of your home directory to the encrypted one, then replacing the unencrypted
home/ with the encrypted
home/. EncryptFS comes with a built in option to do this, so you don’t need to worry about doing it manually.
Unfortunately, once Linux is installed, encrypting your entire filesystem (root directory) is not possible. There are files stored outside the home directory that could contain sensitive information, like log, configuration and in particular, temporary/cache files. You don’t necessarily know what a malicious party might find in this unencrypted part of your disk, so if you want absolute peace of mind, sadly you’ll have to install Linux afresh with encryption switched on from the start.