記錄 TCP 標誌
我使用 nftables 作為我的規則。
我的問題:如何記錄 tcp 標誌?
這是我的規則:
nft add rule filter input tcp dport 22 ct state new tcp flags \& \(fin\|syn\) ==\( fin \| syn\) accept
我總是得到的結果:
Dec 6 13:40:19 my_host my_FIN IN=eth0 OUT=eth1 MAC= SRC=x.1.1.1 DST=x.2.2.2 LEN=40 TOS=00 PREC=0x00 TTL=127 ID=17695 DF PROTO=TCP SPT=54049 DPT=422SEQ=2558094232 ACK=0 WINDOW=8192 SYN URGP=0 MARK=0
編輯 我的規則:
chain FORWARD { ip saddr 1.1.1.1 ip daddr . tcp dport @myset tcp flags & (fin | syn) == fin | syn counter packets 0 bytes 0 log prefix " myprefix " group 1 accept
}
對於 TCP 情況,Netfilter 的 conntrack 在其內部狀態和等效 TCP 狀態之間進行了額外的一致性檢查。這個netdev 2.1 PDF文件(對不起,我找不到它的 netdev url,這是來自作者的網站)講述了它:
L4 跟踪器嘗試保持狀態,例如 tcp:跟踪狀態,檢查序列號。例子:
- 新的tcp數據包?SYN位設置?
- 預期視窗中的tcp序列號?
- 未確認的數據?→ 調整超時
- 首先?鰭?→ 刪除連接和/或調整超時
conntrack NEW狀態匹配 TCP SYN_SENT或 TCP SYN_RECEIVED狀態。如果您在規則中選擇NEW狀態條件,使用
ct state new
,它將永遠不會匹配任何FIN數據包,因為在建立新的 TCP 連接時永遠不會涉及FIN數據包。刪除後重試
ct state new
。更新:我最初沒有看到第二個問題。這個表達式:
tcp flags & (fin | syn) == fin | syn
將永遠不會與 FIN 標誌匹配,因為永遠不會同時找到 FIN+SYN(除了一些隨機的無效嘗試)。正確的表達應該是:
tcp flags & (fin | syn) != 0
無論何時設置 FIN或SYN都會匹配。實際上nftables簡化了它,只有這個被顯示或需要:
tcp flags fin,syn
因此,考慮到這兩種調整(
ct state new
必須仍然被刪除),規則變為:nft add rule filter FORWARD 'tcp dport 22 tcp flags fin,syn log prefix " my_FIN " group 1 accept
或在完整的鏈組中:
chain FORWARD { type filter hook forward priority 0; policy accept; ip saddr 1.1.1.1 ip daddr . tcp dport @myset tcp flags fin,syn counter log prefix " myprefix " group 1 accept }
一旦您可以使用上述規則實際檢測到 FIN 數據包,如果您的意圖是過濾一些 TCP 攻擊(您真的需要嗎?),請注意 netfilter 可能會考慮首先在 TCP 連接的第一個數據包中將 TCP FIN 視為INVALID狀態:您可能有興趣記錄這些狀態 (
ct state invalid
)。有 netfilter sysctl 切換可以改變關於INVALID狀態的結果:啟用 不會將其歸類為無效的 nf_conntrack_tcp_be_liberal 和禁用nf_conntrack_tcp_loose這將停止恢復已建立的 TCP 連接,即停止擁有沒有 SYN 的狀態 NEW。只有在失去連接跟踪後才能進行此恢復:在路由器重啟防火牆或使用 刷新 conntrack 狀態conntrack -F
之後,但誰知道呢,這裡可能會選擇偏執狂。