我有 2 个 iptables 配置。第二个 iptables 在 15:00 取代第一个。第一个 iptables 是:
#!/bin/bash
/usr/sbin/iptables -F
/usr/sbin/iptables -P INPUT DROP
/usr/sbin/iptables -P FORWARD DROP
/usr/sbin/iptables -P OUTPUT ACCEPT
/usr/sbin/iptables -A INPUT -i lo -j ACCEPT
/usr/sbin/iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
csa=MY_IP_TO_ALLOW
/usr/sbin/iptables -A INPUT -p tcp -m tcp -s $csa --dport 22 -m connlimit --connlimit-upto 1 -j ACCEPT
/usr/sbin/iptables -A INPUT -p tcp -m tcp -s $csa --dport 80 -m connlimit --connlimit-upto 1 -j ACCEPT
/usr/sbin/iptables -A INPUT -p tcp -m tcp -s $csa --dport 443 -m connlimit --connlimit-upto 1 -j ACCEPT
/usr/sbin/iptables -A INPUT -p tcp -s MY_SECOND_IP --dport 3306 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
Run Code Online (Sandbox Code Playgroud)
第二个 iptables 是:#!/bin/bash
/usr/sbin/iptables -F
/usr/sbin/iptables -P INPUT DROP
/usr/sbin/iptables -P FORWARD DROP
/usr/sbin/iptables -P OUTPUT ACCEPT
/usr/sbin/iptables -A INPUT -i lo -j ACCEPT
/usr/sbin/iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
/usr/sbin/iptables -A INPUT -p tcp -s MY_SECOND_IP --dport 3306 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
Run Code Online (Sandbox Code Playgroud)
当我从第一个 iptables 切换到第二个 iptables 时,我如何确定所有活动连接都会从“csa”中保存的 ip 中被终止?
我不是 iptables 专家。这是一种保护外部 IP 的安全方法吗?当第二个 iptables 激活时,这是阻止第一个 iptables 中允许的 ip 连接的正确方法吗?
多谢
使用iptables-restore
逐一添加规则一次会更改一条防火墙规则,从而为防火墙规则集带来可能不需要的中间状态。相比之下,iptables-save原子地保存规则集,而相反地iptables-restore原子地恢复规则集(至少对于给定的表)。数据包将要么看到第一个规则集,要么看到第二个规则集,但永远不会看到中间状态。
一旦有了工作规则集,就不应该使用 shell 命令将其加载回来,而应该使用iptables-save将规则转储到文件中并iptables-restore从该文件加载它们。该文件可以轻松地直接编辑,因为它是规则本身的常用语法。如果存在动态组件(动态 IP、临时 IP 禁止等),则应使用某种逻辑来调整规则,例如使用用户定义的链或配套工具ipset以及关联的match和target。
已建立的连接将使用当前方法保持已建立状态
iptables-restore由于有状态短路规则,以这种方式(或使用 )切换规则不会终止活动连接。此规则查询conntrack,该 conntrack 仍具有有效条目并将继续允许流量。因此,尽管新规则集现在禁止,但允许端口 22 80 或 443 上已建立的连接无限期地持续(只要有足够的流量)。
要终止所有已建立的连接,还应该在以下命令之后立即运行(安装conntrack-tools并):
conntrack -F
Run Code Online (Sandbox Code Playgroud)
这将刷新conntrack查找表,要求连接通过 NEW 状态返回。端口 3306 的规则将保持已建立的连接不受阻碍。
默认情况下,即使conntrack -F使用 TCP 也是不够的。
已经建立的 TCP 连接有一个特殊的处理,可以根据 TCP 属性验证其流,并允许在 NEW 状态下再次创建conntrack条目,尽管没有看到 TCP SYN 数据包。这是由sysctl属性控制的net.netfilter.nf_conntrack_tcp_loose,默认为宽松。
这仍然需要在iptables规则集中的某个位置允许新状态。唉,事实就是如此,因为OUTPUT链允许一切,所以这包括处于新状态的流的数据包。因此,虽然来自客户端的数据包现在最初被丢弃,但如果服务器将先前流中的单个数据包发送到客户端,连接将不受阻碍地恢复。
为了避免这种情况,通常可以netfilter.nf_conntrack_tcp_loose像这样禁用:
sysctl -w net.netfilter.nf_conntrack_tcp_loose=0
Run Code Online (Sandbox Code Playgroud)
但这也会中断之后与端口 3306 建立的连接conntrack -F。conntrack-tools不容易用来删除除一个之外的所有流,因此使用多个流conntrack -D ... 并不是一种简单的方法,但对于 OP 的特定情况来说很好(只需删除三种流):
用。。。来代替conntrack -F:
conntrack -D -s $csa -p tcp --dport 22
conntrack -D -s $csa -p tcp --dport 80
conntrack -D -s $csa -p tcp --dport 443
Run Code Online (Sandbox Code Playgroud)
另一种方法是保持宽松的 TCP 处理,但也使用状态规则限制传出数据包。
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
iptables -P OUTPUT DROP
Run Code Online (Sandbox Code Playgroud)
在这种情况下,还应该使用诸如 ) 之类的规则为服务器所需的常见服务(DNS、NTP、Web 访问等)启用显式传出流量-A OUTPUT -p ... --dport ... -m conntrack --ctstate NEW -j ACCEPT。
注意:我在 RELATED 的处理旁边留下了。通常最好将 RELATED 与 ESTABLISHED 一起使用。
例如,OP 的规则不允许 ICMP,因此如果没有 RELATED 规则来启用相关 ICMP 错误,路径 MTU 发现将无法正常工作(例如:在通过路径中的隧道时,TCP 连接可能会挂起)。人们仍然应该首先看一下这个博客:Secure use of iptables and Connection Tracking Helpers。