阻止過時的 tcp 選項
在 Linux 上,我想丟棄所有包含任何過時 tcp 選項的數據包。過時的選項是指所有那些 tcp 選項種類編號高於 8 的選項。我該如何使用
nftables
?例如,如果有一種方法可以檢查 tcp 數據包是否具有 nftables 中給定數字類型的選項,那將起作用。如果 nftables 不支持這個,我可以使用
tc
或其他標準的 linux 實用程序來做到這一點嗎?
nftables中的許多關鍵字只代表一個常數。tcp 選項就是這種情況(更新:但僅從nftables 0.9.8 開始)。
這是 tcp 選項的摘錄:
擴展標頭表達式是指來自可變大小協議標頭的數據,例如 IPv6 擴展標頭和 TCP 選項。
$$ … $$ tcp 選項
{eol | noop | 最大賽格 | 視窗 | 允許麻袋| 高解析度照片| CLIPARTO 麻袋 | 麻袋0 | 麻袋1 | 麻袋2 | 麻袋3 | 時間戳} tcp_option_field
TCP 選項
$$ … $$ 布爾規範
以下表達式支持布爾比較:
$$ … $$
# match if TCP timestamp option is present filter input tcp option timestamp exists
這裡
eol
代表 0,nop
代表 1,…timestamp
代表 8,等等。更新:從 0.9.8 版開始,可以指定任意數值而不是關鍵字:
- 添加原始 tcp 選項匹配支持
… tcp 選項@42,16,4
您可以在其中指定@kind,offset,length
- 允許檢查是否存在任何 tcp 選項
… tcp 選項 42 存在
所以有了這種規則:
nft add table t nft add chain t c '{ type filter hook input priority 0; policy accept; }' nft add rule t c tcp option 8 exists drop nft add rule t c tcp option 9 exists drop nft add rule t c tcp option 10 exists drop [...] nft add rule t c tcp option 254 exists drop
可以過濾所有值為 8 的規則(包括在內以稍後顯示 8 表示
timestamp
)或更高(選項值在 8 位欄位上)。已知值(僅此處
timestamp
)與關鍵字一起顯示,否則它們保持為數字:# nft -a --debug=netlink list ruleset ip t c 2 [ exthdr load tcpopt 1b @ 8 + 0 present => reg 1 ] [ cmp eq reg 1 0x00000001 ] [ immediate reg 0 drop ] ip t c 3 2 [ exthdr load tcpopt 1b @ 9 + 0 present => reg 1 ] [ cmp eq reg 1 0x00000001 ] [ immediate reg 0 drop ] ip t c 4 3 [ exthdr load tcpopt 1b @ 10 + 0 present => reg 1 ] [ cmp eq reg 1 0x00000001 ] [ immediate reg 0 drop ] ip t c 5 4 [ exthdr load tcpopt 1b @ 254 + 0 present => reg 1 ] [ cmp eq reg 1 0x00000001 ] [ immediate reg 0 drop ] table ip t { # handle 21 chain c { # handle 1 type filter hook input priority filter; policy accept; tcp option timestamp exists drop # handle 2 tcp option 9 exists drop # handle 3 tcp option 10 exists drop # handle 4 tcp option 254 exists drop # handle 5 } }
我沒有找到將其分解為集合或映射的方法,也沒有與選項值進行比較,這會簡化這一點,因為整個
tcp option foo
語法必須使用,而不僅僅是tcp option
,據我所知,這會導致無用特點:
- 檢查選項 timestamp 是否意味著kind 8的 kind 值為… 8。(如果存在則始終為 true,因此等價於
tcp option timestamp exists
):nft add rule t c tcp option timestamp kind == 8
- 或檢查選項時間戳是否意味著種類 8的種類值大於 8(始終為假):
nft add rule t c 'tcp option timestamp kind > 8'
考慮到tcp 選項是選項列表的一部分,我可以理解實現並不是那麼容易,因為它必須遍歷所有現有選項才能選擇一個。當兩個可以匹配時會選擇哪個?
注意:8 個以上的選項值得保留。例如tcp option kind 30用於MPTCP,它最近被添加到主流 Linux 中,而 tcp options kind 6 (echo) 和 7 (echo reply) 已過時。