
我正在嘗試讓一些流量通過 VPN,而其他流量則不這樣做。
具有給定 fwmark 的封包應該發送至我的預設介面 ( wlo1
),所有其他流量都會傳送至tun0
主表中的隧道介面( ,使用 OpenVPN)。我在 nftables 中加入了這條規則:
table ip test {
chain test {
type route hook output priority mangle; policy accept;
meta cgroup 1234 meta mark set 1
}
}
在主路由表中,我有以下條目:
default via 10.11.0.1 dev tun0
10.11.0.0/16 dev tun0 proto kernel scope link src 10.11.0.20
[WANIP.0]/24 dev wlo1 proto kernel scope link src [WANIP]
128.0.0.0/1 via 10.11.0.1 dev tun0
[VPNIP] via [WANGATEWAY] dev wlo1
帶有 fwmark 的封包1
會被引導到它們自己的路由表:ip rule add from all fwmark 1 lookup test
。在test
表中我新增了以下路線:
default via [WANGATEWAY] dev wlo1
當我ping 8.8.8.8
從這個 cgroup 運行時,它被卡住了。它似乎能夠發送但無法接收任何資料包。
VPN 流量如預期運作。
究竟發生了什麼事?
答案1
當封包發出時,會做出路由決策:此決策選擇傳出接口和要使用的符合來源 IP 位址。
當。路線/輸出鏈條設定一個標記,它會觸發一個重新路由檢查,正如在此看到的示意圖(這是為iptables記住但完全可以用於nftables)。重新路由檢查會變更路由...但不會變更來源 IP 位址。因此還需要做更多的工作。
- 新增 NAT 規則以變更來源 IP 位址。
這是必須要做的後重新路由檢查,所以它是在NAT/後路由。請注意,同一個表可以有不同的鏈類型(與iptables其中表 <=> 型)。
nft add chain ip test testnat '{ type nat hook postrouting priority srcnat; policy accept; }'
nft add rule ip test testnat meta mark 1 masquerade
現在正確的資料包確實離開了。
- 並允許接受回復流,儘管未通過預設路由到達
你可以放鬆一下反向路徑轉送透過變更為鬆散模式
rp_filter
:sysctl -w net.ipv4.conf.wlo1.rp_filter=2
或標記回復流以使用與傳出流相同的路由表。它不會真正提高安全性,但無論如何:
nft add chain ip test testpre '{ type filter hook prerouting priority mangle; policy accept; }' nft add rule ip test testpre iif "wlo1" meta mark set 1
唉,如果沒有其他調整,這將無法工作,這是自新版本以來所需要的未記錄的功能2010年出現:
sysctl -w net.ipv4.conf.wlo1.src_valid_mark=1
筆記:
透過將標記儲存在 conntrack 中,可以在安全性方面做得更好康馬克(
ct mark
) 僅允許正確的回復流,不允許任何其他流繞過嚴格反向路徑轉送。在嚴格模式下,任何內容都不會通過wlo1除非它是來自傳出流量的回應。以下是完整對應的 nftables 規則檔案(在替換 nftables 規則時與上面的選項 2 一起使用):table ip test { chain test { type route hook output priority mangle; policy accept; meta cgroup 1234 meta mark set 1 ct mark set meta mark } chain testnat { type nat hook postrouting priority srcnat; policy accept; meta mark 1 masquerade } chain testpre { type filter hook prerouting priority mangle; policy accept; ct mark 1 meta mark set ct mark } }
此外,根據我在烏德範圍入口:https://kernelnewbies.org/Linux_4.10#Networking
如果您可以將 cgroups 用法轉換為一組有限的 uid,則可以僅使用路由堆疊(無需 netfilter 或 nftables)來正確完成此操作,
ip rule add ... uidrange ...
如上所述。請參閱我對此的回答:透過特定介面 (tum1) 路由用戶流量。