First Steps in Server Security

Tutorials – Server Security

Article from Issue 199/2017

Fear not the barbarians of cyberspace, and follow our guide to shoring up your digital defenses.

So, you just got your first server. Maybe it's a VPS you're renting, or maybe it's running off your home Internet connection. The main point is that it's connected directly to a public IP address, so you can access it from anywhere. That means you can share things with other people or access your data on the go, but it also means that you've entered the domain of hackers, distributed denial-of-service (DDoS) attackers, and other nefarious folk who roam the Internet looking for weak links in security. You need to batten down the virtual hatches and bar the digital door: You're now responsible for securing your own domain. Let's look at the first things you need to do to ensure you stay safe (see "Picking a Distro" for more information).

Picking a Distro

Generally, when picking a distro for a server, you want to consider the stability and longevity of the distro, particularly with regards to for how long you get security updates (Figure 1). If you want to constantly run the latest and greatest software, then you need to pick a distro that supports this, but also be aware that this means that you will have to do more work to update the server as core software versions become unsupported.

Figure 1: All good server distros have security announcements as an RSS feed or email list (ideally both). You should keep an eye on this so you know when to update.

On the other hand, if you just want basic software (web server, SQL database server, etc.), then you may wish to plump for a distro that's stable and supported for a long time. It may not always have the latest software, but keeping up to date should mostly be a simple case of grabbing the latest security fixes from the package repository and not having to reconfigure software or reinstall the distro. There's no right answer to this question, but our approach is to choose a stable, long-supported distro (such as CentOS) unless there's a good reason not to (Figure 2).

Figure 2: Be careful what you put on your server, because Google's always watching. The Google Hacking Database [1] is a list of searches that find improperly secured servers.

If you're renting your server, then the chances are that you're first interaction with it is via Secure Shell (SSH). This protocol allows you to create an encrypted shell session to your server and generally use it as though it were a local server. The power that comes with SSH is the reason it's the most common target for attackers. If you have a server on a public IP address, people will attempt to log in via SSH, and usually this starts happening almost instantly.

When it comes to server security, SSH is the place to start. The first rule is never, not even temporarily, use a default password to log in with. We're looking particularly at people using Raspberry Pis, but it goes with anything. If you have to login via password, it should be a randomly generated long string of characters, but we won't delve too far into password rules, because we'll move swiftly on to the second rule of SSH: Disable password login as soon as possible.

Sometimes, when first setting up a server, you have to login via password as it's the only option the server host gives you. However, this should only ever be a temporary solution, because passwords just aren't secure enough to guard this most powerful entry point to your server. As soon as you can, you should shift to disabling passwords and only log in with keys.

When you go to a secure website, your web browser authenticates the website using a certificate and then sets up an encrypted channel to communicate over. That way, you can be sure that you're really communicating with and that no one can listen in on the conversation. All that took place without any passwords being used; instead, cryptographic keys were used to validate the identity of the servers. You can use the exact same cryptographic techniques to log into your new server.

There are a few advantages to using keys rather than passwords to authenticate:

  • Multiple different keys can access the same account so that you can let other people access the machine without giving away your secrets (and likewise you can remove their access without having to change passwords).
  • You can use the same keys on multiple machines without having to let other people know the passwords to the machines.
  • You can be sure that no one breaks your security by setting up a weak password.
  • Keys are easier because you don't have to remember (or even type) a password.

Setting up keys is easy. First, you need to generate a public/private key pair. The public key is what the server knows and uses to validate your identity. Any machine with the private key can authenticate against the public key and log in to the server, so guard the private key. The command to generate a key pair is:

ssh-keygen -t rsa

You'll get a few options: You can just accept the defaults for where to store the key (in your ~/.ssh folder), and if you want, you can add a password to protect the key even if the file itself is compromised.

You then need to copy the public key onto the remote server. This can be as simple as copying the public key from ~.ssh/ (or wherever you told the previous command to save the files) to the ~/.ssh/authorized_keys file of the user you want to log in as on the remote host. It's best not to overwrite the authorized_keys file but to copy the data from the public key to the end of the authorized keys file. Once this is done, you should be able to ssh in without using a password.

Once you've verified that you can log in without a password, you can then block all passworded SSH logins. This is done by editing /etc/ssh/sshd_config and ensuring that the following lines are in there (without a preceding #):

ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM no

Once you've put these in, restart your SSH server with:

Service sshd restart

Now you've blocked SSH passwords, which is one of the biggest security vulnerabilities you can have.

Ports of Entry

You computer allows connections from the outside world via numbered ports. You bind software on your machine to a port number; then anything trying to connect to that port number on that machine gets forwarded to the appropriate bit of software. In this context, ports are virtual and don't exist in the real world: They have nothing to do with the physical connections on the back of your server.

For example, we've already looked at SSH. By default, the SSH software on your server listens on port 22, and your SSH client automatically tries to connect to port 22 (see the "Move SSH Port" box for more information). The two link up and everything works. Understanding what is listening on which ports is key to understanding the security of your machine. Every bit of software listening on a port is a thing that an attacker could have access to.

Move SSH Port

Since SSH is the most popular target for attackers, some people advocate moving it from the default port (22) onto another port. (Typically one numbered above 1000). The advantage of this is that anyone scanning for open SSH ports (which is typically how attackers find machines to target) will simply assume that you don't have SSH running and move along. Anyone actually targeting your machine will probably still find the SSH port.

Another way of adding a bit more security is using Fail2ban. This is a service that watches your log files looking for IP addresses that repeatedly try to log in with invalid credentials and blocks them.

In our opinion, neither using a different SSH port nor using Fail2ban is necessary if you're using SSH keys rather than passwords, and if you're not, neither provides a sufficient level of security. So, for personal servers, we're not convinced that they're needed. However, if you're protecting a high-value server, you may wish to consider additional security measures. In that case, you should be looking for more specific security advice and not a basic guide to securing your first server.

You can see all the network connections on your machine with the following command (Figure 3):

netstat -plnt
Figure 3: Netstat is one of the most important pieces of security software, because it allows you to keep track of what software is on what port.

You'll need to run this command as sudo to get the full output. The two key columns here are Local Address and PID/Program Name. The Local Address tells you which IP/port combination the software is listening on and the PID/Program name tells you what it is.

The Local Address column contains two bits of information: the IP address and the port number. The IP address could be localhost (, it could be all IP addresses (, or it could be a specific IP address assigned to the machine. The software is only available to machines that can reach that IP address, so anything listening on can only be reached by from the server itself so isn't a significant security consideration. On the other hand, anything listening on is accessible to everyone.

At this point, you need to decide what it is you want to be accessible. More services mean more functionality, but also more things for attackers to target. There's no right answer here, but it really comes down to deciding how much you want to run on your server versus how much time you have to keep your machine secure.

Before we look too closely at this, we need to look at another piece of the network security puzzle: iptables. When a packet of data arrives at your machine, the kernel evaluates it against a set of rules before deciding whether to let it in. These rules are usually created by a bit of software called iptables. You can see the currently running iptables rules with the command:

iptables -nL

If you've just set up the machine, then this list could be empty, or it could have some default rules created by the OS. Iptables gives you quite fine-grained control over what external IP addresses should be able to access which ports on your machine.

There are whole books written on iptables, and we can only cover the basics here. By default, you have three lists of rules: one for input, one for output, and one for forwarding. For a basic server setup, you can ignore the output and forwarding lists and only deal with the rule on packets coming into the server. Iptables is configured using the file /etc/sysconfig/iptables. But it can be easier to make changes to the running iptables interface and then save those changes to disk.

There are two ways of adding rules to Iptables, via insert and append. Insert places a rule at a particular point in the list, whereas append adds it to the end.

You'll want to define rules to set up, that is, which IP addresses can access what. Exactly what goes here depends on what you want to be possible. If you want port 80 to be available to every IP address, you could add this rule by inserting it at the first position in the list with:

iptables -I INPUT 1 --dport 80 -j ACCEPT

If you want a port to be available to a specific IP address (e.g., one assigned to another server you run), in this case, you could add a rule such as:

iptables -I INPUT 1 -s --dport 80 -j ACCEPT

If you omit the --dport 80, then that IP address will have access to all the ports on the machine.

If you want a port to be available to a specific range of IP addresses (e.g., just the local network on to, you could use a rule such as this:

iptables -I INPUT 1 -m iprange --src-range -j ACCEPT

Once you've defined all the rules you want, you need to end with the following rule, which tells iptables to drop all the packets that don't match one of these rules. This time, we'll use the append option so that this rule is at the end of the list. Because rules are evaluated sequentially, anything after this rule will never be reached.

iptables -A INPUT  -j DROP

If you're connecting to the server via SSH, don't forget to make sure the SSH port (typically 22) is opened in the iptables config before adding the above rule. All of these rules will be applied as you type them in, but unless you use the save command:

Service iptables save

they will be lost when you restart the machine.

Proxy Moxy

So far, we've locked down our machine by SSH and by the ports that are open. However, much of what we want to install on our servers these days comes with a web interface. Sometimes this web interface is the whole of the app, other times it's just an admin panel. Not all of the web interfaces have good security built in, so let's look at how to put a layer of protection in front of a web service with a reverse proxy.

There are a few ways of doing this, but the easiest way is with NGINX (pronounced engine-X). Essentially, this just listens on a port (typically 80) and then forwards any web requests onto other software (which you'll have to configure to listen on other ports). You can configure it to perform authentication before passing any request on, or to apply HTTPS encryption to the connection between the web browser and the server. So, before you can deploy NGINX, you have to consider what ports you want to use for what.

Typically, you should use port 80 for NGINX itself, but other software you're using might already be configured to use this port, so first use netstat -plnt to see what (if anything) is on port 80, and reconfigure it to use a different port (this should be straightforward and highlighted in the documentation or the config file). Once you've done this, install NGINX through your package manager. You'll also need a tool for generating password files (htpasswd). This is usually in the Apache tools package, which is called apache2-utils in Debian and Ubuntu or httpd-tools in Red Hat, CentOS, or Scientific Linux.

htpasswd creates a password file that just contains one or more username/password hash pairs. If a user enters a password that matches the hash, they are allowed to view the site; if not, they're denied. To configure this with NGINX, first create the username/password pair with:

htpasswd -c /etc/nginx/.htpasswd <username>

You then need to configure NGINX to reverse proxy the other web page using this authentication. Essentially, what you're doing here is linking one port with another. In the file /etc/nginx/nginx.conf, you should see various sections that define different parts of the way NGINX works. There are many ways to fine-tune this server if you need to handle huge numbers of requests, but we don't need that. You just need to add a new server block to the configuration file with something like what is shown in Listing 1 (which links port 80 to port 8080).

Listing 1

Add a New Server Block


Once you've saved the file, restart NGINX with:

Service nginx restart

And you should now have a password protected version of the software running on port 8080 on port 80. Don't forget to block port 8080 in iptables to everything other than localhost; otherwise, this hasn't added any security.

Security doesn't have to be hard, but you do have to pay attention to it. By just keeping an eye on what software is listening on which ports, you should stay out of trouble online. Always remember to keep your software up to date, especially any software that runs on a public port. Do this and you can benefit from all the advantages of an Internet-facing server without having security problems.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Single-Packet Port Knocking

    If you are looking for an extra layer of remote access security, try single-packet port knocking.

  • FAQ

    Nftables promises to be the future of Linux firewalls. Meet iptables' replacement.

  • ufw

    Canonical's ufw lets you configure your firewall without the hassle of the iptables tool, while reducing the risk of misconfiguration and simplifying maintenance.

  • Firewall Logfile Analyzers

    Netfilter firewalls create highly detailed logfiles that nobody really wants to inspectmanually. Logfile analysis tools like IPtables Log Analyzer,Wallfire Wflogs,and FWlogwatch help administrators keep track of developments and filter for importantmessages.

  • KTools: KMyFirewall

    Linux has a fantastic selection of firewalls for securing stand-alone computers or whole networks. Although you can use IPTables to set up a firewall, the configuration is often the most difficult step. KMyFirewall offers a powerful, user-friendly, GUI-based approach.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More