Linux Server – Configure IP tables Firewall

In this post I will be showing how to configure an IP tables firewall on a Ubuntu Linux server. At first glance configuring iptables seems cryptic and complex but once you analyze the commands and understand what they are doing it becomes much easier to work with.

There are a few things you will need to understand out of the gate, 1 your rules will take affect once you hit enter so if you make a drop rule and cut your arm off because your allow rules are not correct you will know right away, and 2 iptables rules are non persistent by default so if you do cut your arm off you can reboot the server and your faulty rule will be purged away. Now you may be asking yourself “will I need to re enter my firewall rules every time I reboot?” and the answer is no, as you will see below there is a command with iptables that will allow us to save the rules and make them persistent. And the last thing you may want to understand is that in iptables it refers to a firewall rule set as a ‘chain’, when reading the rules in the chain it reads them from top to bottom, and when a rule in the chain is matched it uses that rule and stops processing the rest of the rules.


Typicaly IP tables comes installed by default, if it is not installed on your machine you can install it via apt-get using the folowing command


Our first step prior to doing any configuration will be to check our existing rules, if you have not made any configuration changes it should be at default and accepting everything


The first rule we should have in our firewall is to allow any related and established traffic a return route, for example if our firewall allows port 80 out from the server to serf the web, the return traffic that will be coming back needs to be allowed otherwise the web page served up from the outside server will be blocked. To do this we need to allow established and related traffic, a single command will encompass any return traffic that is related or established in a chain so you do not need add a rule for each kind of return traffic. Below will allow established and related traffic that is needed for connections that were made from the server to the outside world.

Notice I added it to the input firewall chain as the traffic will be coming from the outside to our server

Since this is a server, there will more than likely be connections originating from the outside to your server requesting something so you will also need to allow established and related traffic out from your server to the outside otherwise your server will not be able to fulfill any requests. Below is the command to do that, you will notice it is the exact same command as used above the only thing that is changing is the chain we are applying the rule on.

Again notice that I added it to the output firewall chain because the traffic will be coming from the server to the outside when serving up a webpage or other service.

At this point if we dropped all packets we would maintain our SSH connection as our connection is already established, but would not be able to connect another SSH connection or have any new network connectivity from the machine to the outside because we have not allowed any ports open either in or out so therefore there can not be any established or related traffic. Because of the risky nature of adding a drop rule at this stage we will not add any drop rules yet.


We will first want to add the rules we want to allow because we are allowing traffic and not blocking any so there is no risk of cutting our arm off to the box.

Analyzing this command:

sudo iptables: Gives us root privileges using iptables

-A INPUT: appends the rule to the end of the list of the INPUT chain

-p tcp: Tells iptables that the protocol(-p) that needs to be matched is tcp

–dport 22: Tells iptables that the destination port number should match 22

-j ACCEPT: -j is the option telling iptables what to do if the packet being processed matches all of the previous requirements and in this case it ACCEPTS the packet.

With the above information we know that any traffic that originates form the outside to our machine that is TCP port 22 will be allowed.

At this point we know how to understand the syntax of adding a rule into an iptables firewall lets add all of the ports we wish to allow in our firewall from the outside which will be our INPUT firewall, for this example my server will be a web server so I wish to have TCP ports 80 and 443 to be able to serve web pages and also TCP port 22 for SSH administration (for security purposes I recommend using a port other than 22 but that is beyond the scope of this tutorial). Below is the commands to allow those ports into your server from the outside.

Our rules that we need from the outside to the inside are now staged. Now to add the rules to handle traffic from the server to the outside, we already added a rule to allow established and related traffic so we don’t need to worry about our web page or SSH session getting blocked when trying to fulfill a clients request, we will just need to add the ports we want our server to be able to communicate out to the world for. For me the only services I need is HTTP, HTTPS, and DNS mainly for update purposes so I will be adding rules for TCP ports 80, 443, and 53, but DNS (port 53) uses TCP and UDP so I will need to account for that in my firewall rules. Below is an example of the rules that will be needed, notice that I needed to make 2 rules for DNS, one for TCP and UDP


Now just a quick check to make sure that our rules took as we expect


We can see our input and output chains have all the rules that we put in. At this point it will be a good idea to save our rules that we entered in our firewall so they stay persistent through a reboot and we dont have to re enter all of them. Below is the command to save your iptables rules.


Now we are ready to change our input and output chain to drop by default so that all other ports that are not explicitly accepted are dropped this can be thought of as turning the firewall on. Below are the commands to change the input and output chains default policy.

At this point if your session did not freeze up things are looking good, do not disconnect your current SSH session, open a new window and start a new one, if you are allowed to establish a connection you know your SSH rule is working, if you have a web page currently published on your server attempt to navigate to it and make note of the port its using (HTTP or HTTPS) and if your web server is configured for both HTTP and HTTPS you should be able to access your web page from both. Lastly to test attempt to telnet to a port you do not have in your allowed list like port 21 for FTP and it should not be able to establish.

If something went wrong you can power cycle the machine and it will lose your last 2 changes that changed your default policies to drop allowing you to remotely access the machine again, but will keep all the changes prior to your save. You will then be able to analyze your rules and validate that the ports you need are allowed, save your changes, set the default chain policies to drop once more and attempt your tests again.

As long as your tests went according to plan you have successfully configured an IPtables firewall on your server congratulations! You should be save to save your rules one more time so the your default policy on your input and output chains stays set to drop.



Be the first to comment

Leave a Reply

Your email address will not be published.