1

I have a set of scripts I designed for network monitoring, control and so on. One thing I do in these scripts is create an iptables chain like iptables -N mychain. I then insert rules into the main tables as appropriate to get packets to my custom chain for whatever purpose I want them to have there.

My question is: I have a script that does a "Refresh" - in other words, it removes all rules and starts over. It is useful in case of any odd anomalies that crop up. People often still manually manage iptables even if there's something managing part of it. (This is why I wanted all of my work to be done in a separate table.)

If I want to clear my chain, that's easy: iptables -F mychain. But what I don't know how to do is to remove any rule that I may have created that references that chain back in the built-in chains (INPUT, OUTPUT, etc.)

Let's assume there was a bug in my app, or a user was fiddling and ended up messing with the tables, and it somehow added the rule to the INPUT chain twice. Now packets will go through the chain twice - being counted twice, being routed twice, whatever.

The obvious solution to this is to go through the main chains and remove any rule whose jump target is my custom chain. But I don't know how to do this.

Here's an example of a worst-case situation we could setup:

iptables -N TEST
iptables -A INPUT -j TEST
iptables -I INPUT 1 -p tcp --dport 1234 -j TEST
iptables -I INPUT 1 -p tcp --dport 1234 -j TEST # again, for doubling error
iptables -I INPUT -p icmp -j TEST

Let's assume that an unscrupulous or uninformed admin created the three bottommost rules.

So now, I could issue iptables -D INPUT -j TEST and the rule I created would go away. However, those other rules would not be deleted since the parameters when using -D have to match. So even if I remove my own rule diligently, the packets could still end up there more than once for different reasons.

Flushing the main chains isn't necessarily appropriate. Again, using iptables at the command line is common (I do it myself all the time) so just blindly clearing every rule could clear out something someone added for a good reason, even if it's a temporary rule.

The obvious solution is to somehow remove any rule whose destination is the TEST chain and remove those rules. However I haven't seen any commands in the iptables man page that could accomplish this.

The closest thing I could see that may be of any user is iptables -S. I could use iptables -S and create a parser to interpret the output, but this is a bit of extra work. I was just wondering if there's a more correct way to delete rules in some sort of wildcard way. Again, remove any rule whose jump target is whichever chain I want.

A similar situation can occur if I have a chain that I want to get rid of, but it has a reference somewhere else. I would want to be able to figure out where that reference is, and most likely, delete it also.

Is this possible? Or am I going to end up having to write a parser to interpret the iptables -S output?

3 Answers 3

5

This should be fairly simple. Use iptables-save to write the current rule-set out to a file or stdout, remove anything with -j YOURCHAIN and load the result back with iptables-restore

This is tempting to do as a pipe

iptables-save | grep -v -- '-j YOURCHAIN' | iptables-restore

However, I'm not sure if running save and restore concurrently would work well. It would be safer to separate the save from the restore. There will be a small critical region where an intervening update to the ruleset would be lost.

2
  • 1
    Oooh interesting - just checked on a test system and it does work as a pipeline.
    – user9517
    May 9, 2014 at 11:01
  • Elegant, and useful to know! +1 from me.
    – MadHatter
    May 9, 2014 at 14:54
2

I don't think there is a trivial way to solve this other than perhaps reloading the whole configuration.

You should perhaps give some thought to adding a drop Policy to your chain that way at least if you are diligent it will cause issues for the less so and perhaps provoke some discussion.

From a technical standpoint if you're going to have to parse the output of various commands, you may find --line-num helpful but remember to delete in reverse order (high to low) so that the index doesn't change every time.

0
0

If you need advanced manipulations on iptables, an excellent python library http://ldx.github.io/python-iptables/ may be worth taking a look. It provides a programmatic interface (both read and modify) for netfilter. Interoperability with iptables is achieved via using the iptables C libraries (libiptc, libxtables, and the iptables extensions), not calling the iptables binary and parsing its output.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .