If you don’t know what a firewall is, let’s start there…
A firewall is basically a digital “wall” that sits on the edge of your network or device. When someone makes a connection over a network or the internet to your server, they connect by the IP address + a Port. Firewalls, on a very basic level, say “allow traffic on this port” or “deny traffic on this port.”
So for web traffic you might connect to our server here: 18.104.22.168 on port 80. There are a lot of services that run on any machine and many of them you don’t want to be accessible from the internet. For example, many distributions of Ubuntu come with a running DNS server that is accessible on port 53. If left alone, this could be a route for people to exploit your machine.
One way to think about it is like your home. Your house has a physical address that someone can punch into a GPS and it will take them to your driveway. However to get into the house they will need to go through a door or a window. Ports are those doors and windows. If a person needs access to the services of your kitchen, then they can come through the kitchen door. If they need access to your garage, you can send them through the garage door. On a computer, different doors (ports) tend to correspond to different services (servers). For example, Apache Web Server commonly uses port 80 for HTTP traffic to host a website, or port 443 to host a secure website with SSL. SMTP servers often use port 25 to receive incoming mail. FTP servers often use port 21, and so forth and so on.
So it is advantageous to block certain ports. I.E. you might allow everyone to visit your kitchen but you don’t want everyone in your bedroom. It is best to actually just block all ports by default and only allow specific ports to incoming traffic.
Finally it is worth noting that firewalls can do all kinds of interesting and complex things with traffic. Most of those functions are well outside of the scope of this article, and outside of the scope of UFW, but we will get there.
If you spend enough time around Ubuntu servers you will come across a couple of terms related to security and particularly firewalls:
UFW = Uncomplicated FireWall
ipTables = the default host-based firewall built into Ubuntu and many other Linux distributions
Host Based Firewall vs. Network or Dedicated Firewalls
There are two basic types of firewalls. Host Based and Network. A Host Based firewall runs directly on a computer or server. It only controls traffic to/from that device. A network based firewalls is usually a dedicated piece of hardware that sits at the logical “edge” of your network and protects all devices behind it on the network. Dedicated firewalls can also be installed inside the network to limit traffic between machines on the same local network but that is beyond the scope of this article. You can think of host based firewalls as protecting an individual home and network firewalls like a fence around a gated community, protecting access to all of the homes inside.
Why do I want to bother with this?
Simply put, if you don’t, bad stuff could, and invariably will, happen. Because people do bad things, and setup automated systems to further speed up their badness. Setup a public web server and look at some of your logs, I guarantee within a very short period of time you will see all kinds of odd activity, most of which are automated systems that are driving around your house and looking for doors (ports) and then they start trying the doorknob on each one and if it is unlocked they will start trying different combinations of common usernames and passwords (if the service is protected at all) to see if any of them will work.
By enabling a firewall and setting up a default deny all rule, you are slamming and locking all doors in everyone’s face all the time. Which might be poor neighborhood etiquette but is exactly what you need to be doing with an internet connected system. You still want to allow everyone access to some services though so you unlock and open up some specific doors (like HTTP for a web server).
What is iptables?
ipTables is the builtin default host-based firewall on many distributions of linux, including Ubuntu. It is very powerful and very good at blocking stuff. It is also extremely configurable and can do some fairly advanced traffic routing, hence it is difficult to configure, especially for the majority of folks that don’t need all the extra bells and whistles.
Enter UFW – Uncomplicated FireWall
UFW is a tool that is also pre-installed on most Ubuntu distributions and many other linux distrubutions which seeks to make ipTables easier to manipulate and use for the masses. And it excels at doing so. With only a handful of easy/short commands you can setup a default deny rule and a few rules allowing access to your server.
Okay, what do I do?
If you are now sold on the idea of getting ipTables up and running with UFW on your Ubuntu server, follow along and I will do my best to take you there, as safely as possible. If you are working with a remote server, you have to be careful, because you don’t want to accidentally close the door that is allowing you to administer to the server.
ipTables is disabled by default. So it is nearly ready to go but is just sitting there doing nothing. Before enabling it though you need to first figure out what doors you need to keep open and then put in the rules to open them. Here are perhaps the four most common items:
Webserver: HTTP — 80/TCP
Secure Webserver: HTTPS — 443/TCP
FTP: FTP — 21/TCP
SFTP and SSH: SSH — 22/TCP
If you were already somewhat security conscious, you might have changed your default SSH/SFTP port to something other than 22. To check which port SSH is running on, take a look at the config file by doing the following:
That should return something in the format of “Port ##”. For example the default is “Port 22”, you might be running on “Port 922” or some other odd number if you changed it.
If you are running a public website, you are almost certainly using 80, and if a secure site (HTTPS) then port 443. Put together a list of any other services and their corresponding ports before proceeding. As long as you get SSH (assuming you administer your server remotely from the command line) open/working you at least won’t lock yourself out.
Next, install UFW. It might already be installed but it can’t hurt to run these commands anyhow.
sudo apt-get install ufw
Next setup a default deny rule that says all traffic will not be allowed by default. Remember, ipTables is currently not running so we are changing the config file but none of this takes effect until we turn ipTables on. Furthermore, remember UFW is just a simple front-end for ipTables, they aren’t two separate things per se’.
Next, open up all the ports you are going to need. Lets start with HTTP and HTTPS and SSH:
sudo ufw allow https
sudo ufw allow ssh
We just opened up 80/tcp, 443/tcp, and 22/tcp respectively.
Open up any non-standard ports, for example if you are running SSH on port 922, that would look like this:
If you also have udp ports to open, you can put “udp” in place of “tcp” in the above command.
Great, you should be all set and ready to turn your firewall on. After do so, I recommend you use Putty or whatever and open up another SSH session to ensure you didn’t accidentally close your SSH port. Your existing SSH session probably won’t be terminated, so it is safe to leave it open and make sure you can open up a second, new connection.
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
Use Putty or whatever you are using for SSH and at this point open up another session and make sure it works. If not, go back to your existing SSH window, and disable the firewall
…and go back to figuring out which port you are running SSH on and adding an allow rule in for that port before turning the firewall back on again. If you somehow did kill your SSH port, and you are having a good day, it shouldn’t have killed your existing connection. If it did, your are kind of stuck as the only way to get access to the box is to plug a keyboard and mouse directly into it and access it locally, which often isn’t an option on remote servers :(.
Backtracking – I added something I didn’t want…
Let’s say you messed something else up, commonly someone might have added an allow rule they want to get rid of, to do that, simply run the following (example, I want to close 922/tcp again):
If you opened a bunch of ports and can’t remember everything you did, you can review the rule list in simplified format with the following:
To Action From
-- ------ ----
[ 1] 6522 ALLOW IN Anywhere
[ 2] 6522/tcp ALLOW IN Anywhere
[ 3] 80 ALLOW IN Anywhere
[ 4] 443 ALLOW IN Anywhere
[ 5] 80/tcp ALLOW IN Anywhere
[ 6] 443/tcp ALLOW IN Anywhere
[ 7] 4545/tcp ALLOW IN Anywhere
This is handy for particularly complex rules as you can just delete by “number”. In the above example, you can see item 7 is port 4545 and I want to delete that rule. So I issue the following:
Proceed with operation (y|n)? y
If you have the luxury if a development server or dev environment, I recommend starting and playing around a bit there. If not, as long as you are careful not to kill SSH you should be able to backtrack and fix anything you break.
Hope this has been helpful!