5

I have a script that adds iptable PREROUTING rules. They all have the same to address. When I run this:

 iptables --list PREROUTING -t nat

I see output like this:

 DNAT       tcp  --  anywhere             165.193.122.18      tcp dpt:https to:192.168.2.1:443
 DNAT       tcp  --  anywhere             63.135.91.11        tcp dpt:https to:192.168.2.1:443
 DNAT       tcp  --  anywhere             63.135.90.224       tcp dpt:https to:192.168.2.1:443

It seems like I should be able to drop all these rules by writing a command like this...

"drop all PREROUTING rules that go to 192.168.2.1:443"

So, in looking at the options for itables it looks like I need to use the -D option. But I don't know the rulenum to give it. :-(

So, I probably need to query for existing rules, grep to limit it to destination 192.168.2.1:443, and run -D passing the rulenum for each one. I have no idea how to do that. Any help would be appreciated.

Thanks!

EV

3

Something like this:

#!/bin/bash

for line_num in $(sudo iptables --line-numbers --list PREROUTING -t nat | awk '$7=="to:192.168.2.1:443" {print $1}')
do
  # You can't just delete lines here because the line numbers get reordered
  # after deletion, which would mean after the first one you're deleting the
  # wrong line. Instead put them in a reverse ordered list.
  LINES="$line_num $LINES"
done

# Delete the lines, last to first.
for line in $LINES
do
  sudo iptables -t nat -D PREROUTING $line
done

unset LINES

You may need to adjust the field number in awk if it's not matching.

  • This worked great. I had to change the field to $9. After that it worked exactly as I hoped. thx! – user548971 Jun 22 '12 at 19:16
1

You may be able to simplify the line reversal with tac:

#!/bin/bash

for line in $(sudo iptables --line-numbers --list PREROUTING -t nat | awk '$7=="to:192.168.2.1:443" {print $1}' | tac)
do
  # You can't just delete lines here because the line numbers get reordered
  # after deletion, which would mean after the first one you're deleting the
  # wrong line. Instead put them in a reverse ordered list.
  sudo iptables -t nat -D PREROUTING $line
done
1

You could use the following one-liner:

sudo iptables -S | grep $pattern | cut -d " " -f 2- | xargs -L1 sudo iptables -D

Where $pattern is your desired pattern.

I recommend you first echo the results of this command though, to avoid drama

  • In case it helps somebody, my Ubuntu 16.04 didn't have the -S option in iptables, and had a slightly different output, so I ended up with this: iptables -L -vt nat --line-number | grep $pattern | cut -d " " -f 0-3 | xargs -L1 iptables -t nat -D PREROUTING – pgr Feb 13 '17 at 12:17
0

Use --line-numbers to display the rule number, grep and awk it and you have it.

# iptables -vnL -t nat --line-numbers |grep 10.1.1.0|awk '{print $1}' 
1

You can then use for to clear all the rules matching one specific IP.

# for rule in $(iptables -vnL -t nat --line-numbers |grep 10.1.1.0|awk '{print $1}'); do iptables -D INPUT $rule; done

Remember those numbers are shown per table, so you may need to limit the list command by table and clear one by one.

  • 1
    This won't work because the rules are listed in ascending order. Once you delete the first one all the other rules will re-order and have a different number. Once you get to the second rule that you want to delete you're now deleting the wrong line. You'd have to regenerate the list after each and every deletion. – bahamat Jun 22 '12 at 19:34
  • Not a real motive to -1 right? – coredump Jun 23 '12 at 22:12

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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