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?