iptables/nftables:如何從路由器上的連接跟踪中排除所有轉發的流量?
Linux 機器有多個網路介面。為 IPv4 和 IPv6 啟用了 IP 轉發。
我想通過狀態防火牆保護在路由器本身上執行的服務。為此,需要啟用連接跟踪。同時,我想從連接跟踪中排除從一個介面轉發到另一個介面的所有流量。
對於有狀態防火牆,我通常會使用過濾表的 INPUT 和 OUTPUT 鏈。轉發的流量將進入 FORWARD 鏈。但是 AFAIK 無法在 FORWARD 鏈中將流量標記為未跟踪。這樣的邏輯必須進入原始表中的 PREROUTING 鏈。但是,我相信,在 PREROUTING 鏈中,還沒有決定是否轉發流量。
連接跟踪有許多缺點,例如當跟踪的連接列表達到其最大大小時會失去數據包。
從連接跟踪中排除轉發流量(並且僅轉發流量)的最簡單方法是什麼?
對於通用規則集,可以使用表達式提前要求nftables
fib
進行路由查找,而不是等待路由堆棧進行。這允許涉及(未來的)輸出介面,儘管它還不存在(路由決定沒有發生),但代價是額外的查找。然後,如果結果告訴數據包將被路由,則使用notrack
語句防止跟踪發生。FIB 表達式
fib {saddr | daddr | mark | iif | oif} [. ...] {oif | oifname | type}
fib表達式查詢fib(轉發資訊庫)以獲取資訊,例如特定地址將使用的輸出介面索引。輸入是元素的元組,用作fib查找函式的輸入。
不跟踪聲明
notrack 語句允許禁用某些數據包的連接跟踪。
notrack
請注意,要使此語句有效,必須在conntrack查找發生之前將其應用於數據包。因此,它需要位於具有預路由或輸出鉤子且鉤子優先級為 -300 或更低的鏈中。
因此,應該從prerouting進行“簡單”路由檢查,僅使用目標地址作為選擇器並檢查是否存在輸出介面(不可路由的數據包或用於主機的數據包不會解析任何內容)。lo (環回)介面有一個例外來保持跟踪:雖然它代表本地流量,但從主機發送到自身的數據包(通過輸出路徑)通過**預路由路徑返回,並且也有一個輸出介面lo。由於傳出數據包已經創建了一個conntrack條目,因此最好保持一致。
nft add table ip stateless nft add chain ip stateless prerouting '{ type filter hook prerouting priority -310; policy accept; }' nft add rule ip stateless prerouting iif != lo fib daddr oif exists notrack
ip
用組合系列替換inet
系列應該將相同的通用行為擴展到 IPv4+IPv6。更具體地說,可以指定未來的輸出介面,
fib daddr oif eth1
例如,它或多或少相當於oif eth1
,但也可用於預路由。當然,如果事先知道拓撲,則可以通過使用基於地址測試的一個或幾個規則來避免 FIB 查找,因為管理員會提前知道路由。可能需要對結果進行基準測試,以了解這是否比保留通用方法更有趣。
例如,使用 OP 提供的資訊,將之前的規則替換為:
nft add rule ip stateless prerouting 'ip daddr != { 192.168.1.1, 192.168.2.1, 127.0.0.0/8 } notrack'
應該有差不多的效果。127.0.0.0/8 存在的原因與上述lo介面相同。
處理廣播(如在eth0上接收到的 192.168.1.255 )和多播(如在介面上接收到的本地連結 224.0.0.1 )在這兩種方法中的工作方式可能不一樣,也不如預期的那樣,並且可能需要針對特定需求的額外規則,尤其是對於第二種方法。由於跟踪廣播和多播很少有用,因為回复源不會(也不能)是原始廣播或多播地址目標,因此 conntrack 條目永遠不會“看到”雙向流量,這通常無關緊要有狀態的規則。
筆記
- 這通常與有狀態 NAT 不兼容。
我的理解是,針對遠端主機的 DNAT 不會對其回复流量進行取消 NAT 並失敗,並且轉發的 SNAT 不會觸發,因為沒有創建conntrack條目。在輸入路徑中很少使用 SNAT 應該沒問題,並且 DNAT+SNAT 的組合(使用本地地址源)也可能工作,因為從那時起在原始和回複方向都涉及本地目標,因此應該始終正確創建conntrack條目或抬頭。
- 標準規則集
然後可以照常執行使用iptables或nftables (在其自己的不同表中)的實際規則,包括主機本身的有狀態規則。由於路由流量不會創建conntrack條目,因此涉及此類流量的任何規則都應堅持僅是無狀態的,並且不使用任何
ct
表達式,因為它永遠不會匹配。
- 驗證行為
即使沒有適當的防火牆規則,也可以通過以下方式檢查整體行為:
- 使用虛擬
ct
規則確保conntrack設施在目前網路命名空間中註冊。nft add table ip mytable nft add chain ip mytable mychain '{ type filter hook prerouting priority -150; policy accept; }' nft add rule ip mytable mychain ct state new
使用該[`conntrack`](https://conntrack-tools.netfilter.org/manual.html#conntrack)工具關注事件:
nntrack -E
從遠端生成流量 後將為路由器接收的流量創建新的*conntrack*條目,但不會為路由流量創建。