use*_*169 3 linux ssh firewall 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;
}
}
Run Code Online (Sandbox Code Playgroud)
对我来说,这只是一个临时解决方案。我想使用官方联机帮助页中的示例进行动态黑名单。如果我使用联机帮助页中的官方示例,我的 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;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当我使用 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
Run Code Online (Sandbox Code Playgroud)
我不知道为什么会这样,但根据维基,它应该可以在 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的情况下(评论:hydra -l <username> -P </path/to/passwordlist.txt> -I -t 6 ssh://<ip-address>),它会使用6个连接并发线程。
根据服务器设置,一个连接通常可以尝试 5 或 6 个密码,并且在被 SSH 服务器拒绝之前大约需要 10 秒,所以我看不出如何超过每秒10 次连接尝试的速率(但就是这样) . 这可能意味着触发的是在不到 1/2 秒的时间内完成了 5 次以上的连接尝试。我不会太相信 的准确性10/s,但可以假设它发生在这里。
不适用于 0.8.1 或 0.8.3 版本的语法是此提交中出现的较新语法:
src:重新访问语法以从数据包路径更新集合和映射
对于集合,我们允许这样做:
Run Code Online (Sandbox Code Playgroud)nft add rule x y ip protocol tcp update @y { ip saddr}[...]
它是在0.8.3 版本之后提交的,因此仅适用于 nftables >= 0.8.4
从数据包路径更新集的当前 wiki 修订版,在同一页面中,仍然显示具有以前语法的命令
Run Code Online (Sandbox Code Playgroud)% nft add rule filter input set add ip saddr @myset[...]
并使用较新的语法显示结果:
[...]
Run Code Online (Sandbox Code Playgroud)add @myset { ip saddr }[...]
某些 wiki 页面或最新的联机帮助页可能不适用于较旧的 nftables 版本。
无论如何,如果使用内核 4.19 运行,则应首选nftables >= 0.9.0 以获得附加功能。例如,它在Debian 10或Debian 9 backports 中可用。
将 IP 添加到黑名单后,这不会阻止已建立的连接继续、不受阻碍和不受控制,直到它们被 SSH 服务器本身断开连接。那是因为之前有通常的现有短路规则:
Run Code Online (Sandbox Code Playgroud)# accept traffic originating from us ct state established,related accept
此评论具有误导性:它不接受来自我们的流量,但不接受任何已经在进行的流量。这是短路规则。它的作用是通过仅解析新连接的所有规则来处理有状态连接:此规则之后的任何规则都适用于新连接。一旦连接被接受,它们各自的数据包就会一直被接受,直到连接结束。
对于黑名单处理的具体情况,应将特定的黑名单规则或其中的一部分置于本短路规则之前,才能立即生效。在 OP 的情况下,即:
Run Code Online (Sandbox Code Playgroud)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链中添加使用的等效规则,拒绝更快地通知本地进程尝试发出他们应该中止的信息:
ip daddr @blackhole counter reject
Run Code Online (Sandbox Code Playgroud)
add和update应用于集合之间的差异现在有了这样的设置,即使正在进行的连接立即停止,攻击者也能够继续尝试并在 100 万后获得一个新的短窗口,这不是最佳的。
条目必须在输入规则中更新@blackhole ... drop。update如果条目已经存在,将刷新计时器,而add什么也不做。这将继续阻止任何进一步(不成功)连接到 SSH 服务器的尝试,直到攻击者放弃,打开的窗口为零。(我上面添加的输出规则不应该改变,这不是攻击者的行为):
代替:
Run Code Online (Sandbox Code Playgroud)ip saddr @blackhole counter drop
with(仍然保留旧语法):
ip saddr @blackhole counter set update ip saddr timeout 1m @blackhole drop
Run Code Online (Sandbox Code Playgroud)
它甚至应该在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
Run Code Online (Sandbox Code Playgroud)
将允许任何给定的 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
Run Code Online (Sandbox Code Playgroud)
在 OP 的情况下,这甚至应该在之前的仪表规则之前触发。小心使用以避免合法用户受到影响(但请参阅 openssh 的ControlMaster选项)。
由于没有通用的 IPv4+IPv6 集地址类型,所有处理 IPv4 的规则(只要有 2 个字母的单词ip)可能都应该复制到ip6其中包含并处理 IPv6 集的镜像规则中。
| 归档时间: |
|
| 查看次数: |
3098 次 |
| 最近记录: |