Configuring iptables on the latest version of Ubuntu is a piece of cake as long as you understand the basics of iptables. By default, every installation of Ubuntu comes with iptables enabled and configured to pass/allow all traffic. Learning how to configure and work with iptables should be priority #1 for every person just starting out with linux, so let’s take a look at some of the basic concepts that will help you become more proficient with iptables.
One of the most basic commands that beginners learn is the iptables -L command and for a good reason: it’s handy! Fire up your fresh Ubuntu installation and list the current iptables rules.
sudo iptables -L
Which will return your current “list” of rules in the iptables. Assuming this is a fresh installation of Ubuntu, you won’t have any rules setup yet – here’s what an “allow all” iptables -L looks like :
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Now that you know how to display your current rules in iptables, let’s take a look at some of the other options that you can use with iptables. I keep a printout of these options near my screen for reference as I’ve found them to be the most useful for getting around in iptables and getting stuff done.
-m conntrack : Allow filter rules to match based on connection state. Permits the use of the –ctstate option.
-A : Appends a rule to a rule chain. There are three possible chains in iptables; OUTPUT, INPUT, and FORWARD. INPUT is incoming traffic, OUTPUT is outgoing traffic, and FORWARD is used to direct traffic to a particular IP, which is based on the port used on the header.
-L : Displays current iptables rules.
-p : The protocol used by the connection.
–dport : The target port or ports for this iptables rule. You can also implement a range of ports by using start:end, example : 60000:61000 would allow all ports between 6000 and 61000.
–ctstate : Set a list of “states” for the rule to “listen” on. There are four possible “states” :
RELATED – New connection, but is related to another current connection that is permitted.
ESTABLISHED – Exactly what it sounds like – current connections.
INVALID – A state that doesn’t match any of the other 3 states – usually incomplete packet data.
NEW – The connection has not been observed yet.
-j : Jumps to the desired “target.” There are four possible targets by default:
ACCEPT – Accepts the packet and quits processing rules in the chain.
REJECT – Rejects the packet, notifies the source of the packet, then quits processing rules in the chain.
DROP – Similar to REJECT, but it quietly ignores the packet without any notification, then quits processing.
LOG – Logs the packet but continues to process rules in the chain.
–log-prefix : Displays text before the actual log message itself, useful for filtering your logs.
–log-level : Sets the “log level” for syslog. A good way to visualize log level is to picture a large circle containing 7 other circles, with each smaller circle containing more and more detail. Since this is Linux, there are of course “7 bits” of logging levels, with the default starting at 7 and ending at 0.
-s –source : IP/MASK source information.
-o –out-interface : output name PLUS interface name ( + = wildcard )
-d –destination : IP/MASK destination information.
-i : Designates a particular network interface to “peer” the rule chain to.
-I : “Inserts” a rule, you have to use this with an order as well. Example : -I OUTPUT 9 would insert the rule into the OUTPUT chain and make it the 9th rule on the list.
-v : The “verbose” switch which simply displays more information.
1.) Allow Incoming Traffic On Certain Ports
So, now that you know some of the more common switches used to manipulate the iptables and a little bit about what each one does, let’s jump into some basic configuration. The goal here is to start out simple by blocking all traffic except on the default port of SSH. Before we can block all traffic however, we want to open up SSH so we don’t kick outselves out of the server. Run the following :
sudo iptables -A INPUT -p tcp –dport ssh -j ACCEPT
Reading the rule chain from left, here’s a breakdown of what we just achieved.
1.) Elevated our account first to run iptables.
2.) Appended this rule to the input chain for incoming traffic.
3.) Verified that the incoming protocol is TCP/IP.
4.) If the traffic is TCP/IP, does the packet contain target information for the SSH port?
5.) If all of those rules are satisfied, then the rule chain will accept the traffic.
Check your rules and you’ll see output similar to below :
sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all – anywhere anywhere state RELATED,ESTABLISHED
ACCEPT tcp – anywhere anywhere tcp dpt:ssh
2.) How To Block Traffic
Now that we’ve configured iptables to accept TCP/IP traffic on port 22, we can lock down the rest of our firewall without fear of locking ourselves out. One interesting to thing to note here is that unlike other operating systems or firewalls that you may have worked with before, ACCEPT always overrides DROP or REJECT rules – which is the opposite of popular practice. iptables is also interesting in that it reads rules from top to bottom, meaning rules are enforced in the order they are inputted. Let’s take a look at how to block all traffic.
sudo iptables -A INPUT -j DROP
Check the rules now, you’ll notice something interesting.
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all – anywhere anywhere state RELATED,ESTABLISHED
ACCEPT tcp – anywhere anywhere tcp dpt:ssh
DROP all – anywhere anywhere
Two things are going on here, firstly the rules are being enforced from top to bottom, and regardless of order the ACCEPT rule is going to override the “top to bottom” enforcement. Notice also that the DROP rule was placed at the end of the iptables configuration. Also because we didn’t get too fancy and specify a protocol or a particular network interface, iptables is going to take that as acknowledgement that we want to block traffic on all protocols and interfaces. Unfortunately we also blocked our loopback ( 127.0.0.1 / 1::1 ) interface because we didn’t specify an interface. We can either duplicate these rules across all interfaces on our system, or add an exception for the loop back interface only, which is the easiest option in this case. Don’t skip this step as a lot of programs need the loop back interface to work properly ( Apache/NGINX/MySQL/etc ) just to name a few.
sudo iptables -I INPUT 1 -i lo -j ACCEPT
Now check your iptables by running sudo iptables -L again :
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all – anywhere anywhere
ACCEPT all – anywhere anywhere state RELATED,ESTABLISHED
ACCEPT tcp – anywhere anywhere tcp dpt:ssh
DROP all – anywhere anywhere
And that concludes our basic tutorial and explanation of iptables on Ubuntu 12.10 – make sure to save the changes with :
iptables-save
















Great post pal, but what you think of using Dome9 for Ubuntu security, Is it relaible? I always hated configuring iptables. Dome9 seems good for me.
I haven’t used Dome9 yet, but from looking at their offerings I might be giving it a try soon :)