![使用 iptables 在 Web 服务器上丢弃 ACK FIN、ACK RST、RST 数据包](https://linux22.com/image/625610/%E4%BD%BF%E7%94%A8%20iptables%20%E5%9C%A8%20Web%20%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E4%B8%A2%E5%BC%83%20ACK%20FIN%E3%80%81ACK%20RST%E3%80%81RST%20%E6%95%B0%E6%8D%AE%E5%8C%85.png)
我在 Debian 7 机器上运行 Web 服务器 (Apache),并在该机器上运行 iptables。iptables 规则由 ConfigServer 防火墙 (CSF) 脚本生成。不过,我这边托管的网站运行正常我发现 80 端口有大量入站流量被丢弃。
以下是日志的摘录(网络服务器 IP:11.22.33.44):
Jan 27 15:21:36 [hostname] kernel: [1229124.817624] Firewall: *TCP_IN Blocked* IN=venet0 OUT= MAC= SRC=199.30.24.209 DST=11.22.33.44 LEN=40 TOS=0x00 PREC=0x00 TTL=115 ID=3144 DF PROTO=TCP SPT=36879 DPT=80 WINDOW=510 RES=0x00 ACK FIN URGP=0
Jan 27 15:21:36 [hostname] kernel: [1229124.872795] Firewall: *TCP_IN Blocked* IN=venet0 OUT= MAC= SRC=199.30.24.209 DST=11.22.33.44 LEN=40 TOS=0x00 PREC=0x00 TTL=115 ID=3183 DF PROTO=TCP SPT=36684 DPT=80 WINDOW=513 RES=0x00 ACK FIN URGP=0
Jan 27 16:03:36 [hostname] kernel: [1231642.223513] Firewall: *TCP_IN Blocked* IN=venet0 OUT= MAC= SRC=5.39.50.0 DST=11.22.33.44 LEN=40 TOS=0x00 PREC=0x00 TTL=122 ID=19101 DF PROTO=TCP SPT=51394 DPT=80 WINDOW=508 RES=0x00 ACK FIN URGP=0
Jan 27 16:03:41 [hostname] kernel: [1231647.015463] Firewall: *TCP_IN Blocked* IN=venet0 OUT= MAC= SRC=5.39.50.0 DST=11.22.33.44 LEN=40 TOS=0x00 PREC=0x00 TTL=122 ID=26215 DF PROTO=TCP SPT=51394 DPT=80 WINDOW=508 RES=0x00 ACK RST URGP=0
Jan 27 16:03:51 [hostname] kernel: [1231656.677627] Firewall: *TCP_IN Blocked* IN=venet0 OUT= MAC= SRC=5.39.50.0 DST=11.22.33.44 LEN=40 TOS=0x00 PREC=0x00 TTL=122 ID=10630 DF PROTO=TCP SPT=51394 DPT=80 WINDOW=0 RES=0x00 ACK RST URGP=0
Jan 27 16:04:42 [hostname] kernel: [1231707.911962] Firewall: *TCP_IN Blocked* IN=venet0 OUT= MAC= SRC=86.217.34.8 DST=11.22.33.44 LEN=40 TOS=0x00 PREC=0x00 TTL=111 ID=3513 DF PROTO=TCP SPT=54465 DPT=80 WINDOW=0 RES=0x00 RST URGP=0
Jan 27 16:04:42 [hostname] kernel: [1231707.911976] Firewall: *TCP_IN Blocked* IN=venet0 OUT= MAC= SRC=86.217.34.8 DST=11.22.33.44 LEN=40 TOS=0x00 PREC=0x00 TTL=111 ID=3514 DF PROTO=TCP SPT=54465 DPT=80 WINDOW=0 RES=0x00 RST URGP=0
数百行这样的内容。没有特定的时间模式,并且掉线发生在随机客户端。
但这些丢弃的数据包总是被标记为 ACK FIN、RST、ACK RST,很少被标记为 SYN。我理解这些是“确认传输并结束连接”数据包。
相关iptables规则:
Chain INPUT (policy DROP)
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere ctstate NEW tcp dpt:80
LOGDROPIN all -- anywhere anywhere
Chain LOGDROPIN (1 references)
LOG tcp -- anywhere anywhere limit: avg 30/min burst 5 LOG level warning prefix "Firewall: *TCP_IN Blocked* "
DROP all -- anywhere anywhere
因此,从表面上看,这些数据包被丢弃是因为它们对应的连接不再打开,即 RELATED 或 ESTABLISHED。这意味着传输成功,并且服务器在客户端有时间确认收到的数据之前关闭了连接,从而使连接(也许是 HTTP 请求?)挂在客户端。
我真的很好奇是什么原因造成的。我也想知道客户是否受到影响,因为我似乎无法复制这个问题。我希望你们能帮助我理解!
感谢阅读 =)
编辑:好的,我去钓鱼,并对其中一个 [ACK,FIN] 数据包被丢弃的情况进行了数据包跟踪(按照下面我的评论中描述的方法)。最后三个数据包是被防火墙丢弃的:
Source Destination Protocol Length Info Time
[CLIENT COMP] [WEBSERVER] TCP 68 55478 > http [SYN] Seq=0 Win=8192 Len=0 MSS=1400 WS=4 SACK_PERM=1 2014-01-29 20:44:36.044009
[WEBSERVER] [CLIENT COMP] TCP 68 http > 55478 [SYN, ACK] Seq=0 Ack=1 Win=14600 Len=0 MSS=1460 SACK_PERM=1 WS=512 2014-01-29 20:44:36.044052
[WEBSERVER] [CLIENT COMP] TCP 68 http > 55478 [SYN, ACK] Seq=0 Ack=1 Win=14600 Len=0 MSS=1460 SACK_PERM=1 WS=512 2014-01-29 20:44:37.243948
[CLIENT COMP] [WEBSERVER] TCP 56 55478 > http [ACK] Seq=1 Ack=1 Win=16800 Len=0 2014-01-29 20:44:37.421123
[CLIENT COMP] [WEBSERVER] HTTP 464 GET /sites/default/files/js/js_R9UbiVw2xuTUI0GZoaqMDOdX0lrZt....js HTTP/1.1 2014-01-29 20:44:37.432097
[WEBSERVER] [CLIENT COMP] TCP 56 http > 55478 [ACK] Seq=1 Ack=409 Win=15872 Len=0 2014-01-29 20:44:37.432122
[WEBSERVER] [CLIENT COMP] HTTP 963 HTTP/1.1 200 OK (text/javascript) 2014-01-29 20:44:37.432703
[CLIENT COMP] [WEBSERVER] TCP 56 55478 > http [ACK] Seq=409 Ack=908 Win=15892 Len=0 2014-01-29 20:44:37.769928
[WEBSERVER] [CLIENT COMP] TCP 56 http > 55478 [FIN, ACK] Seq=908 Ack=409 Win=15872 Len=0 2014-01-29 20:44:42.437129
[CLIENT COMP] [WEBSERVER] TCP 56 55478 > http [ACK] Seq=409 Ack=909 Win=15892 Len=0 2014-01-29 20:44:42.580378
[CLIENT COMP] [WEBSERVER] TCP 56 55478 > http [FIN, ACK] Seq=409 Ack=909 Win=15892 Len=0 2014-01-29 20:49:44.668730
[CLIENT COMP] [WEBSERVER] TCP 56 55478 > http [FIN, ACK] Seq=409 Ack=909 Win=15892 Len=0 2014-01-29 20:49:49.194316
[CLIENT COMP] [WEBSERVER] TCP 56 55478 > http [FIN, ACK] Seq=409 Ack=909 Win=15892 Len=0 2014-01-29 20:49:58.869659
根据这个:
- 服务器发送 HTTP 200 OK 响应
- 希望关闭连接。它向客户端发送一个 [FIN, ACK] 数据包,因为我猜它正在尝试同时关闭连接。
- 客户端以 [ACK] 响应服务器的 [FIN, ACK](Seq/Ack 编号的顺序正确),但没有 [FIN],根据规范,这意味着连接仅半关闭。
- 但是之后,5分钟后,客户端发送 [FIN,ACK],这是不寻常的,因为它已经向服务器的“连接结束”发送了 ACK。我猜想这涉及到某种形式的 TCP 超时,并且客户端仅尝试关闭保持打开的连接。
因此,很明显,连接终止握手没有按照正确的顺序发生。问题似乎出在客户端,客户端直到 5 分钟超时才关闭连接。
我注意到了三件事:
- 这个特定的客户端正在运行现代浏览器,因此浏览器不是问题。
- 他/她发送/接收了大量 TCP 重传,表明连接有丢失。事实证明,这个人是从摩洛哥用 3G 连接的,所以这确实有道理 ^^。
- 最后,Apache 日志显示他确实得到了正确的 HTTP 响应,因此网站流量没有受到该“问题”的影响。
很有趣的东西。如果你有的话,就拍吧!
答案1
根据邮件链在 netfilter 上,这似乎是 iptables 的正常功能。如果您不想在日志中收到这些消息,可以尝试将其添加INVALID
到端口 80 上要接受的状态列表中,看看该问题是否消失。
否则,除了令人烦恼和填充日志之外,它是无害的流量,您的客户不会遇到任何问题。