Answers:
-C --check
在最新的iptables版本中有一个新选项。
# iptables -C INPUT -p tcp --dport 8080 --jump ACCEPT
iptables: Bad rule (does a matching rule exist in that chain?).
# echo $?
1
# iptables -A INPUT -p tcp --dport 8080 --jump ACCEPT
# iptables -C INPUT -p tcp --dport 8080 --jump ACCEPT
# echo $?
0
对于较旧的iptables版本,我将使用Garrett建议:
# iptables-save | grep -- "-A INPUT -p tcp -m tcp --dport 8080 -j ACCEPT"
新-C
选项并不令人满意,因为它可以接受使用时间检查(TOCTTOU)竞赛条件。如果两个进程尝试在大约同一时间添加同一规则,-C
则不会保护他们避免两次添加该规则。
因此,这确实比grep
解决方案更好。在的输出上进行准确的文本处理工作iptables-save
可以像一样可靠地工作-C
,因为该输出是表状态的可靠快照。
所需要的是一个--ensure
选项,该选项仅在规则不存在时才自动检查并添加规则。此外,最好将规则移到正确的位置,如果该位置尚不存在,则可以插入新规则(--ensure-move
)。例如,如果iptables -I 1
用于在链的顶部创建规则,但是该规则已经位于第七位置,那么现有规则应移至第一位置。
如果没有这些功能,我认为可行的解决方法是根据此伪代码编写一个Shell脚本循环:
while true ; do
# delete all copies of the rule first
while copies_of_rule_exist ; do
iptables -D $RULE
done
# now try to add the rule
iptables -A $RULE # or -I
# At this point there may be duplicates due to races.
# Bail out of loop if there is exactly one, otherwise
# start again.
if exactly_one_copy_of_rule_exists ; then
break;
fi
done
这段代码可能会旋转。它不能保证两个或多个赛车在固定的迭代次数内出局。可以添加一些随机的指数回退睡眠来帮助实现此目的。
这似乎有些倒退,但是对我有用-尝试先删除规则。
iptables -D INPUT -s xxx.xxx.xxx.xxx -j DROP;
您应该收到类似的消息:
iptables:错误的规则(在该链中是否存在匹配的规则?)
然后只需正常添加规则:
iptables -A INPUT -s xxx.xxx.xxx.xxx -j DROP;
只是列出并搜索?
iptables --list | grep $ip
...或者您指定了规则。如果使用grep -q
它不会输出任何内容,则可以使用以下命令检查返回值:$?
iptables-save|grep $ip
使用它,因为它是一种更容易解析的格式,尤其是在脚本中。您也可以根据需要检查命令的确切语法。
iptables-save|grep $ip
可以很好地匹配多个规则。可能iptables-save
可以用来检查完整的规则规范,但这仍然有些技巧:返回的格式iptables-save
可能与脚本中的规则不完全匹配。iptables-save
可能会以不同的顺序生成选项,添加内容(例如-m tcp
),依此类推。
iptables --list
将尝试解析知名端口。因此,在grep输入端口之前,请确保已确定。
如何按照https://serverfault.com/questions/628590/duplicate-iptable-rules中的说明先添加然后删除重复项。最简单(对于相邻线)似乎是
iptables-save | uniq | iptables-restore
为了避免脚本中重复的规则,请在下面添加行。
iptables -C -INPUT -p tcp --dport 8080 --jump ACCEPT || iptables -A -INPUT -p tcp --dport 8080 --jump ACCEPT
第一次运行上述命令时,我们将观察以下消息
iptables:错误规则(该链中是否存在匹配规则?)。
这仅供参考。但是命令的后半部分将确保添加规则。