Linux

何時以及如何在 nftables 中使用鏈優先級

  • July 3, 2020

在 nftables 中配置鏈時,必須提供一個priority值。幾乎所有線上範例都將a設置piority為0;有時,值 100 與某些鉤子 ( output, postrouting) 一起使用。

nftables wiki不得不說

優先級可用於對鏈進行排序或將它們放在某些 Netfilter 內部操作之前或之後。例如,優先級為 -300 的 prerouting 鉤子上的鏈將被放置在連接跟踪操作之前。

作為參考,以下是 iptables 中使用的不同優先級的列表:

  • NF_IP_PRI_CONNTRACK_DEFRAG (-400):碎片整理的優先級
  • NF_IP_PRI_RAW (-300):在連接跟踪操作之前放置的原始表的傳統優先級
  • NF_IP_PRI_SELINUX_FIRST (-225):SELinux 操作
  • NF_IP_PRI_CONNTRACK (-200):連接跟踪操作
  • NF_IP_PRI_MANGLE (-150): 破壞操作
  • NF_IP_PRI_NAT_DST (-100):目標 NAT
  • NF_IP_PRI_FILTER(0):過濾操作,過濾表
  • NF_IP_PRI_SECURITY (50):例如可以設置secmark的安全表位置
  • NF_IP_PRI_NAT_SRC (100):源 NAT
  • NF_IP_PRI_SELINUX_LAST (225):SELinux 在數據包出口
  • NF_IP_PRI_CONNTRACK_HELPER (300):退出時的連接跟踪

這表明priority控制與內部 Netfilter 操作的互動,但僅提及 iptables 使用的值作為範例。

在哪些情況下是priority相關的(即必須設置為值≠ 0)?僅適用於具有相同鉤子的多個鏈條?結合 nftables 和 iptables 怎麼樣?哪些內部 Netfilter 操作與確定正確priority值相關?

更新:(iptables-nft而不是iptables-legacy)正在使用nftables核心 API 和另外一個兼容層來重用xtables核心模組(在 中描述的那些iptables-extensions),當沒有可用的本機nftables翻譯時。在大多數情況下,它應該被視為nftables,除了這個問題,它像舊版本一樣具有固定的優先級,因此nftables的優先級在這裡仍然很重要。


iptables (legacy) 和nftables都依賴於相同的 netfilter 基礎設施,並在不同的地方使用鉤子。它在那裡解釋:Netfilter hooks,或者有這個systemtap manpage,它記錄了一些鉤子處理:

PRIORITY 是一個整數優先級,給出了觸發探測點相對於在同一數據包上觸發的任何其他 netfilter 掛鉤函式的順序。鉤子函式在每個數據包上按從最小優先級到最大優先級的順序執行。

$$ … $$

或者這個關於 netfilter 的部落格:How to Filter Network Packets using Netfilter–Part 1 Netfilter Hooks (部落格消失了,改用Wayback Machine連結。)

所有這些共同表明,各種模組/功能可以在五個可能的鉤子中的每一個上註冊(對於 IPv4 情況),並且在每個鉤子中,它們將按照該鉤子的註冊優先級順序被呼叫。

這些鉤子不僅適用於iptablesnftables。還有各種其他使用者,例如上面的 systemtap,甚至是 netfilter 自己的子模組。例如,當使用 iptables 或 nftables 使用 NAT 時,使用 IPv4,nf_conntrack_ipv4在 4 個不同優先級的鉤子中註冊總共 6 次。該模組將依次拉取位於和nf_defrag_ipv4的寄存器。NF_INET_PRE_ROUTING/NF_IP_PRI_CONNTRACK_DEFRAG NF_INET_LOCAL_OUT/NF_IP_PRI_CONNTRACK_DEFRAG

所以是的,優先級僅在同一個鉤子中相關。但是在同一個鉤子中,有幾個使用者,並且他們已經有了預定義的優先級(通常但不總是在不同的鉤子中重用相同的值),因此要圍繞它們正確互動,必須使用兼容的優先級。

例如,如果必須儘早對未碎片整理的數據包執行規則,然後(像往常一樣)使用碎片整理的數據包,只需在預路由中註冊兩個nftables鏈,一個 <= -401(例如-450),另一個在-399和之間-201(例如-300)。直到最近, iptables可以做的最好的事情是-300,即它在 conntrack 時看不到碎片數據包,因此使用了早期碎片整理(因為核心 4.15 帶有選項raw_before_defrag,它將註冊在-450,但不能同時做,但iptables-nft不會出現提供這樣的選擇)。


所以現在關於nftablesiptables之間的互動:兩者可以一起使用,除了舊核心中的 NAT,它們都競爭 netfilter 的 nat 資源:只有一個應該註冊 nat,除非使用核心 >= 4.18,如維基範例nftables設置與 iptables 具有相同的優先級,但差異很小。

如果iptablesnftables一起使用並且一個應該在另一個之前使用,因為需要互動和效果順序,只需相應地稍微降低或增加nftables的優先級,因為iptables ’ 不能更改。

例如,在大多數iptables設置中,可以使用具有iptables中不可用的特定匹配功能的nftables來標記數據包,然後在iptables中處理此標記,因為它支持特定目標(例如花哨的iptables LED目標閃爍一個 LED)在nftables中不可用。只需為nftables鉤子註冊一個稍低的優先級值,以確保它之前完成。對於通常的輸入過濾器規則,例如而不是. 再說一次,這個值不應該低於,否則它將在iptables之前執行-5``0``-149’ INPUT mangle 鏈,這可能不是預期的。這是在輸入情況下唯一重要的其他低值。例如,沒有NF_IP_PRI_CONNTRACK要考慮的門檻值,因為conntrack不會在此優先級中註冊某些內容,如果與此相關的某些內容確實重要,SELinux 也不會在此掛鉤中註冊某些內容,因此NF_INET_LOCAL_IN這裡沒有-225特殊含義。

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