iptables 是否不应该阻止端口 80 和 443 上的部分流量?

iptables 是否不应该阻止端口 80 和 443 上的部分流量?

我管理的 Web 服务器显示目标端口 443 上 IPv4 地址的奇怪 iptables 拒绝,尽管明确允许 HTTPS 流量。同一规则中还允许端口 80,但该站点仅支持 HTTPS,并且 nginx 立即将 80 重定向到 443。

事情是:浏览网站作品。您可以加载所有页面,所有资源都可以正常访问等等。但这里显然有些不对劲,这可能会损害页面加载性能。

以下是分别针对端口 443 和 80 记录的一些错误示例/var/log/iptables_deny.log。根据tail -f日志文件的记录,这些错误可能单独出现,也可能突发出现。绝大多数错误都与端口 443 有关:

iptables denied: IN=eth0 OUT= MAC=f2:3c:91:26:1e:1f:84:78:ac:0d:8f:41:08:00 SRC=(redacted IP) DST=(redacted IP) LEN=40 TOS=0x08 PREC=0x00 TTL=53 ID=61266 DF PROTO=TCP SPT=49264 DPT=443 WINDOW=0 RES=0x00 RST URGP=0
iptables denied: IN=eth0 OUT= MAC=f2:3c:91:26:1e:1f:84:78:ac:0d:8f:41:08:00 SRC=(redacted IP) DST=(redacted IP) LEN=40 TOS=0x00 PREC=0x00 TTL=115 ID=11186 DF PROTO=TCP SPT=58445 DPT=443 WINDOW=254 RES=0x00 ACK FIN URGP=0
iptables denied: IN=eth0 OUT= MAC=f2:3c:91:26:1e:1f:84:78:ac:0d:8f:41:08:00 SRC=(redacted IP) DST=(redacted IP) LEN=40 TOS=0x00 PREC=0x00 TTL=116 ID=16941 DF PROTO=TCP SPT=16278 DPT=80 WINDOW=255 RES=0x00 ACK FIN URGP=0

快速 grepping 显示拒绝中的数据包类型至少可以是 ACK、ACK FIN、ACK RST、ACK PSH 和 RST。也许还有其他,但它们没有引起我的注意。

下面是 iptables -nvL 的输出。根据我所读到的所有内容,基本模式(首先允许所有相关和已建立的流量,然后允许 80 和 443 上的所有新流量)应该是可靠的。LOG 和 DROP 规则是 INPUT 链中的最后一个规则,理应如此。

Chain INPUT (policy ACCEPT 1 packets, 391 bytes)
 pkts bytes target     prot opt in     out     source          destination   
    0     0 ACCEPT     all  --  lo     *       0.0.0.0/0       0.0.0.0/0     
 8893  770K ACCEPT     all  --  *      *       0.0.0.0/0       0.0.0.0/0      ctstate RELATED,ESTABLISHED
    0     0 ACCEPT     tcp  --  *      *       (redacted IP)   0.0.0.0/0      ctstate NEW tcp dpt:22
    0     0 ACCEPT     tcp  --  *      *       (redacted IP)   0.0.0.0/0      ctstate NEW tcp dpt:22
    0     0 ACCEPT     tcp  --  *      *       (redacted IP)   0.0.0.0/0      ctstate NEW tcp dpt:22
    0     0 ACCEPT     tcp  --  *      *       (redacted IP)   0.0.0.0/0      ctstate NEW tcp dpt:22
    0     0 ACCEPT     icmp --  *      *       0.0.0.0/0       0.0.0.0/0      icmptype 8
   63  3840 ACCEPT     tcp  --  *      *       0.0.0.0/0       0.0.0.0/0      ctstate NEW multiport dports 80,443
    0     0 DROP       udp  --  *      *       0.0.0.0/0       0.0.0.0/0      udp dpt:137
    0     0 DROP       udp  --  *      *       0.0.0.0/0       0.0.0.0/0      udp dpt:138
    0     0 DROP       udp  --  *      *       0.0.0.0/0       0.0.0.0/0      udp dpt:139
    0     0 DROP       udp  --  *      *       0.0.0.0/0       0.0.0.0/0      udp dpt:445
    1    40 LOG        all  --  *      *       0.0.0.0/0       0.0.0.0/0      limit: avg 15/min burst 5 LOG flags 0 level 7 prefix "iptables denied: "
    1    40 DROP       all  --  *      *       0.0.0.0/0       0.0.0.0/0     

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source          destination   
    0     0 DROP       all  --  *      *       0.0.0.0/0       0.0.0.0/0     

Chain OUTPUT (policy ACCEPT 1 packets, 65 bytes)
 pkts bytes target     prot opt in     out     source          destination   
 7311   19M ACCEPT     all  --  *      *       0.0.0.0/0       0.0.0.0/0

实际的相关规则(如果它们在该输出之后有任何用处):

-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p tcp -m conntrack --ctstate NEW -m multiport --dports 80,443 -j ACCEPT

很明显,这总体上不是恶意流量。我从几个不同的 IP 地址浏览了该网站,虽然该网站加载看似正常,但我的 IP 也出现在拒绝日志中,没有任何我能辨别的模式,浏览器中也没有任何用户可见的错误情况。

知道这背后可能是什么原因吗?

答案1

RST 和 ACK,FIN 数据包是 TCP 连接最末端的一部分。

我的理解是,iptables出于安全原因,的连接跟踪引擎采用了一种非常强大的方法来删除状态表条目:一旦它看到连接的一端试图关闭它,那么(知道这样的请求表示连接的结束,因为它的一端现在认为连接已关闭)它会删除允许该连接流量的状态表条目。

等待更长时间再这样做可能是不安全的,以防万一其他类似的防火墙也位于路径中,阻止了 RFC 指定的其余整理数据包;延迟收割状态表条目直到看到这些条目可能会冒着在表中保留无效条目一段时间的风险,并且这将带来潜在的漏洞。

但是 RFC 指定了更多需要完成的整理工作,而您看到的被拒绝的正是这些数据包。是的,这意味着连接中的端点将使用更多内存,等待连接过期,而不是看到完全关闭并能够更快地释放连接内存;但提高安全性通常需要资源,这就是其中一种权衡。

这些数据包永远无法通过并没有什么危害,所以您可以放心地忽略日志条目。

编辑:如果你不想在日志中看到它们,请在日志记录行之前处理它们,例如

iptables -I INPUT 13 -p tcp -m conntrack --ctstate INVALID --tcp-flags ACK,FIN ACK,FIN -j DROP

相关内容