Server security is an important part of every website, especially when you are storing sensitive customer information. I recently started investigating ways of hardening our hosting environment and enabling the firewall was the first logical step.
In general, my hosting environments run on Ubuntu. By default there are a couple of options available right out of the box. Ubuntu ships with
ufw. My choice was to go with UFW for it's simplicity and quick learning curve.
What is it?
UFW, or Uncomplicated Firewall is the default firewall configuration tool for Ubuntu. It was created to simplify the configuration of
iptables and provides a user friendly way to create an IPv4 or IPv6 host-based firewall. By default it's disabled.
Even though UFW normally ships with Ubuntu, let's make sure it's installed. To do this, lets run:
You should see something like:
If you don't get any output, that means we need to install it. You can easily do this with
aptitude by running:
sudo apt-get install ufw
sudo aptitude install ufw
Before we turn UFW on, we should add a couple of rules to help protect our server. Let's start with a couple of defaults to get us going and then add some more specific rules based on how we will be using our server. UFW's defaults are to deny all incoming requests and allow all outgoing. This means anyone trying to connect to the server will not be allowed, but the internal applications can still reach out. Let's make sure these rules are active by running the following:
sudo ufw default deny incoming sudo ufw default allow outgoing
Note: for a little added security, you could also deny all outgoing connections and only open up the ports you know you'll need for your application.
Allowing what we need
There are a couple of different ways to allow connections to our server. UFW provides a simple and complex way of setting up rules. If you would like to enable a specific service you could just run:
sudo ufw allow ssh
This is essentially just shorthand for:
sudo ufw allow 22/tcp
As you can see, this would open up port 22 on the TCP protocol. If your SSH server is running on a different port, we could instead enable connections to that with:
sudo ufw allow <port number>/tcp
You could also enable an entire port range, like 2345 through 3456 by issuing the following command:
sudo ufw allow 2345:3456/tcp
or on a different protocol, like UDP:
sudo ufw allow 2345:3456/udp
IP Specific Rules
To enhance our security rules further, it's a good idea to only allow certain services access based on their IP address. Specifically, I like to only allow SSH connections from the places I work, like my home or office. To add a rule with an IP address, use this command:
sudo ufw allow from 126.96.36.199
This would allow IP address 188.8.131.52 to connect to any port on our server. Let's tighten that up by telling UFW which port and protocol we want to allow access:
sudo ufw allow from 184.108.40.206 to any port 22 proto tcp
Now IP address 220.127.116.11 would be allowed to connect to port 22 specifically.
Up until now, we have been only adding rules to allow access to our server. But it is simple enough to deny access as well. All we have to do is swap in deny in place of allow. Say you wanted to ban a specific IP address after having been attacked. You could add a rule to ban that IP on all ports with:
sudo ufw deny from 18.104.22.168
If you wanted to ban that IP on a specific port:
sudo ufw deny from 22.214.171.124 to any port 80
Oops, you made a mistake about that IP address and no longer want to ban them. We can remove the rule by simply adding delete to the front of it:
sudo ufw delete deny from 126.96.36.199 to any port 80
When your rules start to get long and complex though, it might be easier to remove them based on a specific id. Two steps are involved to remove rules in this way. First we have to get a list of our current rules (with numbers) using the following command:
sudo ufw status numbered
Note: for this to work, you have to have UFW already enabled (continue reading to find out how to enable it). If it isn't, you will just be presented with the prompt again.
This will give us output similar to the following:
Status: active To Action From -- ------ ---- [ 1] 22/tcp ALLOW IN Anywhere [ 2] 2345:3456/tcp ALLOW IN Anywhere [ 3] 2345:3456/udp ALLOW IN Anywhere [ 4] Anywhere ALLOW IN 188.8.131.52 [ 5] 22/tcp ALLOW IN 184.108.40.206 [ 6] Anywhere DENY IN 220.127.116.11 [ 7] 80 DENY IN 18.104.22.168 [ 8] 22/tcp (v6) ALLOW IN Anywhere (v6) [ 9] 2345:3456/tcp (v6) ALLOW IN Anywhere (v6)  2345:3456/udp (v6) ALLOW IN Anywhere (v6)
Now, to delete one of the above rules, just type in:
sudo ufw delete <number>
Let's start it up
Remember, by default UFW is disabled, so after we have all our rules setup, it's time to turn it on. Be careful though, if you have closed up connections to everything and haven't added a rule to allow access to port 22 (which you are most likely connected to the server on via SSH) you could get disconnected (although in my experience, the server won't actually close your connection, it will just refuse it the next time you try to connect). With that in mind, let's start it up!
sudo ufw enable
If all went well, you should see nothing but the prompt again. Now that we are up and running, you can check the current status with:
sudo ufw status
or, if you'd like more details:
sudo ufw status verbose
In the off chance you want to turn the firewall off, you could issue the following:
sudo ufw disable
Feel like you might have messed something up? You can always roll back to the defaults with:
sudo ufw reset
You should now have a better understanding of how to setup a firewall quickly and easily using UFW, making your server much more secure than before. I'm only just getting started learning about server security myself, but so far I've found the following setup to be a good basic starting point if you're just setting up a simple website:
To Action From -- ------ ---- 80/tcp ALLOW IN Anywhere 443/tcp ALLOW IN Anywhere 22/tcp ALLOW IN YOUR_IP_ADDRESS 80/tcp (v6) ALLOW IN Anywhere (v6) 443/tcp (v6) ALLOW IN Anywhere (v6)
If you'd like to take your SSH access security a step further, checkout my blog post about
knockd called Enhanced Security with Knock.