Every minute, every few seconds, your server is receiving a number of malicious connections; from an IP address in Moldava checking to see if a far out port is open, to someone in Iran trying to login into your server with a random username. It’s a bit unsettling but rest assured these connections are likely stemming from autonomous crawlers scanning the web and you are not being personally targeted.
The attacks seem to take on two different forms; 1) The port is accessed via SSH protocol (i.e. accessible through the use of specialized software or browser extensions), or 2) The port can be accessed via HTTP (i.e. accessible via a fresh browser install). Depending on your setup, you will likely spot attempts of type one in your system authentication log files. Attempts of type two should be visible on any firewall or web server logs you may have setup.
The rest of this post is written with a Debian based OS in mind, so commands may be slightly different depending on your distro. Below are a few basic items to begin securing your Linux server.
- SSH Keys
- Uncomplicated Firewall (UFW)
- Apache Web Server
You don’t need to use SSH keys to log into your server but it would make it a lot more secure than having a generic root account with a password.
SSH keys utilize public-key cryptography where a public key is used for encryption and a private key is used for decryption. Your public key can be shared openly without compromising your server’s security. However, you will need to make sure your private key is never disclosed.
Your private key is a file that you will use every time you need to make a connection to your server. This means in order to connect to your server the individual must physically (or would it be digitally) have this file. This communication occurs over port 22 and also known as Secure Shell (SSH).
This document over at Digital Ocean is extremely informative on how SSH works, how to setup SSH for your server and even walks you through disabling root login.
If you happen to have multiple servers, you will need to consider trade-offs between security and convenience. The issue is explained beautifully by tylerl and YaOzl at Stack Overflow and I highly recommend reading through the thread. In summary, you must make a choice between using the same key for all of your servers or generating different keys for each server (potentially, inconvenient). Moreover, since it is recommend you add a passphrase to your key-pair, you have the option of using the same passphrase or using a different one for each key-pair.
Last but definitely not least, make sure to back up your private keys in a secure location and produce an additional external backup in case of an emergency. Your private key is only as secure as you make it.
Uncomplicated Firewall (UFW)
While you could directly use iptables to manage your server’s firewall, a simpler alternative is to use Uncomplicated Firewall (UFW). UFW is a front-end to iptables that is easier to learn.
UFW is disabled by default so you will want to enable it as soon as possible. You will also want to make your first rule so that you can SSH back into your system. It is a good idea to set this rule to LIMIT to prevent brute force attacks on your server.
sudo ufw limit 22/tcp
sudo ufw enable
sudo ufw logging on
If your home IP happens to be static (unlikely, but worth a look), you could limit your rule even further by specifying your home IP.
If you are using your server to serve a website you will need to write additional rules to allow connections to port 80. If your site makes use of SSL certificates you will also need to open port 443. Since you want to make your site available to everyone make sure to use ALLOW instead of LIMIT here.
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
If you are using multiple servers, you can be write even more specific rules for your firewall (i.e. having your web server’s port 80 only listen to your load balancer’s IP).
You can view your current UFW configuration with the command below.
sudo ufw status verbose
Apache Web Server
If you have installed Apache web server, it might be a good idea to turn off some of the default settings. When Apache runs into a problem it displays an error page that shows a little too much information for our visitors including our OS and web server version. To remove this information, head over to your Apache folder and into your conf-available folder. Locate the file security.conf and look for the following blocks to change your settings.
cat conf-available/security.conf | grep -in "ServerTokens"
cat conf-available/security.conf | grep -in "ServerSignature"
You will want to turn off your ServerSignature and change your ServerTokens value to what is most appropriate for you.
A second setting we may want to change is the directory listing that is enabled by default in the absence of an index.html file. This option can be overridden by a virtual host file so if the configuration below appears to have no effect consider looking into your virtual host configurations.
Lastly, if your website accepts uploads it is a good idea to limit your request size. By default, the request size is unlimited which can cause issues with your site or perhaps be abused in a malicious way.
Head over to your main Apache configuration file, apache2.conf and locate the directory tags near the bottom of the file.
Options -Indexes #Remove directory listing, note the -
Require all granted
LimitRequestBody 512000 #Set request size in bytes
Make sure to restart your Apache web server to save these changes.
sudo systemctl restart apache2
Consider installing Fail2ban to prevent brute force attacks. This will allow you to ban malicious IP addresses for a variable amount of time. The application comes with an SQLITE database so you can preserve long-term bans over server resets.
sudo apt-get install fail2ban
Fail2ban is ready to use as soon as you install it but I would recommend increasing the ban time and double checking the default settings correspond with your setup.
After installing Fail2ban, create a copy of the jail.conf file and name it jail.local. (Fail2ban is configured to read the settings off your .local file). Next, locate the default bantime variable and set it to something higher. This variable will be towards the top under default settings. You can configure different ban times for different Fail2ban “jails”. If you would like to permanently ban these IP’s enter a value of -1.
cp jail.conf jail.local
cat jail.local | grep -in "bantime"
Now, restart Fail2ban to save your changes.
sudo fail2ban-client reload
If you would like to further configure Fail2ban, I recommend this article which provides more background information and instructions.
Remember to routinely monitor your system for malicious activity. This is probably best done through specialized software or probably writing your own scripts!