50

I have a chain appended with many rules like:

> :i_XXXXX_i - [0:0]
> -A INPUT -s 282.202.203.83/32 -j i_XXXXX_i 
> -A INPUT -s 222.202.62.253/32 -j i_XXXXX_i 
> -A INPUT -s 222.202.60.62/32 -j i_XXXXX_i 
> -A INPUT -s 224.93.27.235/32 -j i_XXXXX_i 
> -A OUTPUT -d 282.202.203.83/32 -j i_XXXXX_i 
> -A OUTPUT -d 222.202.62.253/32 -j i_XXXXX_i 
> -A OUTPUT -d 222.202.60.62/32 -j i_XXXXX_i 
> -A OUTPUT -d 224.93.27.235/32 -j i_XXXXX_i

when I try to delete this chain with:

iptables -X XXXX

but got error like (tried iptables -F XXXXX before):

iptables: Too many links.

Is there a easy way to delete the chain by once command?

6
  • 2
    I've not seen iptables barf like that before when trying to flush. Apr 2, 2012 at 17:18
  • Just curious... how many rules is "many" ?
    – Ladadadada
    Apr 2, 2012 at 17:21
  • 1
    2 many is many :) if I try to delete the rules first, it will like typing many times: iptables -D OUTPUT -d XXX/32 -j i_XXXXX_i
    – timy
    Apr 2, 2012 at 17:23
  • 5
    Try this: iptables-save | grep -v i_XXXXX_i | iptables-restore Apr 2, 2012 at 19:01
  • @StevenMonday why not write as answer, this is the most useful one (alternative do this via file and edit file). Only thing it does not remove is complete tables ("raw" anyway)
    – nhed
    Mar 7, 2014 at 0:56

8 Answers 8

53

You can't delete chains when rules with '-j CHAINTODELETE' are referencing them. Figure out what is referencing your chain (the link), and remove that. Also, flush then kill.

-F, --flush [chain]

Flush the selected chain (all the chains in the table if none is given). This is equivalent to deleting all the rules one by one.

-X, --delete-chain [chain]

Delete the optional user-defined chain specified. There must be no references to the chain. If there are, you must delete or replace the referring rules before the chain can be deleted. The chain must be empty, i.e. not contain any rules. If no argument is given, it will attempt to delete every non-builtin chain in the table.

3
  • I just want to find a way to delete the chain(has many '-j CHAINTODELETE' ref rules) directly, but from your answer, it seems impossible :(
    – timy
    Apr 3, 2012 at 10:11
  • 1
    @timy StevenMonday's comment will single-pass remove any references to the chain. Perhaps not ideal, but darned close. Apr 3, 2012 at 13:20
  • Works like a charm. iptables -nvL|grep "^Chain.*0 references"|awk '{print $2}'|while read LINE; do iptables -X $LINE; done
    – LinuxGuru
    Feb 11, 2020 at 15:58
20

This is potentially off-topic, but it's what I did after I found this post! For some use cases the iptables -D option might be useful. Since it allows you to clear out referring rules added programmatically with -A (if you know precisely how you added them).

E.g

    iptables -N MYCHAIN
    iptables -A INPUT -i interface -j MYCHAIN
    iptables -A MYCHAIN -j ACCEPT

can be reversed with

   iptables -D INPUT -i interface -j MYCHAIN
   iptables --flush MYCHAIN
   iptables -X MYCHAIN
15

You need two steps, but this does it in one command.

Create a file, and place this in it.

# Empty the entire filter table
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

Save the file as "clear-all-rules". Now, do this command:

iptables-restore < clear-all-rules

Now you can clear it anytime with just one command.

1
  • 1
    +1 This is actually the fastest way to start with a clean fw config.
    – dr_
    Apr 5, 2016 at 10:46
12

Here's an alternate plan. It involves three commands, not one, but with luck, it should work.

Dump your iptables ruleset to a file:

iptables-save > /tmp/iptables.txt

Remove ALL uses of (and references to) the offending chain:

sed -i '/i_XXXXX_i/d' /tmp/iptables.txt

Then reload the ruleset:

iptables-restore < /tmp/iptables.txt && rm /tmp/iptables.txt
5

In the iptables man file there is an option -S

S, --list-rules [chain] Print all rules in the selected chain. If no chain is selected, all chains are printed like iptables-save. Like every other iptables command, it applies to the specified table (filter is the default).

By using iptables -S | grep <CHAINNAMEHERE>. For examples:

root@root:~# iptables -S | grep TRAFFICLOG

-N TRAFFICLOG

-A FORWARD -i eth0 -j TRAFFICLOG

you can then see which rules are blocking the deletion of the chain from the table. Go through each rule (except the iptables -N <CHAINNAMEHERE> and delete the rule by using the -D option

-D, --delete chain rulenum Delete one or more rules from the selected chain. There are two versions of this command: the rule can be specified as a number in the chain (starting at 1 for the first rule) or a rule to match.

For example iptables -D FORWARD -i eth0 -j TRAFFICLOG. After you have deleted each rule for your chain flush the chain with the -F option, iptables -F <CHAINNAMEHERE>.

-F, --flush [chain] Flush the selected chain (all the chains in the table if none is given). This is equivalent to deleting all the rules one by one.

Then delete your chain with the -X option, iptables -X <CHAINNAMEHERE>

-X, --delete-chain [chain] Delete the optional user-defined chain specified. There must be no references to the chain. If there are, you must delete or replace the referring rules before the chain can be deleted. The chain must be empty, i.e. not contain any rules. If no argument is given, it will attempt to delete every non-builtin chain in the table.

Iptables is a complicated tool set so an ideal tutorial is needed. You can try one out at www.iptables.info

1
  • This helped a lot because flush cleans the chain itself but not the references to it in the other chains.
    – Hardoman
    Jan 20, 2021 at 11:27
0

Something along these lines will get all of them in a single line without taking iptables down in any way.

for chain in `iptables -L |grep i_XXXXX_i|awk '{ print $2 }'`; do iptables -X $chain; done
0

This will spit out chains and delete them

for i in $(iptables -S | awk '{print $2}' | uniq ); do iptables -F $i && iptables -Z $i && iptables -X $i  ; done
0

I have found that you can remove the rules and chain by editing the rules file in /etc/iptables/rules.v4. If you delete the unwanted chain in this file and then reload iptables, you should no longer see the chain when doing a iptables -L.

1
  • This file exists only on certain Linux distributions, and then only on certain versions of certain Linux distributions. May 4, 2018 at 18:36

You must log in to answer this question.

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