Working with iptables

Iptables, more properly referred to as "iptables/netfilter" because of the two modules that are involved -- the userspace module "iptables" and the kernel module "netfilter" -- is the firewall that you'll find running by default on most Linux systems today. Offspring of the earlier ipchains, iptables generally blocks network traffic that tries to reach services on your system. You can pretty much leave it as is unless or until you need to provide a service to other systems or, in other words, until your system needs to become a server.

As the name implies, iptables is organized as a set of tables. By default and in most cases, only one table -- the one called "filter" -- is actually configured. If you haven't made any changes, the filter table will likely be set up to accept established connections, icmp requests and requests sent to the loopback interface (i.e., those generated on the system itself). It will reject everything else. This provides the "default deny" rule that gives firewalls their claim to fame -- denying everything that you don't explicitly allow.

Since iptables is a kernel function, you're not going to see processes running so no ps command is going to tell you anything about whether or how it is working. You can, however, easily check the status of iptables with the command systemctl status iptables.service or maybe just the service iptables status command -- depending on your Linux distribution.

systemctl status iptables.service
iptables.service - IPv4 firewall with iptables
          Loaded: loaded (/usr/lib/systemd/system/iptables.service; enabled)
          Active: active (exited) since Sun, 25 Nov 2012 19:50:53 -0500; 2min 5s ago
         Process: 565 ExecStart=/usr/libexec/iptables.init start (code=exited, status=0/SUCCESS)
          CGroup: name=systemd:/system/iptables.service

You can also query iptables with the command iptables -L that will list the active rules.

# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere
REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

If iptables isn't running when you run the iptables -L command, you'll see what looks like empty tables.

# iptables -L
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

You can stop and restart iptables with commands like these:

# systemctl stop iptables.service
# systemctl start iptables.service
# systemctl restart iptables.service
# service iptables restart

You can add rules to the iptables config file /etc/sysconfig/iptables by editing the file itself (generally not recommended) or you can add them with an iptables command. For example, you could use a command like this to enable ssh connections:

# iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

Notice that the destination port (--dport) in this example is 22, the port for ssh.

You can also use the desktop tool system-config-firewall, if you have it available, to select the services you want to support from a list. Just understand that your previous manual changes will be wiped out when you use this tool, so save them first if you'll need to reapply them.

If you want to go with iptables commands, you can issue a series of commands to configure your firewall rules. You could even put your rules into a script and run it, but once you get your rules into the /etc/sysconfig/iptables file, iptables will start up with those rules whenever your system boots -- if it's set up to start on boot. If it isn't, run this command to make it so:

# systemctl enable iptables.service

The rules you could use if you needed to configure your iptables filter table (i.e., the primary table) from scratch might include commands like these:

  • iptables -F to flush the existing rules.
  • iptables -P INPUT DROP to set the default policy on the INPUT chain to DROP. This sets the default deny for incoming packets.
  • iptables -P FORWARD DROP sets the default on FORWARD chain to drop, though it is unlikely to encounter any packets if your system isn't acting as a router.
  • iptables -A INPUT -i lo -j ACCEPT all incoming packets for the loopback interface will be accepted
  • iptables -A INPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT accepts packets that are part of established connections

After you run iptables commands, you can use the iptables-save command to save them in your /etc/sysconfig/iptables config file.

# iptables-save

On a new system, your iptables rules are likely going to look something like this:

-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited

The *filter line marks the start of the filter table. The following three lines establish the three chains -- INPUT, FORWARD and OUTPUT.

The first three -A lines do what was just described above. The first is a rule that accepts established connections. Read this as "add (-A) to the INPUT chain a rule that is going to match on connection state and, if a connection state is established, will then accept the connection". The second accepts ICMP requests. The third accepts connections generated on the system itself (i.e., from the loopback interface).

The fourth and fifth -A lines reject everything else.

The COMMIT line ends the definition of the filter table and commits the rules just established to the kernel, readying them for use.

The arguments in the rules all have specific meanings as described here:

<b>-i</b> interface
<b>-m</b> match
<b>-p</b> protocol
<b>-j</b> jump to policy (ACCEPT, DROP, etc.)
<b>--reject-with</b> identifies rejection type
<b>--state state</b> identifies state

Iptables isn't as difficult to understand or update as it might first appear, but you should still be careful as you compose your rules so as not to lock yourself out of the system you're trying to manage. Compose your rules slowly and carefully and you should be OK.

Join the Network World communities on Facebook and LinkedIn to comment on topics that are top of mind.
Must read: 10 new UI features coming to Windows 10