Nftables
簡化 nftables(網路過濾表)規則
我有一個有效的 nftables 規則集。但是它很長,並且有很多重複的程式碼:
- ip4 和 ip6 完全相同(只是幾個字元不同)重複。
- 規則鏈,分支成幾乎相同的分支。我覺得一些布爾邏輯在這裡會有所幫助。
如何減少重複程式碼,使這個規則集更簡潔?
我正在嘗試各種事情,然後意識到我可以像下面那樣做,但這讓我的程序員感到骯髒。它有太多重複的程式碼。
#!/usr/sbin/nft -f table ip vnc_table {}; table ip6 vnc_table {}; flush table ip vnc_table; flush table ip6 vnc_table; table ip vnc_table { # 3 near identical sets set richardports { type inet_service; flags interval; elements = { 5910-5919 }; } set henryports { type inet_service; flags interval; elements = { 5920-5929 }; } set sholaports { type inet_service; flags interval; elements = { 5930-5939 }; } chain output { type filter hook output priority 0; policy accept; ip daddr 127.0.0.1 jump localhost; } chain localhost { tcp dport @richardports jump richard_chain; tcp dport @henryports jump henry_chain; tcp dport @sholaports jump shola_chain; } # 3 near identical chains chain richard_chain { skuid "richard" accept; reject; } chain henry_chain { skuid "henry" accept; reject; } chain shola_chain { skuid "shola" accept; reject; } } #then we do it all again for ip6 table ip6 vnc_table { set richardports { type inet_service; flags interval; elements = { 5910-5919 }; } set henryports { type inet_service; flags interval; elements = { 5920-5929 }; } set sholaports { type inet_service; flags interval; elements = { 5930-5939 }; } chain output { type filter hook output priority 0; policy accept; ip6 daddr ::1 jump localhost; } chain localhost { tcp dport @richardports jump richard_chain; tcp dport @henryports jump henry_chain; tcp dport @sholaports jump shola_chain; } chain richard_chain { skuid "richard" accept; reject; } chain henry_chain { skuid "henry" accept; reject; } chain shola_chain { skuid "shola" accept; reject; } }
將 IPv4 和 IPv6 連接在一起
將家庭ip和ip6的表加入到家庭**inet的單個表中:
- 刪除整個ip6 vnc_table表
- 將ip vnc_table表更改為inet vnc_table表
Family inet可以同時處理 IPv4 和 IPv6,並且在需要時仍然可以接受特定的 IPv4 或 IPv6 規則。所以替換:
table ip vnc_table {
和:
table inet vnc_table {
- 調整之前的沖洗
在回答這個問題時,我發現這
flush table
不足以重新載入規則(我不得不修改我對這個主題的回答):如文件所述,它將“刷新指定表的所有鍊和規則”。但不會刪除這些對象本身,從而導致剩餘或衝突的對象。delete table
應該改用:delete table inet vnc_table
當然ip vnc_table和ip6 vnc_table表應該手動刪除一次:
# nft delete table ip vnc_table # nft delete table ip6 vnc_table
- 添加現在缺少的 ip6 規則,以便 IPv4 和 IPv6 localhost 都匹配
nft add inet vnc_table output ip6 daddr ::1 jump localhost
需要流血邊緣才能做得更好
為了更進一步,這些集合必須以不同的方式組織,但只有在 2020年 4 月 1 日發布的 nftables 0.9.4和 libnftnl 1.1.6中才解除了一個錯誤/限制,同時還需要核心 5.6:
- 支持串聯範圍(需要 Linux 核心 >= 5.6),
如果沒有這些版本,nftables 將無法接受包含範圍(此處為埠範圍)的串聯。在處理以下規則集時,僅使用核心 5.5 而不是 5.6 會導致分段錯誤(這可以說是一個錯誤):核心也是必需的。
所以做了兩套:第一套是告訴哪些埠範圍被過濾了,需要特殊處理。第二個(仍然必須重新包含以前的埠範圍)是埠範圍和使用者 ID 的串聯。將根據數據包檢查這兩個屬性:如果存在埠 + 使用者關聯,則將被接受,否則對於那些過濾的埠,數據包將被拒絕。
結果:
table inet vnc_table delete table inet vnc_table table inet vnc_table { set filteredport { type inet_service flags interval elements = { 5910-5919, 5920-5929, 5930-5939 } } set portuser { type inet_service . uid flags interval elements = { 5910-5919 . "richard", 5920-5929 . "henry", 5930-5939 . "shola" } } chain output { type filter hook output priority filter; policy accept; ip daddr 127.0.0.1 jump localhost ip6 daddr ::1 jump localhost } chain localhost { tcp dport @filteredport jump portuser_chain } chain portuser_chain { tcp dport . meta skuid @portuser accept reject with tcp reset } }
筆記: