iptables - 如何杀死除 IP 之外的已建立连接?

iptables - 如何杀死除 IP 之外的已建立连接?

我有 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

  1. 使用iptables-restore

    逐一添加规则一次会更改一条防火墙规则,从而为防火墙规则集带来可能不需要的中间状态。相比之下,iptables-save原子地保存规则集,而相反地iptables-restore原子地恢复规则集(至少对于给定的表)。数据包将要么看到第一个规则集,要么看到第二个规则集,但永远不会看到中间状态。

    一旦有了工作规则集,就不应该使用 shell 命令将其加载回来,而应该使用iptables-save将规则转储到文件中并iptables-restore从该文件加载它们。该文件可以轻松地直接编辑,因为它是规则本身的常用语法。如果存在动态组件(动态 IP、临时 IP 禁令等),则应使用某种逻辑来调整规则,例如使用用户定义的链或同伴ipset工具及相关匹配目标

  2. 已建立的连接将使用当前方法保持已建立状态

    iptables-restore由于有状态短路规则,以这种方式(或使用 )切换规则不会终止活动连接。该规则查询连线仍然有有效的入口,并将继续允许交通。因此,尽管新规则集现在禁止,但允许端口 22 80 或 443 上已建立的连接无限期地持续(只要有足够的流量)。

    要终止所有已建立的连接,还应该(安装conntrack 工具并且)紧接着运行:

    conntrack -F
    

    这将冲洗连线查找表,要求连接通过 NEW 状态返回。端口 3306 的规则将保持已建立的连接不受阻碍。

  3. 默认情况下,即使使用 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 -Fconntrack 工具不容易用来删除除一个之外的所有流,因此使用多个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 处理,但也使用状态规则限制传出数据包。

      例如(使用现代版本state:conntrack):

      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 和连接跟踪助手

相关内容