3

Say there are several iptables scripts (run at boot time), all of which run something like iptables -A ... to add rules. I'm thinking this could be improved, turning all those shell scripts into text files generated by iptables-save.

But I must be doing something wrong, trying to read all those rulesets. The script run at boot time would loop through those files and read them using iptables-restore. Of course with -n or --noflush. This works for some rules (stored in the default chains) but not for most of my rules which are in other chains. Below is an example of 2 rulesets that flush each other (reading set a, check; reading set b, check but set a is gone).

How would you read a bunch of iptables rulesets?

Example:

$ cat fake1-a.rules 
*nat
:PREROUTING ACCEPT [7:997]
:INPUT ACCEPT [7:997]
:OUTPUT ACCEPT [28:1810]
:POSTROUTING ACCEPT [28:1810]
COMMIT
*mangle
:PREROUTING ACCEPT [344:84621]
:INPUT ACCEPT [344:84621]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [296:37971]
:POSTROUTING ACCEPT [296:37971]
COMMIT
*filter
:INPUT ACCEPT [102:26513]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [89:10767]
:TESTCHAIN - [0:0]
-A TESTCHAIN -p tcp -m tcp --dport 12345 -j DROP
COMMIT
$ cat fake1-b.rules 
*nat
:PREROUTING ACCEPT [7:997]
:INPUT ACCEPT [7:997]
:OUTPUT ACCEPT [28:1810]
:POSTROUTING ACCEPT [28:1810]
COMMIT
*mangle
:PREROUTING ACCEPT [344:84621]
:INPUT ACCEPT [344:84621]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [296:37971]
:POSTROUTING ACCEPT [296:37971]
COMMIT
*filter
:INPUT ACCEPT [102:26513]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [89:10767]
:TESTCHAIN - [0:0]
-A TESTCHAIN -p tcp -m tcp --dport 54321 -j DROP
COMMIT
# cat fake1-a.rules | iptables-restore --noflush
# iptables -nL | grep DROP
DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:12345
# cat fake1-b.rules | iptables-restore --noflush
# iptables -nL | grep DROP
DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:54321
  • I would do it in a single file ... in fact that is what I am doing, but of course your use case is different. Does this yield any different outcome if you chain the files and leave out the COMMIT from them and then add the commit to the end yourself? E.g. in a subshell (cat file1 file2 file2; echo "COMMIT")|iptables-restore -n ... also not sure you need to declare the chain creation stanzas once again, perhaps the CHAIN gets re-created? – 0xC0000022L Jun 5 '14 at 17:09
  • @0xC0000022L iptables-restore: line 43 failed (that's the last COMMIT). Without the echo, only the last ruleset is applied. – basic6 Jun 6 '14 at 7:42
3

The --noflush option for iptables-restore doesn't work for user-defined chains, such as TESTCHAIN, only builtin chains. Your best bet is to consolidate all of the TESTCHAIN rules into a single file and import that ruleset using iptables-restore. You could find all the rules with something along the lines of:

egrep -r  "\sTESTCHAIN\s" firewall_rules_directory/*
  • Oh, interesting fact. Thanks. This is not even mentioned in the man page. – 0xC0000022L Jun 6 '14 at 11:14
  • @0xC0000022L yea, it's funny what they don't tell you – Creek Jun 6 '14 at 11:17
  • So --noflush is basically broken, thanks for the confirmation. The regex would have to be more complex though, because it makes a difference what table the rules live in. – basic6 Jun 6 '14 at 11:55
  • 1
    Just as an update to this, I'm using iptables v1.4.21 and the "iptables-restore -n" functionality now works correctly, including user-defined chains. – Jak Sep 18 '14 at 11:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.