新聞中心
這是有關(guān)網(wǎng)絡(luò)地址轉(zhuǎn)換network address translation(NAT)的系列文章中的第二篇。之前的第一篇文章介紹了 如何使用 iptables/nftables 的報文跟蹤功能 來定位 NAT 相關(guān)的連接問題。作為第二部分,本文介紹 conntrack 命令,它允許你查看和修改被跟蹤的連接。

引言
通過 iptables 或 nftables 配置的 NAT 建立在 netfilters 連接跟蹤子系統(tǒng)之上。conntrack 命令作為 “conntrack-tools” 軟件包的一部分,用于查看和更改連接狀態(tài)表。
連接跟蹤狀態(tài)表
連接跟蹤子系統(tǒng)會跟蹤它看到的所有報文流。運行 sudo conntrack -L 可查看其內(nèi)容:
tcp 6 43184 ESTABLISHED src=192.168.2.5 dst=10.25.39.80 sport=5646 dport=443 src=10.25.39.80 dst=192.168.2.5 sport=443 dport=5646 [ASSURED] mark=0 use=1
tcp 6 26 SYN_SENT src=192.168.2.5 dst=192.168.2.10 sport=35684 dport=443 [UNREPLIED] src=192.168.2.10 dst=192.168.2.5 sport=443 dport=35684 mark=0 use=1
udp 17 29 src=192.168.8.1 dst=239.255.255.250 sport=48169 dport=1900 [UNREPLIED] src=239.255.255.250 dst=192.168.8.1 sport=1900 dport=48169 mark=0 use=1
上述顯示結(jié)果中,每行表示一個連接跟蹤項。你可能會注意到,每行相同的地址和端口號會出現(xiàn)兩次,而且第二次出現(xiàn)的源地址/端口對和目標地址/端口對會與第一次正好相反!這是因為每個連接跟蹤項會先后兩次被插入連接狀態(tài)表。第一個四元組(源地址、目標地址、源端口、目標端口)記錄的是原始方向的連接信息,即發(fā)送者發(fā)送報文的方向。而第二個四元組則記錄的是連接跟蹤子系統(tǒng)期望收到的對端回復報文的連接信息。這解決了兩個問題:
- 如果報文匹配到一個 NAT 規(guī)則,例如 IP 地址偽裝,相應的映射信息會記錄在鏈接跟蹤項的回復方向部分,并自動應用于同一條流的所有后續(xù)報文。
- 即使一條流經(jīng)過了地址或端口的轉(zhuǎn)換,也可以成功在連接狀態(tài)表中查找到回復報文的四元組信息。
原始方向的(第一個顯示的)四元組信息永遠不會改變:它就是發(fā)送者發(fā)送的連接信息。NAT 操作只會修改回復方向(第二個)四元組,因為這是接受者看到的連接信息。修改第一個四元組沒有意義:netfilter 無法控制發(fā)起者的連接狀態(tài),它只能在收到/轉(zhuǎn)發(fā)報文時對其施加影響。當一個報文未映射到現(xiàn)有連接表項時,連接跟蹤可以為其新建一個表項。對于 UDP 報文,該操作會自動進行。對于 TCP 報文,連接跟蹤可以配置為只有 TCP 報文設(shè)置了 SYN 標志位 才新建表項。默認情況下,連接跟蹤會允許從流的中間報文開始創(chuàng)建,這是為了避免對啟用連接跟蹤之前就存在的流處理出現(xiàn)問題。
連接跟蹤狀態(tài)表和 NAT
如上一節(jié)所述,回復方向的四元組包含 NAT 信息。你可以通過命令過濾輸出經(jīng)過源地址 NAT 或目標地址 NAT 的連接跟蹤項。通過這種方式可以看到一個指定的流經(jīng)過了哪種類型的 NAT 轉(zhuǎn)換。例如,運行 sudo conntrack -L -p tcp –src-nat 可顯示經(jīng)過源 NAT 的連接跟蹤項,輸出結(jié)果類似于以下內(nèi)容:
tcp 6 114 TIME_WAIT src=10.0.0.10 dst=10.8.2.12 sport=5536 dport=80 src=10.8.2.12 dst=192.168.1.2 sport=80 dport=5536 [ASSURED]
這個連接跟蹤項表示一條從 10.0.0.10:5536 到 10.8.2.12:80 的連接。與前面示例不同的是,回復方向的四元組不是原始方向四元組的簡單翻轉(zhuǎn):源地址已修改。目標主機(10.8.2.12)將回復數(shù)據(jù)包發(fā)送到 192.168.1.2,而不是 10.0.0.10。每當 10.0.0.10 發(fā)送新的報文時,具有此連接跟蹤項的路由器會將源地址替換為 192.168.1.2。當 10.8.2.12 發(fā)送回復報文時,該路由器將目的地址修改回 10.0.0.10。上述源 NAT 行為源自一條 NFT 偽裝 規(guī)則:
inet nat postrouting meta oifname "veth0" masquerade
其他類型的 NAT 規(guī)則,例如目標地址 DNAT 規(guī)則或重定向規(guī)則,其連接跟蹤項也會以類似的方式顯示,回復方向四元組的遠端地址或端口與原始方向四元組的遠端地址或端口不同。
連接跟蹤擴展
連接跟蹤的記帳功能和時間戳功能是兩個有用的擴展功能。運行 sudo sysctl net.netfilter.nf_conntrack_acct=1 可以在運行 sudo conntrack -L 時顯示每個流經(jīng)過的字節(jié)數(shù)和報文數(shù)。運行 sudo sysctl net.netfilter.nf_conntrack_timestamp=1 為每個連接記錄一個開始時間戳,之后每次運行 sudo conntrack -L 時都可以顯示這個流從開始經(jīng)過了多少秒。在上述命令中增加 –output ktimestamp 選項也可以看到流開始的絕對時間。
插入和更改連接跟蹤項
你可以手動為狀態(tài)表添加連接跟蹤項,例如:
sudo conntrack -I -s 192.168.7.10 -d 10.1.1.1 --protonum 17 --timeout 120 --sport 12345 --dport 80
這項命令通常被 conntrackd 用于狀態(tài)復制,即將主防火墻的連接跟蹤項復制到備用防火墻系統(tǒng)。于是當切換發(fā)生的時候,備用系統(tǒng)可以接管已經(jīng)建立的連接且不會造成中斷。連接跟蹤還可以存儲報文的帶外元數(shù)據(jù),例如連接跟蹤標記和連接跟蹤標簽??梢杂酶逻x項(-U)來修改它們:
sudo conntrack -U -m 42 -p tcp
這條命令將所有的 TCP 流的連接跟蹤標記修改為 42。
刪除連接跟蹤項
在某些情況下,你可能想從狀態(tài)表中刪除條目。例如,對 NAT 規(guī)則的修改不會影響表中已存在流的經(jīng)過報文。因此對 UDP 長連接(例如像 VXLAN 這樣的隧道協(xié)議),刪除表項可能很有意義,這樣新的 NAT 轉(zhuǎn)換規(guī)則才能生效。可以通過 sudo conntrack -D 命令附帶可選的地址和端口列表選項,來刪除相應的表項,如下例所示:
sudo conntrack -D -p udp --src 10.0.12.4 --dst 10.0.0.1 --sport 1234 --dport 53
連接跟蹤錯誤計數(shù)
conntrack 也可以輸出統(tǒng)計數(shù)字:
# sudo conntrack -S
cpu=0 found=0 invalid=130 insert=0 insert_failed=0 drop=0 early_drop=0 error=0 search_restart=10
cpu=1 found=0 invalid=0 insert=0 insert_failed=0 drop=0 early_drop=0 error=0 search_restart=0
cpu=2 found=0 invalid=0 insert=0 insert_failed=0 drop=0 early_drop=0 error=0 search_restart=1
cpu=3 found=0 invalid=0 insert=0 insert_failed=0 drop=0 early_drop=0 error=0 search_restart=0
大多數(shù)計數(shù)器將為 0。Found 和 insert 數(shù)將始終為 0,它們只是為了后向兼容。其他錯誤計數(shù)包括:
invalid:報文既不匹配已有連接跟蹤項,也未創(chuàng)建新連接。insert_failed:報文新建了一個連接,但插入狀態(tài)表時失敗。這在 NAT 引擎在偽裝時恰好選擇了重復的源地址和端口時可能出現(xiàn)。drop:報文新建了一個連接,但是沒有可用的內(nèi)存為其分配新的狀態(tài)條目。early_drop:連接跟蹤表已滿。為了接受新的連接,已有的未看到雙向報文的連接被丟棄。error:icmp(v6) 收到與已知連接不匹配的 icmp 錯誤數(shù)據(jù)包。search_restart:查找過程由于另一個 CPU 的插入或刪除操作而中斷。clash_resolve:多個 CPU 試圖插入相同的連接跟蹤條目。
除非經(jīng)常發(fā)生,這些錯誤條件通常無害。一些錯誤可以通過針對預期工作負載調(diào)整連接跟蹤子系統(tǒng)的參數(shù)來降低其發(fā)生概率,典型的配置包括 net.netfilter.nf_conntrack_buckets 和 net.netfilter.nf_conntrack_max 參數(shù)??稍?nbsp;nf_conntrack-sysctl 文檔 中查閱相應配置參數(shù)的完整列表。
當報文狀態(tài)是 invalid 時,請使用 sudo sysctl net.netfilter.nf_conntrack_log_invalid=255 來獲取更多信息。例如,當連接跟蹤遇到一個所有 TCP 標志位均為 0 的報文時,將記錄以下內(nèi)容:
nf_ct_proto_6: invalid tcp flag combination SRC=10.0.2.1 DST=10.0.96.7 LEN=1040 TOS=0x00 PREC=0x00 TTL=255 ID=0 PROTO=TCP SPT=5723 DPT=443 SEQ=1 ACK=0
總結(jié)
本文介紹了如何檢查連接跟蹤表和存儲在跟蹤流中的 NAT 信息。本系列的下一部分將延伸討論連接跟蹤工具和連接跟蹤事件框架。
文章名稱:網(wǎng)絡(luò)地址轉(zhuǎn)換(NAT)之連接跟蹤工具
標題鏈接:http://m.fisionsoft.com.cn/article/cdjicji.html


咨詢
建站咨詢
