我有 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
第二个 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
当我从第一个 iptables 切换到第二个 iptables 时,我如何确定所有活动连接都会从“csa”中保存的 ip 中被终止?
我不是 iptables 专家。这是一种保护外部 IP 的安全方法吗?当第二个 iptables 激活时,这是阻止第一个 iptables 中允许的 ip 连接的正确方法吗?
多谢
答案1
使用
iptables-restore
逐一添加规则一次会更改一条防火墙规则,从而为防火墙规则集带来可能不需要的中间状态。相比之下,
iptables-save
原子地保存规则集,而相反地iptables-restore
原子地恢复规则集(至少对于给定的表)。数据包将要么看到第一个规则集,要么看到第二个规则集,但永远不会看到中间状态。一旦有了工作规则集,就不应该使用 shell 命令将其加载回来,而应该使用
iptables-save
将规则转储到文件中并iptables-restore
从该文件加载它们。该文件可以轻松地直接编辑,因为它是规则本身的常用语法。如果存在动态组件(动态 IP、临时 IP 禁令等),则应使用某种逻辑来调整规则,例如使用用户定义的链或同伴ipset
工具及相关匹配和目标。已建立的连接将使用当前方法保持已建立状态
iptables-restore
由于有状态短路规则,以这种方式(或使用 )切换规则不会终止活动连接。该规则查询连线仍然有有效的入口,并将继续允许交通。因此,尽管新规则集现在禁止,但允许端口 22 80 或 443 上已建立的连接无限期地持续(只要有足够的流量)。要终止所有已建立的连接,还应该(安装conntrack 工具并且)紧接着运行:
conntrack -F
这将冲洗连线查找表,要求连接通过 NEW 状态返回。端口 3306 的规则将保持已建立的连接不受阻碍。
默认情况下,即使使用 TCP也是
conntrack -F
不够的。已经建立的 TCP 连接有一个特殊的处理,可以根据 TCP 属性验证其流,并允许再次创建一个连线尽管没有看到 TCP SYN 数据包,但仍处于 NEW 状态。这是由系统控制财产
net.netfilter.nf_conntrack_tcp_loose
默认为松散。这仍然需要在某个地方允许新状态iptables规则集。唉,事实就是如此,因为
OUTPUT
链条允许一切因此这包括处于新状态的流的数据包。因此,虽然来自客户端的数据包现在最初被丢弃,但服务器是否应该发出单个数据包从先前到客户端的流,连接将不受阻碍地恢复。为了避免这种情况,通常可以
netfilter.nf_conntrack_tcp_loose
像这样禁用:sysctl -w net.netfilter.nf_conntrack_tcp_loose=0
但这也会中断之后与端口 3306 建立的连接
conntrack -F
。conntrack 工具不容易用来删除除一个之外的所有流,因此使用多个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
另一种方法是保持宽松的 TCP 处理,但也使用状态规则限制传出数据包。
iptables -A OUTPUT -o lo -j ACCEPT iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT iptables -P OUTPUT DROP
-A OUTPUT -p ... --dport ... -m conntrack --ctstate NEW -j ACCEPT
在这种情况下,还应该使用诸如)之类的规则为服务器所需的常见服务(DNS、NTP、Web 访问等)启用显式传出流量。
注意:我留下了 RELATED 的处理。通常最好将 RELATED 与 ESTABLISHED 一起使用。
例如,OP 的规则不允许 ICMP,因此没有 RELATED 规则来启用相关的 ICMP 错误,路径 MTU 发现无法正常工作(例如:当通过路径中的隧道时,TCP 连接可能会挂起)。人们仍然应该先看看这个博客:安全使用 iptables 和连接跟踪助手。