如何使用 IPTables 关闭某些端口上的所有 _existing_ TCP 连接?

Nat*_*ese 4 iptables tcp linux-networking redis

假设我有一个我想运行的快速网络分区测试,例如将 ReDiS 集群的两半彼此断开连接,并且我想使用 IPTables 暂时断开一组服务器与另一组服务器的连接。

这与在 Fedora 邮件列表中提出的问题非常相似:

https://www.redhat.com/archives/rhl-list/2006-January/msg03380.html

如果我EXISTING,RELATED在 的输出中没有看到iptables --list,我是否需要担心这个?

Fedora 邮件列表上的以下答案似乎说是的,如果我EXISTING,RELATEDiptables --list.

https://www.redhat.com/archives/rhl-list/2006-January/msg03396.html

对自反标记者的说明,在那里:这个问题,更重要的是,它的答案,将讨论 IPTables 是否在更新其规则时丢弃现有连接。

据我所知,本网站上关于此主题的其他问题并未解决现有连接和尝试连接之间的差异:

如何关闭除通过 IPTABLES 列出的所有网络的某些 TCP/UDP 端口(传入)

我在以下 URL 链接的页面上通过 Google 搜索找到了我的大部分研究结果:

https://duckduckgo.com/?q=iptables+close+existing+connections

HBr*_*ijn 7

任何 iptables 规则都不会关闭现有的 TCP 连接,因为这涉及主动传输带有 FIN 位消息。这是由应用程序完成的,而不是由数据包过滤器完成的。

另一方面,iptables 可以随时阻止您的应用程序通过任何现有连接接收或传输新数据包,它还可以拒绝建立任何新连接。

这与您是否有状态防火墙无关。

这完全取决于您将新防火墙规则插入的确切位置。因为,请记住,您的防火墙规则是按照它们列出的顺序进行检查的,并且处理将在第一个决定性匹配时停止。

即一个简单的状态防火墙:

[root@host ~]# iptables-save
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [441:59938]
                     #1  < INSERT NEW RULE HERE
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
                     #2  < INSERT NEW RULE HERE
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
                     #3  < INSERT NEW RULE HERE
-A INPUT -j REJECT --reject-with icmp-host-prohibited
                     #4  < iptables -A WILL APPEND NEW RULE HERE
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
Run Code Online (Sandbox Code Playgroud)

现在如果你想要一个新规则:

INPUT -s 10.0.0.89/32 -j REJECT --reject-with icmp-port-unreachable
Run Code Online (Sandbox Code Playgroud)

并将其插入位置 #1,所有从该主机接收到的数据包都将被阻止。

在位置 #2 插入该规则,现有连接上的数据包仍将被允许,但无法建立新连接。

在位置 #3 插入特定的新规则是无用的,因为效果与根本没有针对 10.0.0.89 的特定策略相同,但这是放置规则以授予对 10.0.0.89 的访问权限的正确位置端口。

并采用iptables -A INPUT追加新规则到INPUT链是无用的,将放置在规则的所有业务已经被拒绝位置#4INPUT -j REJECT --reject-with icmp-host-prohibited规则。

简而言之:使用iptables -I(而不是ipatbles -A)中的规则编号选项将新的(临时)规则放置在具有预期效果的位置:

sudo iptables -I <rule number> INPUT -s 10.0.0.89/32 -j REJECT --reject-with icmp-port-unreachable
Run Code Online (Sandbox Code Playgroud)

如果使用相同的状态防火墙配置,您想停止允许纯 HTTP,您可以删除允许流量到端口 80 的规则

sudo iptables -D INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
Run Code Online (Sandbox Code Playgroud)

但是这样做不会清空 iptables 使用的会话状态表,并且规则仍然允许到端口 80 的现有连接 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

您可以通过简单地停止/重新启动网络服务器来解决这个问题,这将通过发送 FIN 消息正确关闭那些打开的会话并将它们从会话状态表中清除。

或者,您可以在位置 #1 处向端口 80 添加阻止数据包的规则。