Iptables

iptables/nftables:如何從路由器上的連接跟踪中排除所有轉發的流量?

  • October 5, 2021

Linux 機器有多個網路介面。為 IPv4 和 IPv6 啟用了 IP 轉發。

我想通過狀態防火牆保護在路由器本身上執行的服務。為此,需要啟用連接跟踪。同時,我想從連接跟踪中排除從一個介面轉發到另一個介面的所有流量。

對於有狀態防火牆,我通常會使用過濾表的 INPUT 和 OUTPUT 鏈。轉發的流量將進入 FORWARD 鏈。但是 AFAIK 無法在 FORWARD 鏈中將流量標記為未跟踪。這樣的邏輯必須進入原始表中的 PREROUTING 鏈。但是,我相信,在 PREROUTING 鏈中,還沒有決定是否轉發流量。

連接跟踪有許多缺點,例如當跟踪的連接列表達到其最大大小時會失去數據包。

從連接跟踪中排除轉發流量(並且僅轉發流量)的最簡單方法是什麼?

對於通用規則集,可以使用表達式提前要求nftablesfib進行路由查找,而不是等待路由堆棧進行。這允許涉及(未來的)輸出介面,儘管它還不存在(路由決定沒有發生),但代價是額外的查找。然後,如果結果告訴數據包將被路由,則使用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條目或抬頭。

  • 標準規則集

然後可以照常執行使用iptablesnftables (在其自己的不同表中)的實際規則,包括主機本身的有狀態規則。由於路由流量不會創建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*條目,但不會為路由流量創建。

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