Working around a giant bug in iptables-restore

Posted

Any Linux users who have customized the /etc/sysconfig/iptables file may have run into a really short-sighted problem: you cannot place comments at the end of a line. All comments apparently must start at column one on any given line. Otherwise, you get this problem when reloading your ruleset (at least on CentOS 5.4):

[root@dal-br-01 sysconfig]# service iptables restart
Flushing firewall rules:                                   [  OK  ]
Setting chains to policy ACCEPT: mangle nat filter         [  OK  ]
Unloading iptables modules:                                [  OK  ]
Applying iptables firewall rules: Bad argument `##'
Error occurred at line: 55
Try `iptables-restore -h' or 'iptables-restore --help' for more information.
                                                           [FAILED]

This may be intentional, but it is so incredibly short-sighted and inconsistent with nearly every other configuration file and script on the system that I’m considering it an actual bug.

Changing the file is not an option for me, as my iptables file is chock-full of lines that look like this:

-A PREROUTING -p tcp -m tcp --dport 22 -j MARK --set-mark 0x11         ## SSHD
-A PREROUTING -p udp -m udp --dport 53 -j MARK --set-mark 0x11         ## DNS
-A PREROUTING -p tcp -m tcp --dport 5060:5061 -j MARK --set-mark 0x11  ## SIP / SIP-TLS

And so it continues for several hundred lines, and ultimately with a ton of very obscure, non-standard port numbers.With so many rules, most of which are for non-standard ports, comments are crucial. Placing them on their own line makes for an unintuitive mess, i.e., “does that comment apply to the rule above it or below it? And WTF is this one?” and so forth.

To work around it, I’ve made a few very small changes. Please note that this will likely jeopardize the functionality of iptables-save! On the other hand, saving ad-hoc rules that were created after the initial load is not relevant nor important to me since I’ve chosen to use a custom ruleset file.

My workaround

Copy /etc/sysconfig/iptables to /etc/sysconfig/iptables.input. Make sure the permissions are the same (0600) as the original. Then you’ll modify /etc/rc.d/init.d/iptables in two places, starting with the variable list at the top. Add a new variable at the bottom of that variables block, and set it to the path to the aforementioned iptables.input file thusly:

    IPTABLES_DATA_INPUT=/etc/sysconfig/${IPTABLES}.input

Modify the start() function in the /etc/rc.d/init.d/iptables script to read the contents of the new iptables.input file, strip all comments out, and pipe it to the existing iptables file. This should be performed directly before the line that executes $IPTABLES-restore:

    cat $IPTABLES_DATA_INPUT | sed -e 's/ #.*$//' > $IPTABLES_DATA
    $IPTABLES-restore $OPT $IPTABLES_DATA

Afterwards, reloading rules with service iptables restart no longer causes any sort of implosion. Opening /etc/sysconfig/iptables after doing so shows that it has no inline comments. Going forward, all changes must be made in the iptables.input file, since the iptables file now gets overwritten at each start/restart.

So there you have it. There might be a more preferred way to do this, but this was the best method for my environment. Hopefully this helps others in the same boat.

Comments

Darren Rush commented on Wednesday 20 January 2010, 6:42pm CST:

I concur that this is a bug, albeit a non-critical one. Self-documenting scripts - especially for things as complex as firewall configurations should be a requirement.

Khalid commented on Wednesday 1 September 2010, 12:03am CDT:

I am running redhat linux and I ran through same issue here, but then found this as part of the iptables rule:

-m comment --comment "type in your comment"

man page for iptables puts it this way:
#man iptables
........
........
........
comment
Allows you to add comments (up to 256 characters) to any rule.

--comment comment

Example:
iptables -A INPUT -s 192.168.0.0/16 -m comment --comment "A privatized IP block"
..........
..........
..........

not sure if that is convenient to anyone who used to put a simple in-line comment though, but it works and i started to like it, because you don't need to open the iptables file to see the comments, typing the command "services iptables status" will list the rules along with their comments.

no sure if CentOS 5.4 have similar feature, otherwise your trick is very helpful.

Khalid