Linux

將我的 linux 配置為路由器,如何使用 nftables 啟用埠轉發?

  • June 23, 2021

我正在嘗試將我的 Gentoo Linux 配置為路由器。

這是我到目前為止的配置。

WAN網卡是enp3s0和LAN網卡是enp1s0f0

接受來自 LAN 的連接到 ICMP、tcp 埠 53、22、80、443、445、5900 和 udp 埠​​ 53、67、68

接受來自 WAN 的 SSH 埠 22 的連接

這些工作很好,我沒有做的是創建埠轉發。

我正在嘗試設置,如果埠 222 上的連接來自 WAN,則將其轉發到192.168.1.2埠上具有 ip 地址的機器22,此規則不會產生錯誤,但也不允許我連接。

這是我的配置:

table ip filter {
   chain input {
       type filter hook input priority filter; policy accept;
       ct state { established, related } accept
       iif "lo" accept
       iif "enp1s0f0" tcp dport { 22, 53, 80, 443, 445, 5900 } counter packets 0 bytes 0 log accept
       iif "enp3s0" tcp dport { 22 } counter packets 0 bytes 0 log accept
       iif "enp1s0f0" udp dport { 53, 67, 68 } accept
       iif "enp1s0f0" ip protocol icmp accept
       counter packets 1 bytes 259 drop
   }

   chain output {
       type filter hook output priority filter; policy accept;
       ct state { established, related, new } accept
       iif "lo" accept
   }

   chain forward {
       type filter hook forward priority filter; policy accept;
       iif "enp3s0" oif "enp1s0f0" ct state { established, related } accept
       iif "enp1s0f0" oif "enp3s0" accept
       iif "enp3s0" oif "enp1s0f0" counter packets 0 bytes 0 drop
   }

   chain postrouting {
       type filter hook postrouting priority filter; policy accept;
   }
}
table ip nat {
   chain postrouting {
       type nat hook postrouting priority srcnat; policy accept;
       oifname "enp3s0" masquerade
   }

   chain prerouting {
       type nat hook prerouting priority 100; policy accept;
       iif "enp3s0" tcp dport { 222 } dnat to 192.168.1.2:22  ### <- PORT FORWARDING RULE HERE
   }
}

我該如何糾正這個問題?

謝謝你。

一旦新流的第一個數據包(因此狀態為 NEW)遍歷nat 預路由鏈,dnat就會發生,並且隨著新的目的地數據包被路由並遍歷過濾器轉發鏈。

然後這條規則刪除它:

        iif "enp3s0" oif "enp1s0f0" counter packets 0 bytes 0 drop

需要一個允許第一個數據包(未處於已建立狀態)的規則。

這可以以第一種天真的方式插入到刪除規則之前:

iif "enp3s0" oif "enp1s0f0" ip daddr 192.168.1.2 tcp dport 22 accept

並且由於特定的拓撲:192.168.1.0/24 LAN 不可路由,因此預設情況下無法從 Internet 訪問,這可能就足夠了(從技術上講,下一跳路由器可以作弊並直接到達 192.168.1.2:22 NAT)。但是如果系統沒有做任何偽裝(並且有一個可路由的 LAN 而不是 192.168.1.0/24),這將使服務可以直接訪問。

實際上有一個更簡單和更安全的方法,如果其他一些埠也被dnat -ed 並且所有這些dnat規則都是允許的,那麼它也更通用:添加一個允許任何經過dnat轉換的數據包的規則。在等效的iptables-extensionsconntrack match中更詳細:

脫氧核糖核酸

一個虛擬狀態,如果原始目標與回复源不同,則匹配。

只需將其插入到最後一個丟棄規則之前的過濾器中:

ct status dnat accept

或者更準確地說:

iif enp3s0 oif enp1s0f0 ct status dnat accept

非常精確:

iif enp3s0 oif enp1s0f0 ct state new ct status dnat ip daddr 192.168.1.2 tcp dport 22 accept

此狀態只能因為先前對流執行的dnat規則而出現,因此它驗證意圖:接受。


筆記:

  • 沒有必要為不同的鉤子類型(filternat)使用不同的表,只要它是關於同一個系列(這裡是ip)。

這是從iptables繼承的一個習慣,可能會限制可能性。例如,集合的範圍是一個表。在過濾器鍊和nat鏈之間使用相同的集合要求它們位於同一個表中(定義集合的地方)。可悲的是,即使來自 wiki 的許多範例仍然使用模仿iptables的命名約定。

  • 雖然在這裡無關緊要,但nat 預路由的歷史優先級不是 100 而是 -100(又名dstnat)。

只有存在其他表也包括nat 預路由鏈,或者是否一起使用iptables nat規則(在這種情況下,建議使用 -101 或 -99 而不是 -100),以確定哪些規則需要優先級。

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