SSH 暴力破解攻击太烦人了,所以...

4 min

language: ja bn en es hi pt ru zh-cn zh-tw

大家好,我是个无能的人。
当我用tail -f查看托管 Gitea 的/var/log/auth.log时,发现了一些可疑的尝试。
例如,像这样:

2024-12-07T16:57:39.486624+00:00 hostname sshd[392231]: Received disconnect from WireGuardSrvIP port 42552:11: Bye Bye [preauth]

有来自 VPN 服务器端的 SSH 登录尝试。之所以会发生这种情况,是因为我正在使用Nginx对这个 Gitea 服务器进行Stream代理。

stream {
    server {
        listen 2222; 
        proxy_pass GiteaSrvIP:2222; 
        proxy_timeout 1m;
        proxy_connect_timeout 1s;
    }
}

这样配置后,在端口 2222 上接收到的 IP 会被转发到 GiteaSrvIP。老实说,我仍然不明白为什么日志中会显示另一个端口42552,但看到这么多来自我用作内部 IP 的地址的登录尝试,感觉很不舒服。
从机制上讲,最终我希望通过 SSH 协议推送到 Gitea,但在使用Stream进行代理时,需要代理到 IP:port。我认为这是因为所有在 2222 端口上的 SSH 尝试都被转发到了 GiteaSrvIP。

我自己说着也有些混乱,所以...


攻击者:我要 SSH 到 git.domain.tld 的 2222 端口!
WireGuardSrv:哦哦,你小子是想在 2222 端口尝试登录吗?
WireGuardSrv:那好,所有发往 2222 端口的请求我都会转发给 GiteaSrv!
GiteaSrv:呃,我这边好像只能看到 WireGuardSrv 的 IP,而且收到了好多 SSH 登录尝试...。


我只能想象来自 WireGuardSrvIP 的 SSH 尝试是这样发生的...。
但奇怪的是,我只配置了在 2222 端口接收并转发到 2222 端口,却不知道为什么会变成port 42552。如果是从全球 IP 地址尝试 SSH 到这个端口,使用只存在于 VPN 上的 IP 地址,那我还能理解...。
当然,SSH 登录本身禁止root登录,并且只使用公钥认证,所以如果被突破了,我也会很好奇他们是怎么做到的。

作为对策

如果留下杂乱的auth.log,作为日志文件很难阅读,而且最重要的是,日志文件可能会变得非常庞大,所以我想在前期就阻止它。
原因是,我虽然用fail2ban阻止了多次 SSH 登录尝试,但这样一来,通过 Wireguard 对 GiteaSrvIP 的 SSH 尝试也会混在其他日志中被阻止。
因此,我想在写入auth.log之前就阻止它。

FreeBSD (WireGuard 服务器端)

将 pf 的默认阻止策略设置为drop
PF: 运行时选项
因此,我将默认策略设置为Drop

set block-policy drop

这样,如果数据包触及 FreeBSD 的阻止策略,就会被直接丢弃。

Debian (WireGuard 客户端兼 Gitea 服务器端)

首先,GiteaHTTP服务器和SSH的 22 号、2222 号端口,从 WireGuardSrvIP 来的其他端口号进行访问本身就很奇怪。
特别是 2222 号以上的端口,如 3000 号,作为默认的本地 HTTP 端口运行,所以这些端口本来不应该打开。但是,我不想让 Gitea 监听 80 号端口,所以暂时在测试期间打开了 3000 号端口。
说了这么多,我用ufw限制了端口,如下所示。

ufw deny proto tcp from WireGuardSrvIP to any port 2223:65535
ufw reload

因为我想把它当作一个玩乐的 VPS 服务器,所以我暂时拒绝了2223:65535范围的端口,并另外明确打开了3000/tcp

无意义的 SSH 尝试日志已成功停止

多亏了这一点,无论是 FreeBSD 端的阻止策略生效了,还是我用 ufw 明确地deny了,因为我是同时进行的,所以不知道是哪一个的效果,但那些像鬼一样涌入auth.log的登录尝试已经停止了。
可能,因为我本来在FreeBSD端就设置了一定程度的防火墙,所以对于被阻止的项目,通过drop而不是REJECT,所有数据包都在FreeBSD阶段被丢弃了。我希望如此。

重新配置 fail2ban

因此,我编辑了/etc/fail2ban/jail.conf
并在默认监控设置中配置了要排除的 IP:

[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 WireGuardSrvIP

之后,我修改了sshd的配置:

[sshd]
enabled = true
port    = all
logpath = /var/log/auth.log
bantime = 10w  
findtime = 1d  
maxretry = 2

我尝试了比WireGuardSrv更严格的设置。
更改的原因如下:

port    =  all
maxretry = 2

WireGuardSrv的端口明确设置为ssh,所以只监控用于 SSH 的端口,但这个设置监控所有端口上的 SSH 尝试。
重试次数也更严格,最多 2 次。
我改变它的原因是想看看会捕获多少次。如果捕获了很多次,我打算在WireGuardSrv上也设置相同级别的规则。
就这样。
我很期待结果。

Related Posts