Firewall

nftables 橋接匹配本地數據包

  • October 8, 2020

我正在使用 Arch linux,並且我已經使用 bridge-utils 建立了一個網橋。現在我想防火牆它。我想丟棄一些通過該網橋的數據包,同時允許這台機器與網橋後面的機器自由通信。我通常通過匹配來處理這種情況iifname lo,但不幸的是它與我的數據包不匹配。

再次,希望更清楚

  • 我有兩台機器,masterslave
  • master有兩個乙太網卡。一個連接到我的網路的其餘部分,另一個連接到slave
  • 我希望master能夠發送任何東西slave
  • 我想過濾來自網路其餘部分的流量以slave開啟master

我想用 nftables 來做。你有什麼想法?

lo介面不是乙太網介面。它沒有鏈路層地址,當然也不能成為網橋的一部分。所以沒有辦法iifname lo永遠匹配。

網橋佈局的組織方式仍與 ip 佈局類似,但在第 2 層工作:交換(而不是路由)的乙太網幀將進入前向鏈。用於主機或來自主機的乙太網幀不會遍歷任何鏈(它們沒有在下面創建,因為它們在此案例中無用)。

假設網路是這樣的:

LAN <--------> eth0 master eth1 <--------> slave
                  (bridge0)

eth0eth1奴役bridge0

因此,通過主機上的一個唯一網橋,這個“空”nft 規則集足以隔離slave,同時允許master不受限制的 LAN 和 流量slave,只需使用前向鏈的丟棄策略即可。

#!/usr/sbin/nft -f

flush ruleset

table bridge forward {
   chain forward {
       type filter hook forward priority 0; policy drop;
   }
}

期望 ARP 雙向工作當然是正常的(否則slave將無法在 IP 級別做很多事情):

nft add rule bridge filter forward ether type arp accept

現在,如果允許 LAN ping slave,但不能相反:

nft add rule bridge filter forward oif eth1 ip protocol icmp icmp type echo-request accept
nft add rule bridge filter forward iif eth1 ip protocol icmp icmp type echo-reply accept

請注意,與 iptables 相比,在橋接級別使用 nftables 仍然有些限制(但更簡潔),因為截至目前還沒有 conntrack 集成。因此,據我所知,沒有可用的狀態防火牆。

因此,一些通常簡單的任務可能看起來很尷尬,例如:允許來自(可能是遠端)IP 的 ssh 203.0.113.3。它變成:允許雙向通信,除了從從站到 LAN 不允許的初始同步:

nft add rule bridge filter forward oif eth1 ip saddr 203.0.113.3 ip protocol tcp tcp dport 22 accept
nft add rule bridge filter forward iif eth1 ip daddr 203.0.113.3 ip protocol tcp tcp sport 22 tcp flags != syn accept

如果 上有多個網橋master,則可能必須調整規則和/或預設策略。


橋接層的狀態防火牆

更新:核心 5.3 使模組nf_conntrack_bridge在橋接層具有可用的 conntrack,從而允許有狀態的防火牆。警告,與舊的互動br_netfilter,通常在 Docker 環境中載入,可能會產生意想不到的結果。

有了這樣的核心和足夠新的nftables,用下面的這個規則集替換上面的規則將允許 ARP,並且只允許來自 IP 地址 203.0.113.3 的傳入ping或傳入ssh以有狀態的方式到達從站:它們的回復被自動允許. 從站仍然被禁止啟動除 ARP 之外的任何通信。該setctzone鍊是完全可選的:它允許通過分配不同的conntrack zone id 來將橋接 conntrack 條目與其他 conntrack 條目(例如:在 IP 路由層生成)分開跟踪,以避免在非常奇特的設置中發生衝突條目。

table bridge isolateslave
delete table bridge isolateslave

table bridge isolateslave {
       chain setctzone {
               type filter hook prerouting priority -300; policy accept;
               ether type ip ct zone set 10
       }

       chain forward {
               type filter hook forward priority 0; policy drop;
               ether type arp accept
               ct state established,related accept
               ct state invalid drop
               oif "eth1" ip saddr 203.0.113.3 tcp dport 22 accept
               oif "eth1" icmp type echo-request accept
       }
}

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