How can I remove specific rules from iptables?

2019-01-20 20:41发布

I am hosting special HTTP and HTTPS services on the ports 8006 and 8007 respectively. I use iptables to "activate" the server; i.e. to route the incoming HTTP and HTTPS ports:

iptables -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 8006 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 8007 -j ACCEPT
iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8006 
iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8007  
iptables -A OUTPUT -t nat -d 127.0.0.1 -p tcp --dport 80 -j REDIRECT --to-ports 8006
iptables -A OUTPUT -t nat -d 127.0.0.1 -p tcp --dport 443 -j REDIRECT --to-ports 8007 

This works like a charm. However I would like to create another script that disables my server again; i.e. restore iptables to the state it was in before running the lines above. However I am having a hard time figuring out the syntax to remove these rules. The only thing that seems to work is a complete flush:

iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

But that will also delete other iptables rules which is undesired.

6条回答
放我归山
2楼-- · 2019-01-20 21:17

Use -D command, this is how man page explains it:

-D, --delete chain rule-specification
-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.

Do realize this command, like all other command(-A, -I) works on certain table. If you'are not working on the default table(filter table), use -t TABLENAME to specify that target table.

Delete a rule to match

iptables -D INPUT -i eth0 -p tcp --dport 443 -j ACCEPT

Note: This only deletes the first rule matched. If you have many rules matched(this can happen in iptables), run this several times.

Delete a rule specified as a number

iptables -D INPUT 2

Other than counting the number you can list the line-number with --line-number parameter, for example:

iptables -t nat -nL --line-number
查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-01-20 21:19

Execute the same commands but replace the "-A" with "-D". For example:

iptables -A ...

becomes

iptables -D ...
查看更多
smile是对你的礼貌
4楼-- · 2019-01-20 21:22

The best solution that works for me without any problems looks this way:
1. Add temporary rule with some comment:

comment=$(cat /proc/sys/kernel/random/uuid | sed 's/\-//g')
iptables -A ..... -m comment --comment "${comment}" -j REQUIRED_ACTION

2. When the rule added and you wish to remove it (or everything with this comment), do:

iptables-save | grep -v "${comment}" | iptables-restore

So, you'll 100% delete all rules that match the $comment and leave other lines untouched. This solution works for last 2 months with about 100 changes of rules per day - no issues.Hope, it helps

查看更多
贼婆χ
5楼-- · 2019-01-20 21:24

First list all iptables rules with this command:

iptables -S

it lists like:

-A XYZ -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT

Then copy the desired line, and just replace -A with -D to delete that:

iptables -D XYZ -p ...
查看更多
太酷不给撩
6楼-- · 2019-01-20 21:36

You may also use the rule's number (--line-numbers):

iptables -L INPUT --line-numbers

Example output :

Chain INPUT (policy ACCEPT) 
    num  target prot opt source destination
    1    ACCEPT     udp  --  anywhere  anywhere             udp dpt:domain 
    2    ACCEPT     tcp  --  anywhere  anywhere             tcp dpt:domain 
    3    ACCEPT     udp  --  anywhere  anywhere             udp dpt:bootps 
    4    ACCEPT     tcp  --  anywhere  anywhere             tcp dpt:bootps

So if you would like to delete second rule :

iptables -D INPUT 2

Update

If you use(d) a specific table (eg nat), you have to add it to the delete command (thx to @ThorSummoner for the comment)

sudo iptables -t nat -D PREROUTING 1
查看更多
冷血范
7楼-- · 2019-01-20 21:42

Assume that, if you want to remove NAT rules,

List the appended IPtables using the command below,

# sudo iptables -L -t nat -v

Chain PREROUTING (policy ACCEPT 18 packets, 1382 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    7   420 DNAT       tcp  --  any    any     anywhere             saltmaster           tcp dpt:http to:172.31.5.207:80
    0     0 DNAT       tcp  --  eth0   any     anywhere             anywhere             tcp dpt:http to:172.31.5.207:8080

If you would like to remove the nat rule from the IPtables, just execute the command,

# sudo iptables -F -t nat -v

Flushing chain `PREROUTING'
Flushing chain `INPUT'
Flushing chain `OUTPUT'
Flushing chain `POSTROUTING'

Then, you can verify that,

# sudo iptables -L -t nat -v
查看更多
登录 后发表回答