如何检查iptables规则是否已存在?


41

我需要向iptables添加一条规则,以阻止从Internet到TCP端口的连接。

由于我的脚本可能被多次调用,并且没有脚本可以删除该规则,因此我想在插入之前检查iptables规则是否已经存在-否则INPUT链中会有很多dup规则。

如何检查iptables规则是否已存在?


或者,使用此包装程序,它提供幂等的iptables交互:xyne.archlinux.ca/projects/idemptables
sampablokuper

Answers:


44

-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"

12

-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

这段代码可能会旋转。它不能保证两个或多个赛车在固定的迭代次数内出局。可以添加一些随机的指数回退睡眠来帮助实现此目的。


1
我可以补充一下,由于您必须指出添加规则的确切方式,因此此命令不太令人满意。我使用安装程序进行了测试,但找不到规则,因为我没有指定确切的关键字和值...
Fabien Haddadi

如果您暂时删除规则,则可能会破坏某些内容……
Mehrdad

5

这似乎有些倒退,但是对我有用-尝试先删除规则。

iptables -D INPUT -s xxx.xxx.xxx.xxx -j DROP;

您应该收到类似的消息:

iptables:错误的规则(在该链中是否存在匹配的规则?)

然后只需正常添加规则:

iptables -A INPUT -s xxx.xxx.xxx.xxx -j DROP;


1
仅仅为了模拟幂等命令而在防火墙中开一个不必要的漏洞,可能不是一个好主意。当然,该漏洞是临时的,但仍会增加攻击者的机会。而且,如果某件事中断了替换规则的添加,则该孔可能会无限期地存在。
sampablokuper

好点@sampablokuper:出于安全原因,此策略可能仅适用于ACCEPT规则,而不适用于DROP规则
lucaferrario

我最终做了同样的事情!
warhansen

4

只是列出并搜索?

iptables --list | grep $ip

...或者您指定了规则。如果使用grep -q它不会输出任何内容,则可以使用以下命令检查返回值:$?


3
我建议iptables-save|grep $ip使用它,因为它是一种更容易解析的格式,尤其是在脚本中。您也可以根据需要检查命令的确切语法。
加勒特

1
这些都不能真正回答问题,因为iptables-save|grep $ip可以很好地匹配多个规则。可能iptables-save可以用来检查完整的规则规范,但这仍然有些技巧:返回的格式iptables-save可能与脚本中的规则不完全匹配。iptables-save可能会以不同的顺序生成选项,添加内容(例如-m tcp),依此类推。
larsk's

请记住,这iptables --list将尝试解析知名端口。因此,在grep输入端口之前,请确保已确定。
法比恩·哈达迪


0

为了避免脚本中重复的规则,请在下面添加行。

iptables -C -INPUT -p tcp --dport 8080 --jump ACCEPT || iptables -A -INPUT -p tcp --dport 8080 --jump ACCEPT

第一次运行上述命令时,我们将观察以下消息

iptables:错误规则(该链中是否存在匹配规则?)。

这仅供参考。但是命令的后半部分将确保添加规则。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.