How to define iptables rule to add all transport to a given interface to nfqueue

  • Running on Ubuntu. I have machine 1 < - > machine 2 < - > machine 3. I dont know machine 1 or machine 3 ip. It can be any ip. machine 1 send packet to machine 3 and machine 3 send packet to machine 1.

    Machine 2 is used as a bridge:

    ifconfig eth0 0.0.0.0
    ifconfig eth2 0.0.0.0
    brctl addbr br0
    brctl addif br0 eth0 eth2
    ifconfig br0 up
    

    i want to have an iptable rule in machine 2 that will add all traffic that come to eth0 to nfqueue1 and all traffic that come to eth2 to nefqueue2.

    Now i have the following rule:

    iptables -A FORWARD -p tcp -j NFQUEUE --queue-num 0
    

    which is not good to me because i want to distinguish between traffic that come from machine 3 to traffic that come from machine 1, so i want to have 2 rule.

    Add -i eth0 to the rule doesn’t help.

    Answers(39)

    • I was only looking at your current /etc/sysconfig/iptables file and the command you ran at the end. I see the --set --name SSH2 in the earlier section now. The command at the bottom has -I SSH_CHECK 3 which may be its problem depending on what rules are already in place. What I would recommend is finding the smallest/simplest set of rules that still cause the error and update your question with that set of rules if still required. – Ladadadada May 5 '12 at 13:27

      • Gah! What error does it generate? How can you not think that is important information to convey? – womble May 5 '12 at 6:37

      • No . All trafic allowed but i need to distinguish between traffic from machine 1 to machine 3 – Avihai Marchiano Aug 12 '12 at 12:32

      • 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.

      • because the incoming interface is considered to be the bridge interface ( br0 ), not the bridge port. – Olipro Aug 12 '12 at 20:18

      • Ah, that wasn't clear. – larsks Aug 12 '12 at 13:06

      • But iptables-restore /etc/sysconfig/iptables fails after replacing anti-bruteforce rules in /etc/sysconfig/iptables with second fragment of code (see question body) . It contains -A SSH_CHECK -m recent --set --name SSH2 line before -A SSH_CHECK -m recent --update --seconds 86400 --hitcount 100 --rttl --name SSH2 -j SSH_ATTACKED . – technocrat May 5 '12 at 8:13

      • 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

        • 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 '12 at 10:11

        • The ip of the machines is not known its group of machines. – Avihai Marchiano Aug 12 '12 at 13:05

        • Just curious... how many rules is "many" ? – Ladadadada Apr 2 '12 at 17:21

        • It just doesn't say anything that could help. iptables-restore /etc/sysconfig/iptables says "iptables-restore: line ## failed" where ## is number of last line in /etc/sysconfig/iptables iptables -I SSH_CHECK 3 -m recent --update --seconds 86400 --hitcount 100 --rttl --name SSH2 -j SSH_ATTACKED says iptables: Invalid argument. Run `dmesg' for more information. – technocrat May 5 '12 at 7:17

        • Right, and I'm suggesting that you use the source ip address to distinguish machine 1 from machine 3 (I'm not suggesting blocking traffic). You would need two rules in your FORWARD chain instead of 1... – larsks Aug 12 '12 at 12:54

        • Can you just add a -s specifier? – larsks Aug 12 '12 at 12:20

        • 10x i will test it tommorow. Why -i interfacename dosnt work ? – Avihai Marchiano Aug 12 '12 at 16:44

          • How can you know that? You don't know enough to solve the problem yourself, and yet you're absolutely , 100% certain that the error message could not possibly be of any help to anyone else who might have an interest in helping you solve your problem? – womble May 5 '12 at 7:19

          • Ah, that wasn't clear. – larsks Aug 12 '12 at 13:06

            • Yes. You are right. I often overestimate my abilities. I added info about error messagees to question body. – technocrat May 5 '12 at 7:26

                • 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
                  
                • 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
                  
                  • Can you just add a -s specifier? – larsks Aug 12 '12 at 12:20

                    • The ip of the machines is not known its group of machines. – Avihai Marchiano Aug 12 '12 at 13:05

                    • 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.

                      • No . All trafic allowed but i need to distinguish between traffic from machine 1 to machine 3 – Avihai Marchiano Aug 12 '12 at 12:32

                      • because the incoming interface is considered to be the bridge interface ( br0 ), not the bridge port. – Olipro Aug 12 '12 at 20:18

                        • 10x i will test it tommorow. Why -i interfacename dosnt work ? – Avihai Marchiano Aug 12 '12 at 16:44

                        • Try this: iptables-save | grep -v i_XXXXX_i | iptables-restore – Steven Monday Apr 2 '12 at 19:01

                        • iptables -A FORWARD -m physdev --physdev-in eth0 .... work!!!! great!!! – Avihai Marchiano Aug 13 '12 at 7:15

                        • Default max number of --hitcount is set to 20

                          You can verify this: cat /sys/module/xt_recent/parameters/ip_pkt_list_tot

                          You need to reload module with extra parameters: modprobe xt_recent ip_pkt_list_tot=500

                          List of available parameters: modinfo xt_recent

                        • 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 '12 at 17:23

                          • @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 '14 at 0:56

                          • 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
                              
                            • iptables -A FORWARD -m physdev --physdev-in eth0 .... work!!!! great!!! – Avihai Marchiano Aug 13 '12 at 7:15

                            • Right, and I'm suggesting that you use the source ip address to distinguish machine 1 from machine 3 (I'm not suggesting blocking traffic). You would need two rules in your FORWARD chain instead of 1... – larsks Aug 12 '12 at 12:54

                              • I've not seen iptables barf like that before when trying to flush. – Tom O'Connor Apr 2 '12 at 17:18

                              • You're missing a line with --set --name SSH2 somewhere before the one that's listed in the error message.

                                The --rttl option requres there to be a

                                --set option for the same list. You have one for the SSH list but not for the SSH2 list.

                                The error message could be a little clearer about this.

                              • since you're operating a bridge, you need to use -m physdev

                                for usage, run iptables -m physdev -h - if you compile your own kernel, you may need to add this module.

                                • since you're operating a bridge, you need to use -m physdev

                                  for usage, run iptables -m physdev -h - if you compile your own kernel, you may need to add this module.

                                    • @timy StevenMonday's comment will single-pass remove any references to the chain. Perhaps not ideal, but darned close. – Jeff Ferland Apr 3 '12 at 13:20