Networking

NAT 數據包在錯誤的網關上發出

  • December 5, 2021

我有兩個介面,比如說eth0eth0.4000vlan。兩者都有一個預設網關。當程序直接在介面上偵聽時,一切都按預期工作。

但不適用於hostPortKubernetes 的綁定。

vlan.gw-mac > eth0-mac,    ethertype 802.1Q (0x8100), length 78: vlan 4000, p 0, ethertype IPv4 (0x0800), clientIP.38712 > vlanIP.80: Flags [S]
eth0-mac    > eth0.gw-mac, ethertype IPv4   (0x0800), length 74:                                          vlanIP.80      > clientIP.38712: Flags [S.]

SYN 來自vlan.gateway,被轉發到容器,但 SYN-ACK 的答案離開了堆棧eth0.gw並且不正確vlan.gw,但 tcpdump 顯示 sourceIP 是vlanIP

路由表看起來不錯:

# ip route get to <clientIP> from <vlanIP> dev eth0.4000
<clientIP> from <vlanIP> via <vlan.gw> dev eth0.4000 table 1 uid 0

hostPort 映射是通過CNI-Plugin埠映射創建的,該映射使用 DNAT 和 SNAT(連結詳細資訊)。所以網關查找發生在早期。當我手動添加從容器 IP 到查找表 1 的路由時,它使用 vlan 介面工作,但會破壞 eth0。

所以問題是 - 在NAT 用 interface-ip 替換 container-ip之後發生路由需要做什麼?

你是對的,來自 DNAT 的隱式 SNAT 發生得太晚了:此時,路由決策已經做出,因此在錯誤的介面上使用了正確的源 IP。

為避免這種情況,您需要更深入地了解基於策略的路由。可以使用https://superuser.com/questions/638044/source-based-policy-routing-nat-dnat-snat-aka-multi-wans-on-centos-5中描述的技術。

為此,您需要在 mangle 表中包含 PREROUTING 鏈:

-A PREROUTING -i vlanIface -m state --state NEW,RELATED,ESTABLISHED -d <vlanIP> -j CONNMARK --set-mark 0x10/0x10
-A PREROUTING -m connmark --mark 0x10/0x10 -j CONNMARK --restore-mark --cfmask 0x10

這樣,所有屬於通過 vlanIface 發起的連接的數據包都將在其 fwmark 中設置 0x10。然後可以將其用於 PBR。假設您的 pod 網路是 10.0.0.0/8 並且您的輔助網關的表是 1:

ip rule add fwmark 0x10/0x10 from 10.0.0.0/8 table 1

您可能可以省略from 10.0.0.0/8,但它是防止錯誤設置 fwmarks 的有用安全網(例如,因為其他東西使用了特定標記)。

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