MODULE
Setup Firewall & Security

Create a new user

The root user has a lot of power on your server. It has the power to read, write, and execute any file on the server. It’s not advisable to use root for day-to-day server tasks. For those tasks, use a user account with normal permissions.

Add a new user:

adduser <your username>

Add the user to the sudo group:

usermod -a -G sudo <your username>

This allows you to perform actions that require root priveledge by simply prepending the word sudo to the command. You may need to type your password to confirm your intentions.

Login with new user:

exit
ssh <your username>@<your server ip>
Create a new user The root user has a lot of power...

Setup SSH Keys

SSH keys allow you to login to your server without a password. For this reason, you’ll want to set this up on your primary computer (definitely not a public or shared computer!). SSH keys are very convenient and don’t make your server any less secure.

If you’ve already generated SSH keys before (maybe for your GitHub account?), then you can skip the next step.

Generate SSH keys

Generate SSH keys with the following command:

(NOTE: Be sure to run this on your local computer — not your server!)

ssh-keygen -t rsa -C "<your email address>"

When prompted, just accept the default locations for the keyfiles. Also, you’ll want to choose a nice, strong password for your key. If you’re on Mac, you can save the password in your keychain so you won’t have to type it in repeatedly.

Now you should have two keyfiles, one public and one private, in the ~/.ssh folder.

 

Setup SSH Keys SSH keys allow you to login to...

Copy the public key to server

Now, copy your public key to the server. This tells the server that it should allow anyone with your private key to access the server. This is why we set a password on the private key earlier.

From your local machine, run:

scp ~/.ssh/id_rsa.pub <your username>@<your server ip>:

On your Linode, run:

mkdir .ssh
mv id_rsa.pub .ssh/authorized_keys
chown -R <your username>:<your username> .ssh
chmod 700 .ssh
chmod 600 .ssh/authorized_keys

 

Copy the public key to server Now, copy your public...

Disable remote root login and change the SSH port

ince all Ubuntu servers have a root user and most servers run SSH on port 22 (the default), criminals often try to guess the root password using automated attacks that try many thousands of passwords in a very short time. This is a common attack that nearly all servers will face.

We can make things substantially more difficult for automated attackers by preventing the root user from logging in over SSH and changing our SSH port to something less obvious. This will prevent the vast majority of automatic attacks.

Disable remote root login and change SSH port:

sudo nano /etc/ssh/sshd_config

Set “Port” to “44444” and “PermitRootLogin” to “no”. Save the file and restart the SSH service:

sudo service ssh restart

In this example, we changed the port to 44444. So, now to connect to the server, we need to run:

ssh <your username>@future.<your domain>.net -p 44444

Update: Someone posted this useful note about choosing an SSH port on Hacker News:

Make sure your SSH port is below 1024 (but still not 22). Reason being if your Linode is ever compromised a bad user may be able to crash sshd and run their own rogue sshd as a non root user since your original port is configured >1024. (More info here)

Disable remote root login and change the SSH port ince...

Add a firewall:

We’ll add an iptables firewall to the server that blocks all incoming and outgoing connections except for ones that we manually approve. This way, only the services we choose can communicate with the internet.

The firewall has no rules yet. Check it out:

sudo iptables -L

Setup firewall rules in a new file:

sudo nano /etc/iptables.firewall.rules

The following firewall rules will allow HTTP (80), HTTPS (443), SSH (44444), ping, and some other ports for testing. All other ports will be blocked.

Paste the following into /etc/iptables.firewall.rules:

*filter

#  Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT

#  Accept all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

#  Allow all outbound traffic - you can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT

#  Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

#  Allow ports for testing
-A INPUT -p tcp --dport 8080:8090 -j ACCEPT

#  Allow ports for MOSH (mobile shell)
-A INPUT -p udp --dport 60000:61000 -j ACCEPT

#  Allow SSH connections
#  The -dport number should be the same port number you set in sshd_config
-A INPUT -p tcp -m state --state NEW --dport 44444 -j ACCEPT

#  Allow ping
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT

#  Log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

#  Reject all other inbound - default deny unless explicitly allowed policy
-A INPUT -j REJECT
-A FORWARD -j REJECT

COMMIT

Activate the firewall rules now:

sudo iptables-restore < /etc/iptables.firewall.rules

Verify that the rules were installed correctly:

sudo iptables -L

Activate the firewall rules on startup:

sudo nano /etc/network/if-pre-up.d/firewall

Paste this into the /etc/network/if-pre-up.d/firewall file:

#!/bin/sh
/sbin/iptables-restore < /etc/iptables.firewall.rules

Set the script permissions:

sudo chmod +x /etc/network/if-pre-up.d/firewall

Get an email anytime a user uses sudo

I like to get an email anytime someone uses sudo. This way, I have a “paper trail” of sorts, in case anything bad happens to my server. I use a Gmail filter to file these away and only look at them occasionally.

Create a new file for the sudo settings:

sudo nano /etc/sudoers.d/my_sudoers

Add this to the file:

Defaults    mail_always
Defaults    mailto="feross@feross.org"

Set permissions on the file:

sudo chmod 0440 /etc/sudoers.d/my_sudoers

This is isn’t mentioned anywhere on the web, as far as I know, but in order for the “mail on sudo use” feature to work, you need to install an MTA server. sendmail is a good choice:

sudo aptitude install sendmail

Now, you should get an email anytime someone uses sudo!

Add a firewall: We’ll add an iptables firewall to the server that...
Next: Install critical components