如何从 iptables 中删除特定规则? [关闭]
Posted
技术标签:
【中文标题】如何从 iptables 中删除特定规则? [关闭]【英文标题】:How can I remove specific rules from iptables? [closed] 【发布时间】:2012-04-29 03:46:13 【问题描述】:我分别在端口 8006 和 8007 上托管特殊的 HTTP 和 HTTPS 服务。我使用 iptables 来“激活”服务器;即路由传入的 HTTP 和 HTTPS 端口:
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
这就像一个魅力。但是我想创建另一个脚本来再次禁用我的服务器;即将 iptables 恢复到运行上述行之前的状态。但是,我很难弄清楚删除这些规则的语法。唯一可行的方法是完全冲洗:
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
但这也会删除其他不需要的 iptables 规则。
【问题讨论】:
我发现ACCEPT
行最好使用-I
而不是-A
。这是因为通常情况下,最后一行(例如 INPUT
链)是 DROP
或 REJECT
并且您希望您的规则在此之前出现。 -A
将新规则放在最后一条规则之后,而 -I
将它放在开头。
【参考方案1】:
这是一个删除与搜索匹配的iptables
规则的单行。此示例搜索与 IP 地址192.168.1.27
匹配的所有规则并将其全部删除。您可以编辑自己的搜索条件来代替该 IP 地址。
eval `iptables --list-rules | grep '192.168.1.27' | sed 's/^-A /iptables -D /g;s/$/;/g'`
工作原理:
它使用此问题的公认答案并使用-D
而不是-A
运行规则。
iptables --list-rules
列出所有现有规则。即使您使用-I
或-R
添加它们,此列表也会以-A
显示它们
| grep '192.168.1.27'
将列表过滤为您想要删除的规则(在本例中为某些特定 IP 地址的规则。)
| sed
进行搜索和替换
s/^-A /iptables -D /g
将每条规则开头的 -A
替换为 iptables -D
,使其成为删除规则的可执行命令。
s/$/;/g
将每个规则的末尾替换为分号,以便在运行时分隔多个命令
eval ...
获取所有输出并将其作为脚本运行。
【讨论】:
【参考方案2】:你也可以使用下面的语法
iptables -D <chain name> <rule number>
例如
Chain HTTPS
target prot opt source destination
ACCEPT all -- anywhere anywhere
ACCEPT all -- 10.0.0.0/8 anywhere
ACCEPT all -- 182.162.0.0/16 anywhere
删除规则
接受所有 -- 10.0.0.0/8 任何地方
iptables -D HTTPS 2
【讨论】:
【参考方案3】:首先用这个命令列出所有 iptables 规则:
iptables -S
列出如下:
-A XYZ -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
然后复制所需的行,只需将-A
替换为-D
即可删除:
iptables -D XYZ -p ...
【讨论】:
注意!这是不完整的答案。来自关于“-S”的手册:“像所有其他 iptables 命令一样,它适用于指定的表(过滤器是默认值)。”。因此,如果使用此开关 - 应该对所有表重复:nat、mangle 等 在我的情况下,我得到iptables: Bad rule (does a matching rule exist in that chain?).
现在怎么办?
啊,想通了 - 我的删除命令缺少表规范。因此,如果您列出表 nat
和 sudo iptables -S -t nat
中的所有规则并且您想删除返回的规则之一,复制是不够的。您必须添加-t nat
,例如sudo iptables -D ... -t nat
.
通俗易懂!【参考方案4】:
执行相同的命令,但将“-A”替换为“-D”。例如:
iptables -A ...
变成
iptables -D ...
【讨论】:
如果你有多个规则,它不会全部删除。 尝试多次执行这个-D命令,会全部删除。 我执行了相同的命令,但使用 -D 而不是 -I。但我得到了错误的规则(是否存在匹配规则)...... 如果您使用-I
或-R
添加规则,您仍然可以使用-D
将其删除。
只是一个注释。我使用“iptables -A ...”创建了一个规则,该规则出现但无效。在使用 'iptables -D ...' 时,响应是 Bad rule。即便如此,这条规则也被删除了。使用“sudo iptables -nvL”可以看到该规则。我使用的链是'INPUT'。【参考方案5】:
假设,如果你想删除 NAT 规则,
使用下面的命令列出附加的 IPtables,
# 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
如果您想从 IPtables 中删除 nat 规则,只需执行命令,
# sudo iptables -F -t nat -v
Flushing chain `PREROUTING'
Flushing chain `INPUT'
Flushing chain `OUTPUT'
Flushing chain `POSTROUTING'
然后,您可以验证,
# sudo iptables -L -t nat -v
【讨论】:
【参考方案6】:使用-D
命令,man
页面是这样解释的:
-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.
意识到这个命令,就像所有其他命令(-A
,-I
)在特定表上工作。如果您不使用默认表(filter
表),请使用 -t TABLENAME
指定该目标表。
删除要匹配的规则
iptables -D INPUT -i eth0 -p tcp --dport 443 -j ACCEPT
注意:这只会删除第一个匹配的规则。如果你有很多匹配的规则(这可能发生在 iptables 中),运行几次。
删除指定为数字的规则
iptables -D INPUT 2
除了计算数字之外,您还可以使用--line-number
参数列出行号,例如:
iptables -t nat -nL --line-number
【讨论】:
我发现这个带有--line-number 的最好 是的!高超!不想要整个iptables -F
【参考方案7】:
您也可以使用规则的编号(--line-numbers):
iptables -L INPUT --line-numbers
示例输出:
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
所以如果你想删除第二条规则:
iptables -D INPUT 2
更新
如果你使用(d)一个特定的表(例如 nat),你必须将它添加到删除命令中(感谢@ThorSummoner 的评论)
sudo iptables -t nat -D PREROUTING 1
【讨论】:
两种解决方案都很好,但是当行号未知时,这个解决方案在脚本设置中不起作用。所以另一个解决方案更通用,因此更正确,IMO。 好吧,如果您不知道该行,您可以使用评论(例如其中的答案)或为您的规则做一个 grep:iptables -L INPUT --line-numbers | grep -oP "([0-9]1,3).*tcp.*domain" | cut -d" " -f1
只有在表格不能在任何时间点插入规则时才可以。否则,行号可能会在观察它们和执行删除规则之间发生变化。在这种情况下,假设时间窗口太短以至于“不可能发生”是不安全的。
请记住,如果您删除一条规则,则其余规则的行号会更改。因此,如果您需要删除规则 5、10 和 12... 删除它们 12、10 和 5。
尝试删除 PREROUTING 规则时,我必须指定 -t nat
,例如:sudo iptables -t nat --line-numbers -L
,并使用 -t nat
删除它们,例如:sudo iptables -t nat -D PREROUTING 1
(可能值得添加到答案中?)【参考方案8】:
对我来说没有任何问题的最佳解决方案如下所示: 1. 添加临时规则并附上一些注释:
comment=$(cat /proc/sys/kernel/random/uuid | sed 's/\-//g')
iptables -A ..... -m comment --comment "$comment" -j REQUIRED_ACTION
2。当添加规则并且您希望删除它(或带有此评论的所有内容)时,请执行以下操作:
iptables-save | grep -v "$comment" | iptables-restore
因此,您将 100% 删除与 $comment 匹配的所有规则,而其他行保持不变。此解决方案在过去 2 个月内有效,每天更改约 100 次规则 - 没有问题。希望,它会有所帮助
【讨论】:
如果您没有 iptables-save/restore:iptables -S | grep "$comment" | sed 's/^-A //' | while read rule; do iptables -D $rule; done
实际使用:CRON 1) 删除旧的 spamhaus
iptables 禁令,2) 抓取 spamhaus.org/drop,3) grep 获取 CIDR IP 和 iptables -A INPUT -s $ip_cidr -j -m comment --comment "spamhaus"
@Mansour 或iptables -S | sed "/$comment/s/-A/iptables -D/e"
;) 喜欢this
@hek2mgl sed 不会放弃,是吗? =] 谢谢,我会记住这个功能(我会在一天内忘记语法)。
sed 仅用于从 uuid 中删除“-”。无论如何,一旦您掌握了 sed 语法,就永远不会忘记它。 ))以上是关于如何从 iptables 中删除特定规则? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
iptables Drop Policy 将删除我的接受规则 [关闭]
如何彻底清除iptables或者删除任何iptables的规则