Skip to main content

Sysadmin tools: How to use iptables

The iptables command is a powerful interface for your local Linux firewall. It provides thousands of network traffic management options through a simple syntax.
Image
How to use iptables

Photo by Belle Co from Pexels

If you want to fully manage network traffic to and from your Linux system, the iptables command is what you need to learn. In this article, I provide general advice on creating iptables entries and several generic examples to get you started. The unfortunate fact about iptables is that there are options don't make intuitive sense. For those, you'll just have to commit them to memory or use this article as an iptables cheat sheet.

I need to mention that iptables rules go into effect immediately after entering them. There's no daemon to restart or configuration to reload. For this reason, you have to be extremely careful or you will lock yourself out of the system you're using. Always issue rules that allow you into the system before you enter those that don't.

Don't run both firewalld and iptables at the same time. Disable firewalld to run iptables.

Show, don't tell

There are many ways to look at your iptables rules list, but I generally only use one, which covers the two things I want to see: the rules and the line numbers. For example:

$ sudo iptables -L --line-numbers

Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination         
1    ACCEPT     tcp  --  192.168.1.0/24       anywhere             tcp dpt:ssh
2    DROP       all  --  anywhere             anywhere            

Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination  

The line numbers are important when you attempt to delete a rule. If you don't care about the line numbers, then a simple iptables -L will work for you:

$ sudo iptables -L 

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     tcp  --  192.168.1.0/24       anywhere             tcp dpt:ssh
DROP       all  --  anywhere             anywhere            

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination       

As you can see from the above listing, there are three sections to the iptables command's output: INPUT, FORWARD, and OUTPUT. FORWARD rules are between interfaces on the system.

Rules of order

If you decide that the order of your rules is awkward, not organized, or just plain wrong, then you change their order by exporting the rules with:

$ sudo iptables-save > ~/iptables.txt

Make your edits in your favorite editor—which is, of course, vi—and then import the new version back into iptables:

$ sudo iptables-restore < ~/iptables.txt

Because iptables rules are read from top to bottom, this factor can become an issue if conflicting rules are read in the wrong order.

INPUT vs. OUTPUT

When you create a new rule, it will typically be in the form of adding an INPUT or an OUTPUT. INPUT rules govern traffic coming into the protected system, and OUTPUT rules govern traffic leaving the system. I'm not sure why INPUT and OUTPUT were used rather than the more descriptive INCOMING and OUTGOING or INBOUND and OUTBOUND, but like so many other things in life, no one asked my opinion prior to implementation. 

So, the general form of an INPUT rule is: 

iptables -I INPUT <other options>

And, OUTPUT rules are:

iptables -I OUTPUT <other options>

Adding entries

There are two ways that I add iptables rules. One is with append (-A), but I only use that one time per system. The second is insert (-I), which is the way I add all other rules to a system. My explanation is that append puts the rule at the bottom of the list, and there's only one rule I want at the very bottom: the classic DENY ALL. It's simple to add.

$ sudo iptables -A INPUT -j DROP

This entry appends the DENY ALL rule to the bottom of whatever list of rules already exists. On a new system, there won't be any, but it's a good practice to start with. Remember, iptables rules are read from the top down, so you always want the DENY ALL rule to be the last one on the list. If this rule falls anywhere else in the list, nothing below it will process. All other rules should be inserted with the (-I) option, like this:

$ sudo iptables -I INPUT -s 192.168.1.0/24 -p tcp --dport 22 -j ACCEPT

The insert option adds the rule to the top of the list, and so the new rule will not be affected by DENY ALL. The particular rule above allows every system on the 192.168.1.0/24 network to connect to the protected system via SSH. Don't forget to add this rule, because the DROP rule locks you completely out of your system by denying all TCP traffic to it. I'm not going to tell you who, but I know someone who recently locked himself out of the system he was using for an article covering iptables by forgetting the SSH rule. Fortunately, the system in question is a virtual machine and the console is easy to access. Imagine what would happen if someone submitted the DENY ALL rule without the SSH rule on a remotely hosted system and the console wasn't so easy to access.

Note: You should add the SSH rule first and then add the DENY ALL rule.

Deleting entries

Deleting iptables entries is where the --line-numbers option becomes essential. From a previous listing, you can see that my so-called DENY ALL rule is the second rule in the list (as it should be). To delete that rule, find the line number of the rule you wish to delete. For example:

$ sudo iptables -L --line-numbers

Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination         
1    ACCEPT     tcp  --  192.168.1.0/24       anywhere             tcp dpt:ssh
2    DROP       all  --  anywhere             anywhere            

Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination  

Issue the following command to remove the second rule:

$ sudo iptables -D INPUT 2

You must specify the list (INPUT, OUTPUT, or FORWARD) and the line number of the rule in that list. There is no response from the delete command.

Saving entries

You'll probably want your configured iptables to survive reboots, so be sure to issue the following command to save your valuable entries, otherwise, you'll have to import your rules after every reboot or script the import.

$ sudo iptables-save > /etc/sysconfig/iptables

Standard entries

For a truly locked-down system, you need a rule that allows you to SSH from a specific host or network, and a DENY ALL rule for both INPUT and OUTPUT. All other rules would be inserted as needed to allow specific traffic into and out of the system.

Other than those minimal rules, there are no other "standard" rules that apply to every system. If you have a web server, you'd have to write an INPUT rule to allow ports 80 and 443. If it's internet-facing, you'd have to open it up to all hosts. If the web server is internal, then you could only allow web access from your internal corporate networks.

Wrapping up

This article is a short introduction to one of the most necessary and useful sysadmin tools: iptables. Iptables is easy to use and requires almost no maintenance. It requires no daemon restarts and it is available for all Linux systems. One of the first things you should do when bringing a new Linux system online is to set up these standard rules. You don't need any security issues springing up in the earliest days of deployment (or ever, really) and iptables is a quick security fix if there ever was one.

Want more on networking topics? Check out the Linux networking cheat sheet.

Topics:   Networking  
Author’s photo

Ken Hess

Ken has used Red Hat Linux since 1996 and has written ebooks, whitepapers, actual books, thousands of exam review questions, and hundreds of articles on open source and other topics. Ken also has 20+ years of experience as an enterprise sysadmin with Unix, Linux, Windows, and Virtualization. More about me

Try Red Hat Enterprise Linux

Download it at no charge from the Red Hat Developer program.