Linux中國

網路地址轉換(NAT)之連接跟蹤工具

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

引言

通過 iptables 或 nftables 配置的 NAT 建立在 netfilters 連接跟蹤子系統之上。conntrack 命令作為 「conntrack-tools」 軟體包的一部分,用於查看和更改連接狀態表。

連接跟蹤狀態表

連接跟蹤子系統會跟蹤它看到的所有報文流。運行 sudo conntrack -L 可查看其內容:

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

上述顯示結果中,每行表示一個連接跟蹤項。你可能會注意到,每行相同的地址和埠號會出現兩次,而且第二次出現的源地址/埠對和目標地址/埠對會與第一次正好相反!這是因為每個連接跟蹤項會先後兩次被插入連接狀態表。第一個四元組(源地址、目標地址、源埠、目標埠)記錄的是原始方向的連接信息,即發送者發送報文的方向。而第二個四元組則記錄的是連接跟蹤子系統期望收到的對端回復報文的連接信息。這解決了兩個問題:

  1. 如果報文匹配到一個 NAT 規則,例如 IP 地址偽裝,相應的映射信息會記錄在鏈接跟蹤項的回復方向部分,並自動應用於同一條流的所有後續報文。
  2. 即使一條流經過了地址或埠的轉換,也可以成功在連接狀態表中查找到回復報文的四元組信息。

原始方向的(第一個顯示的)四元組信息永遠不會改變:它就是發送者發送的連接信息。NAT 操作只會修改回復方向(第二個)四元組,因為這是接受者看到的連接信息。修改第一個四元組沒有意義:netfilter 無法控制發起者的連接狀態,它只能在收到/轉發報文時對其施加影響。當一個報文未映射到現有連接表項時,連接跟蹤可以為其新建一個表項。對於 UDP 報文,該操作會自動進行。對於 TCP 報文,連接跟蹤可以配置為只有 TCP 報文設置了 SYN 標誌位 才新建表項。默認情況下,連接跟蹤會允許從流的中間報文開始創建,這是為了避免對啟用連接跟蹤之前就存在的流處理出現問題。

連接跟蹤狀態表和 NAT

如上一節所述,回復方向的四元組包含 NAT 信息。你可以通過命令過濾輸出經過源地址 NAT 或目標地址 NAT 的連接跟蹤項。通過這種方式可以看到一個指定的流經過了哪種類型的 NAT 轉換。例如,運行 sudo conntrack -L -p tcp –src-nat 可顯示經過源 NAT 的連接跟蹤項,輸出結果類似於以下內容:

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 的連接。與前面示例不同的是,回復方向的四元組不是原始方向四元組的簡單翻轉:源地址已修改。目標主機(10.8.2.12)將回複數據包發送到 192.168.1.2,而不是 10.0.0.10。每當 10.0.0.10 發送新的報文時,具有此連接跟蹤項的路由器會將源地址替換為 192.168.1.2。當 10.8.2.12 發送回復報文時,該路由器將目的地址修改回 10.0.0.10。上述源 NAT 行為源自一條 NFT 偽裝 規則:

inet nat postrouting meta oifname "veth0" masquerade

其他類型的 NAT 規則,例如目標地址 DNAT 規則或重定向規則,其連接跟蹤項也會以類似的方式顯示,回復方向四元組的遠端地址或埠與原始方向四元組的遠端地址或埠不同。

連接跟蹤擴展

連接跟蹤的記帳功能和時間戳功能是兩個有用的擴展功能。運行 sudo sysctl net.netfilter.nf_conntrack_acct=1 可以在運行 sudo conntrack -L 時顯示每個流經過的位元組數和報文數。運行 sudo sysctl net.netfilter.nf_conntrack_timestamp=1 為每個連接記錄一個開始時間戳,之後每次運行 sudo conntrack -L 時都可以顯示這個流從開始經過了多少秒。在上述命令中增加 –output ktimestamp 選項也可以看到流開始的絕對時間。

插入和更改連接跟蹤項

你可以手動為狀態表添加連接跟蹤項,例如:

sudo conntrack -I -s 192.168.7.10 -d 10.1.1.1 --protonum 17 --timeout 120 --sport 12345 --dport 80

這項命令通常被 conntrackd 用於狀態複製,即將主防火牆的連接跟蹤項複製到備用防火牆系統。於是當切換髮生的時候,備用系統可以接管已經建立的連接且不會造成中斷。連接跟蹤還可以存儲報文的帶外元數據,例如連接跟蹤標記和連接跟蹤標籤。可以用更新選項(-U)來修改它們:

sudo conntrack -U -m 42 -p tcp

這條命令將所有的 TCP 流的連接跟蹤標記修改為 42。

刪除連接跟蹤項

在某些情況下,你可能想從狀態表中刪除條目。例如,對 NAT 規則的修改不會影響表中已存在流的經過報文。因此對 UDP 長連接(例如像 VXLAN 這樣的隧道協議),刪除表項可能很有意義,這樣新的 NAT 轉換規則才能生效。可以通過 sudo conntrack -D 命令附帶可選的地址和埠列表選項,來刪除相應的表項,如下例所示:

sudo conntrack -D -p udp  --src 10.0.12.4 --dst 10.0.0.1 --sport 1234 --dport 53

連接跟蹤錯誤計數

conntrack 也可以輸出統計數字:

# 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

大多數計數器將為 0。Foundinsert 數將始終為 0,它們只是為了後向兼容。其他錯誤計數包括:

  • invalid:報文既不匹配已有連接跟蹤項,也未創建新連接。
  • insert_failed:報文新建了一個連接,但插入狀態表時失敗。這在 NAT 引擎在偽裝時恰好選擇了重複的源地址和埠時可能出現。
  • drop:報文新建了一個連接,但是沒有可用的內存為其分配新的狀態條目。
  • early_drop:連接跟蹤表已滿。為了接受新的連接,已有的未看到雙向報文的連接被丟棄。
  • error:icmp(v6) 收到與已知連接不匹配的 icmp 錯誤數據包。
  • search_restart:查找過程由於另一個 CPU 的插入或刪除操作而中斷。
  • clash_resolve:多個 CPU 試圖插入相同的連接跟蹤條目。

除非經常發生,這些錯誤條件通常無害。一些錯誤可以通過針對預期工作負載調整連接跟蹤子系統的參數來降低其發生概率,典型的配置包括 net.netfilter.nf_conntrack_bucketsnet.netfilter.nf_conntrack_max 參數。可在 nf_conntrack-sysctl 文檔 中查閱相應配置參數的完整列表。

當報文狀態是 invalid 時,請使用 sudo sysctl net.netfilter.nf_conntrack_log_invalid=255 來獲取更多信息。例如,當連接跟蹤遇到一個所有 TCP 標誌位均為 0 的報文時,將記錄以下內容:

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

總結

本文介紹了如何檢查連接跟蹤表和存儲在跟蹤流中的 NAT 信息。本系列的下一部分將延伸討論連接跟蹤工具和連接跟蹤事件框架。

via: https://fedoramagazine.org/network-address-translation-part-2-the-conntrack-tool/

作者:Florian Westphal 選題:lujun9972 譯者:cooljelly 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的電子郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國