Nftables

nftables 目標 nat 阻止本地訪問埠

  • November 5, 2020

我已經在我的伺服器上設置了 nftables,我想將所有進入某些受保護埠(例如 80)的流量重定向到更高的埠,該埠無需 root 權限(例如 13080)。我希望只能遠端訪問 80 個,但本地訪問兩個埠。這是我想出的設置:

#!/usr/bin/nft -f

flush ruleset

table inet firewall {

   chain inbound {
       type filter hook input priority filter; policy drop;

       ct status dnat counter accept # accept everything that came through destination nat (port 80)

       iifname lo counter accept
       oifname lo counter accept

       ct state { established, related } counter accept
       ct state invalid counter drop

       tcp dport 22 ct state new counter accept

       counter reject with icmpx type port-unreachable # reject everything else
   }

   chain destination-nat {
       type nat hook prerouting priority dstnat; policy accept
       tcp dport 80 counter redirect to 13080 # redirect 80 to 13080
   }

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

   chain outbound {
       type filter hook output priority 0; policy accept;
   }
}

但是,由於某種原因,這會阻止對埠 80 的本地訪問(儘管仍然可以訪問 13080)。有人可以告訴我我做錯了什麼嗎?

這是Netfilter 和 General Networking 中的數據包流範例,它對 nftables保持有效:

Netfilter 和通用網路中的數據包流

寫了一個重要的細節:*“nat”表僅用於“NEW”連接

對於本地啟動的連接,新連接的第一個數據包在輸出期間創建一個 NEW conntrack 狀態(輸出的 conntrack 框)。當這個連接被環回(在幾乎所有情況下通過lo介面)時,當數據包通過預路由(另一個 conntrack 框)返回時,相同的 conntrack 狀態匹配:本地環回連接沒有兩個 conntrack 狀態。

對於其他情況,新連接的第一個數據包通過預路由(預路由的 conntrack 框)到達並導致創建新的 conntrack 狀態。

因此,當發送連接的第一個環回數據包時,會在輸出期間創建一個新的 conntrack 條目,當該數據包通過預路由返回時,它匹配現有的 conntrack 條目:不再是新狀態。NAT 掛鉤(即 nat/prerouting 鏈destination-nat)不會被遍歷,因此不會影響此連接:在輸出步驟期間錯過了機會。

相反,在 nat/output 中使用dnat語句將有一個 NEW conntrack 狀態將解決這種情況。由於預設情況下它會影響任何本地啟動的連接(即甚至到 Internet),因此必須注意僅將其用於保持本地的連接:通過lo介面。這條鍊和規則將做到這一點:

nft add chain inet firewall loopback-nat '{ type nat hook output priority -100; policy accept; }'
nft add rule inet firewall loopback-nat oif lo tcp dport 80 counter redirect to :13080

您只需conntrack在事件模式下在其他地方執行命令即可遵循該行為:

conntrack -E -p tcp --dport 80

並查看從外部發起的連接和本地發起的環回連接的區別,無論有沒有這個附加鏈。請記住,nat鉤子只會看到與[NEW]狀態一起顯示的條目(並且已經相應地更改了命令顯示的條目)。

引用自:https://unix.stackexchange.com/questions/618229