Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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

share|improve this question

3 Answers 3

up vote 2 down vote accepted

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.

share|improve this answer
    
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

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
share|improve this answer

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.

share|improve this answer
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

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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