Verified and Tested 2/8/15
In this article, let’s discuss some basic steps you can take to troubleshoot problems you may be having with getting your iptables rules to do what you might want them to do.
Server running CentOS 6.x (or any distribution of Linux)
iptables installed and configured (for basic configuration, see Basic IPTables File Configuration)
Basic IPTables Troubleshooting
One helpful addition to making your iptables rules is to set up logging. Logging uses a special target in the iptables toolbox that pipes select output to your operating system’s log files (dmesg or systemd).
On the command line:
sudo iptables -A INPUT -j LOG --log-prefix DROPPED-INGRESS-
Or, in your /etc/sysconfig/iptables file:
Let’s unpack the syntax:
* ‘-A INPUT‘ appends this rule to the end of the INPUT chain. Remember, rule order is important, so if you place this rule after a rule that drops or rejects traffic, it will never be used. More on this when we discuss the –log-prefix below.
* ‘-j LOG‘ jumps to the LOG target. This target is a special one called a “non-terminating” target. Unlike the targets most commonly used (such as ACCEPT, DROP, or REJECT), this one doesn’t stop iptables from parsing further rules. So, when this rule is invoked, it logs the packet (and may perform additional options, if specified in the options following it), and then continues evaluating rules in the same chain until it hits a matching rule with a terminating target or until it gets past the last rule in the chain and follows the default target.
* ‘–log-prefix DROPPED-INGRESS-‘ adds the string “DROPPED-INGRESS-” to each log entry. This addition can be helpful to filter for or to search for in a long log file. The “–log-prefix” option can take a string of up to 256 characters. Since this rule is the final rule in this INPUT chain, this will log any packet that doesn’t match any of the above rules and gets handled with the default policy (in this case, DROP).
If you want to see which of your rules are being invoked (and, perhaps equally importantly, which aren’t), you can take a look at your packet and traffic counters. Use the ‘-v‘ option to the ‘iptables‘ command to show counters (and some additional information, as well):
sudo iptables -vL INPUT
sudo iptables -nvL INPUT
The output from either of these commands will display on the left side columns for packet and byte counters for each rule. The ‘-L‘ option indicates that we want the rules listed (note that this particular option is capitalized). The ‘-n‘ indicates that we don’t want to resolve IPs to their hostnames (in longer lists this reverse name resolution can cause unnecessary server overhead and make your troubleshooting annoyingly slow). You may use each flag separately (-n -v -L, e.g.) or together, as above, but be careful: the ‘L‘ must be last since it looks for further input in the form of the name of the chain to list (if nothing is specified, the default is to list all chains in the filter table).
Note here that I’ve got one packet hitting my allow-all ssh rule and several hitting the first allow RELATED/ESTABLISHED rule (this would correspond to my ssh session into this server). I can also see that my rules for allowing ssh traffic from the 192.168.50.0/24 range has no hits. So, for example, if I had someone saying they couldn’t access this server from that range, I could see that their attempts weren’t even making it to this server.
It’s quite possible your packet byte counters will tick up high enough that the values will be abbreviated with a ‘K’, ‘M’, or even ‘G’ at the end, corresponding to 1000, 1,000,000, or 1,000,000,000, respectively. If you’d still like to see unabbreviated counts, include the ‘-x‘ flag:
sudo iptables -nvxL INPUT
If you’d prefer not to have to deal with large count numbers, you could reset (zero) your counts with the ‘-Z‘ command (again, note that this flag is capitalized). You can zero the counts for all chains, a specific chain, or for a specific line in a chain. Respectively:
sudo iptables -Z
sudo iptables -Z INPUT
sudo iptables -Z INPUT 1
The final example would only zero the counters for line number 1 in the INPUT chain.
The counters would also be reset any time you reload iptables (whether from a server reboot or performing sudo service iptables reload). These are not the most ideal ways to accomplish this task, though.
You may also want to get a more real-time examination of your iptables counters. Here’s where the ‘watch‘ command comes in handy. ‘Watch‘ allows us to repeat the same commands and watch the output every so often (the default is every 2 seconds).
sudo watch iptables -nvL INPUT
While ‘watch‘ itself doesn’t require sudo access, if the command you’ll be watching does, you could prepend ‘sudo‘ to the ‘watch‘ command to have root privilege for the command you’d like to watch. Also, if you would like to pipe watched output through something like ‘grep‘, you’ll want to put the entire command string in single-quotes:
sudo watch 'iptables -nvL INPUT | grep tcp'
To exit out of ‘watch‘, press <Ctrl-C>.