Setting up our server correctly

When I first got my hands on an actual server, I thought nobody would even try to attack it as I had nothing of interest for anybody else than me. I was immensely wrong and if you feel the same, you need to understand Internet is a place where nasty bots constantly try to attack servers in order to own them. If you don’t properly secure your machine, it’s a matter of minutes before you’ll get hacked, and your server will either or both:

  • be use to spam other people
  • participate in large attack that will read on the news as: “the xxx company was hacked by xxx”

First things first

On your newly created machine, you will need to do a few things, namely:

  1. Upgrade everything that came pre-install in your server:

    sudo apt-get update
    sudo apt-get upgrade
    
  2. If you’re using the root user directly (to know which user you are using you can type whoami in the command line), you should create yourself another user

    sudo adduser username
    sudo su username
    passwd
    

    We do that because always using the root user is a very bad practice reserved for cow boys with suicidal tendencies.

  3. Properly setup your SSH connection:

    • by blocking botnets from trying to breach your server using brute force attacks:
    sudo apt-get install fail2ban
    

    Fail2ban is a great tool that block weird behaviors such as somebody attempting to connect to your server after 10 password attempts. I don’t know any good reasons not to use it.

    • disable root access to your machine:
    sudo sed -i 's/^PermitRootLogin/\#PermitRootLogin/' /etc/ssh/sshd_config
    sudo service ssh restart
    

    I don’t know any good reasons for someone to connect directly with the root account. If you need root, connect as a normal user, then become root by typing:

    su root
    
    • Change the default port SSH is using (22) to something else like 2222:
    sudo sed -i 's/Port 22/Port 2222/' /etc/ssh/sshd_config
    sudo service ssh restart
    

    This is not a must have, simply a nice to have. Personally I don’t even do it all the times.

    • Securely connect to your server without always typing your password. From your desktop:
    ssh-keygen -t rsa
    cat ~/.ssh/id_rsa.pub | ssh username@domain.com "mkdir -p ~/.ssh && cat >>  ~/.ssh/authorized_keys"
    

From now on you have different choices:

  1. you stay with this basic setup and jump to the firewall configuration section bellow
  2. you want to increase security even more. You have different options available, you can even add them one on top of the other:
    1. Disable login with password. You can think of private keys as super password as they are random and much longer than any password you’re probably using. Disabling login with password and only authorise login with private key would make your server more secure. Personally, I don’t disable password on my machines as I don’t want to create backups for such a sensitive information and afraid to lose the keys but if you want to do it:

      sed -i 's/\#*PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
      sudo service ssh restart
      
    2. setup a VPN with openVPN. It will make things more secure but it adds an extra step when you want to connect your server: first connect to the VPN, then connect to your SSH server. I’ll show you a bit later on this tutorial how to setup a VPN. This solution has the same problem than the solution above plus if your VPN service is down, well, good luck.

Configure your firewall

Ubuntu comes with iptables, the classic firewall most of the people in the linux community are using. If your infrastructure consist of one machine, iptables will likely be your only protection. That’s why it’s important to get this right. If you have many machines part of the same network, then you probably want to use a physical firewall, create a DMZ, setup honeypots and do a bunch of funny things we won’t cover in this post.

Tips: Some nice tooling was build around iptables, ufw is one of them. In practice, you probably don’t want to use it as I’ve seen some software (eg: docker) who edit their own iptables rules and those rules won’t be seen by ufw.

Warning: The risk is to get locked out of your server with no way to get back in. To be honest, every time I work on a machine’s firewall I don’t have physical access, I am sweating. Getting locked out already happened to me multiple time. The good news is you won’t have to go through such a pain as I’ve include a safeguard to make sure this will be easy for either you and me in the future.

We’ll first create our script and store it under /tmp/firewall.sh. Copy and paste this large command:

cat > /tmp/firewall.sh <<EOF
#!/bin/bash

# Flush current rules
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -X

# block everything by default
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# allow SSH: replace your SSH port if needed
# in
iptables -A INPUT -i eth0 -p tcp --dport 2222 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 2222 -m state --state ESTABLISHED -j ACCEPT
# out
iptables -A OUTPUT -o eth0 -p tcp --dport 2222 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 2222 -m state --state ESTABLISHED -j ACCEPT


# allow HTTP
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT

# allow HTTPS
iptables -A INPUT -i eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT


######
# SAFEGUARD IN CASE WE DID A MISTAKE
# The idea is to have a safeguard that will kick after 2 minutes if you get locked out without a way to login back to your server. The safeguard will simply reset all the firewall rules you currently have in place so that you should be able to connect again.
# If everything went alright, then you can C-c to quit the script before the safeguard activates itself
sleep 120
echo "- PROTECTION: RESET OUR FIREWALL CONFIG"
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
EOF

Read this script and make sure you understand what he does, making relevant change that apply to your specific use case. If you have been following this tutorial from the very first episode without making special customisation, you should be good to go:

sudo bash /tmp/firewall.sh
# wait for a few seconds
# then Ctrl-c to quit the script. If you can still type things, you're all set.
# If you screen is frozen, it means you got locked out of your own server! But don't panic and wait 2 minutes. When you get your access back edit the script by making relevant change to your configuration and start again.

What now?

You might be tempted to install many things on your server right away. Keep in mind that the more tools you have the larger is your attack surface. Be very conservative about what software you want to install on your server.

Now that it is said, the next episode will focus on the installation of applications