使用 nftables 創建動態黑名單
我想用 nftables 創建一個動態黑名單。在嵌入式設備上的 0.8.3 版本下,我使用 nft list 規則集創建了一個如下所示的規則集:
table inet filter { set blackhole { type ipv4_addr size 65536 flags timeout } chain input { type filter hook input priority 0; policy drop; ct state invalid drop ct state established,related accept iif "lo" accept ip6 nexthdr 58 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-request, echo-reply, mld-listener-query, mld-listener-report, mld-listener-done, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, ind-neighbor-solicit, ind-neighbor-advert, mld2-listener-report } accept ip protocol icmp icmp type { echo-reply, destination-unreachable, echo-request, router-advertisement, router-solicitation, time-exceeded, parameter-problem } accept ip saddr @blackhole counter packets 0 bytes 0 drop tcp flags syn tcp dport ssh meter flood { ip saddr timeout 1m limit rate over 10/second burst 5 packets} set add ip saddr timeout 1m @blackhole drop tcp dport ssh accept } chain forward { type filter hook forward priority 0; policy drop; } chain output { type filter hook output priority 0; policy accept; } }
對我來說,這只是一個臨時解決方案。我想使用官方手冊頁中的範例進行動態黑名單。如果我使用手冊頁中的官方範例,我的 nftables 文件如下所示:
table inet filter { set blackhole{ type ipv4_addr flags timeout size 65536 } chain input { type filter hook input priority 0; policy drop; # drop invalid connections ct state invalid drop # accept traffic originating from us ct state established,related accept # accept any localhost traffic iif lo accept # accept ICMP ip6 nexthdr 58 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-request, echo-reply, mld-listener-query, mld-listener-report, mld-listener-done, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, ind-neighbor-solicit, ind-neighbor-advert, mld2-listener-report } accept ip protocol icmp icmp type { destination-unreachable, router-solicitation, router-advertisement, time-exceeded, parameter-problem, echo-request, echo-reply } accept # accept SSH (port 22) ip saddr @blackhole counter drop tcp flags syn tcp dport ssh meter flood { ip saddr timeout 10s limit rate over 10/second} add @blackhole { ip saddr timeout 1m } drop tcp dport 22 accept } chain forward { type filter hook forward priority 0; policy drop; } chain output { type filter hook output priority 0; policy accept; } }
但是,當我使用 nft -f myfile 在版本 0.8.3 上傳入此 nftables 文件時,我收到此錯誤:
Error: syntax error, unexpected add, expecting newline or semicolon tcp flags syn tcp dport ssh meter flood { ip saddr timeout 10s limit rate over 10/second} add @blackhole { ip saddr timeout 1m } drop
我不知道為什麼會這樣,但根據wiki,它應該從 0.8.1 版和核心 4.3 版開始工作。
我有版本 0.8.3 和核心 4.19.94。
我已經在 Debian Buster 下測試了官方手冊頁中 0.9.0 版的規則集。手冊頁中的規則集適用於 Debian,但 ip 僅被阻止一次。
在這個例子中,我想創建一個防火牆規則,如果對我的設備啟動暴力攻擊,它會阻止 ssh 埠上的 ip 地址。但我想阻止 ip 例如 5 分鐘。在那之後,應該可以從攻擊者的 ip 再次連接到設備。如果他再次進行暴力破解,則應再次阻止 ip 5 分鐘,依此類推。如果可以使用 nftables,我想避免為我的嵌入式設備使用其他軟體,如 sshguard 或 fail2ban。
我希望任何人都可以幫助我。謝謝!
該
hydra
工具同時多次連接到 SSH 伺服器。在 OP 的情況下(comment :hydra -l <username> -P </path/to/passwordlist.txt> -I -t 6 ssh://<ip-address>
)它將使用 6 個並發執行緒連接。根據伺服器設置,一個連接通常可以嘗試 5 或 6 個密碼,並且在被 SSH 伺服器拒絕之前大約需要 10 秒,所以我看不到如何超過每秒10 次連接嘗試的速率(但就是這種情況) . 這可能意味著觸發的是超過 5 次連接嘗試在不到 1/2 秒內完成。我不太相信 的準確性
10/s
,但可以假設它發生在這裡。版本和語法問題
不適用於 0.8.1 或 0.8.3 版本的語法是此送出中出現的較新語法:
src:重新訪問語法以從數據包路徑更新集合和映射
對於集合,我們允許這樣做:
nft add rule x y ip protocol tcp update @y { ip saddr}
$$ … $$
它是在 0.8.3 版之後送出的,因此僅適用於 nftables >= 0.8.4
在同一頁面中,從數據包路徑更新集的目前 wiki 修訂版仍顯示具有前一種語法的命令
% nft add rule filter input set add ip saddr @myset
$$ … $$
並以較新的語法顯示結果:
$$ … $$
add @myset { ip saddr }
$$ … $$
某些 wiki 頁面或最新的聯機幫助頁可能不適用於較舊的 nftables 版本。
無論如何,如果使用核心 4.19 執行,應首選*nftables >= 0.9.0 以獲得附加功能。*例如,它在Debian 10或Debian 9 backports中可用。
黑名單應該在有狀態的接受規則之前完成
一旦 IP 被添加到黑名單中,這並不會阻止已建立的連接繼續進行,不受阻礙和無人問津,直到它們被 SSH 伺服器本身斷開連接。那是因為之前通常存在短路規則:
# accept traffic originating from us ct state established,related accept
此評論具有誤導性:它不接受來自我們的流量,但任何流量已經在進行。這是一個短路規則。它的作用是通過只為新連接解析所有規則來處理有狀態的連接:此規則之後的任何規則都適用於新連接。一旦連接被接受,它們各自的數據包就會一直被接受,直到連接結束。
對於黑名單處理的具體案例,應將具體的黑名單規則或其中的一部分放在這條短路規則之前,以便能夠立即生效。在OP的情況下是:
ip saddr @blackhole counter drop
它應該在
ct state established,related accept
規則之前移動。現在,一旦將攻擊者添加到黑名單中,其他正在進行的連接將無法獲得一些剩餘的免費嘗試來猜測密碼:它們將立即掛起。
如果有黑名單,請考慮白名單
作為旁注,廉價
iif lo accept
規則本身可以作為優化和列入白名單之前移動:所有(甚至長期存在的)本地建立的連接現在也將被列入黑名單,以防濫用(例如:從 127.0.0.1 開始) . 考慮在規則前添加各種白名單規則@blackhole
。可選擇更快地警告應用程序
為了防止來自伺服器的持續回復到達黑名單 IP(特別是對於 UDP 流量,對 TCP,包括 SSH 沒有多大用處),
daddr
也可以在inet filter output
鏈中添加等效規則 using,拒絕以更快地通知本地程序試圖發出它們應該中止的資訊:ip daddr @blackhole counter reject
集合之間的差異
add
和update
應用於集合現在有了這樣的設置,即使正在進行的連接立即停止,攻擊者也能夠繼續嘗試並在 1 百萬之後獲得一個新的短視窗,這不是最佳的。
條目必須在輸入規則中*更新。*如果條目已經存在,將刷新計時器,而什麼也不做。這將繼續阻止任何進一步(不成功)連接到 SSH 伺服器的嘗試,直到攻擊者放棄,打開視窗為零。(我上面添加的輸出規則不應該改變,這不是攻擊者的行為):
@blackhole ... drop``update``add
代替:
ip saddr @blackhole counter drop
with(仍然保留舊語法):
ip saddr @blackhole counter set update ip saddr timeout 1m @blackhole drop
它甚至應該在
ct state invalid
規則之前移動,否則如果攻擊者嘗試無效數據包(例如 TCP 數據包不是已知連接的一部分,例如來自已經忘記的連接的延遲 RST),則該集合將不會被更新,而它本來可以更新。限制已建立連接的最大數量
需要核心 >= 4.18 和 nftables >= 0.9.0,因此無法使用 OP 的目前配置完成。
攻擊者可能會發現它不能一次連接太多次,但只要連接速度不要太快,它仍然可以無限制地繼續添加新連接。
還可以使用其他計量規則添加對並發連接的限制(可用於 iptables ):
connlimit
tcp flags syn tcp dport 22 meter toomanyestablished { ip saddr ct count over 3 } reject with tcp reset
將允許任何給定的 IP 地址只有 3 個已建立的 SSH 連接。
或者,同時觸發 @blackhole 集(這次使用更新的語法):
tcp flags syn tcp dport 22 meter toomanyestablished { ip saddr ct count over 3 } add @blackhole { ip saddr timeout 1m } drop
在 OP 的情況下,這甚至應該在之前的計量規則之前觸發。小心使用以避免合法使用者受到影響(但請參閱 openssh 的
ControlMaster
選項)。IPv4 和 IPv6
由於沒有通用的 IPv4+IPv6 集地址類型,所有處理 IPv4 的規則(只要有 2 個字母 word
ip
)可能應該複製到ip6
其中包含並處理 IPv6 集的鏡像規則中。