Apache-2.2

使用 iptables 在網路伺服器上丟棄 ACK FIN、ACK RST、RST 數據包

  • October 17, 2015

我在 Debian 7 機器上執行網路伺服器(Apache),iptables 在同一台機器上。iptables 規則由 ConfigServer Firewall (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

所以從表面上看,這些數據包被丟棄是因為它們相應的連接不再打開,即相關或已建立。這意味著傳輸成功,並且伺服器在客戶端有時間確認接收到的數據之前關閉連接,從而使連接(可能還有 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

根據這個:

  1. 伺服器發送其 HTTP 200 OK 響應
  2. 希望關閉連接。它發出一個$$ FIN, ACK $$數據包到客戶端,因為我猜它正在嘗試關閉同時連接。
  3. 客戶端響應$$ ACK $$到伺服器的$$ FIN, ACK $$(Seq/Ack 編號的順序正確)但沒有$$ FIN $$,根據規範,這意味著連接只是半封閉的。
  4. 但是,5分鐘後,客戶端發送了一個$$ FIN, ACK $$,這是不尋常的,因為它已經向伺服器的“連接結束”發送了一個 ACK。我猜測涉及某種形式的 TCP 超時,並且客戶端只是試圖關閉一個保持打開狀態的連接。

很明顯,連接終止握手沒有以正確的順序發生。看起來問題出在客戶端,直到 5 分鐘超時才關閉連接。

我注意到了 3 件事:

  • 這個特定的客戶端執行的是現代瀏覽器,所以瀏覽器不是問題。
  • 他/她正在發送/接收大量 TCP 重傳,這表明連接失去。事實證明,這傢伙是從摩洛哥通過 3G 連接的,所以它確實加起來了^^。
  • 最後,Apache 日誌顯示他確實得到了正確的 HTTP 響應,因此站點流量不受“問題”的影響。

有趣的東西。有什麼就開槍!

根據 netfilter 上的郵件鏈,這似乎是 iptables 的正常功能。如果您不想在日誌中獲取這些消息,您可以嘗試添加INVALID到狀態列表以在埠 80 上接受並查看該問題是否消失。

否則,除了煩人和填滿日誌之外,它是無害的流量,您的客戶不會遇到任何問題。

引用自:https://serverfault.com/questions/570178