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

user548971
  • 259
  • 1
  • 3
  • 10

4 Answers4

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.

bahamat
  • 6,263
  • 24
  • 28
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
FastFreddy
  • 11
  • 1
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

bryanph
  • 111
  • 1
  • 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.

coredump
  • 12,713
  • 2
  • 36
  • 56
  • 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