sshguard
sshguard 是一个守护进程,用于保护 SSH 和其他服务免受暴力破解攻击,类似于 fail2ban。
sshguard 与后者的不同之处在于它是用 C 语言编写的,更轻量,使用更简单,功能较少,但在执行其核心功能方面同样出色。
sshguard 不易受到大多数(或可能任何)曾给类似工具带来麻烦的日志分析漏洞的影响。
安装
配置
sshguard 通过监控 /var/log/auth.log、syslog-ng 或 systemd journal 中的登录失败尝试来工作。对于每次失败的尝试,违规主机将被禁止在有限的时间内进行进一步通信。违规者被封禁的默认时间从 120 秒开始,每次再次登录失败时,封禁时间将增加 1.5 倍。sshguard 可以配置为永久封禁失败尝试次数过多的主机。
临时和永久封禁都是通过在 iptables 的 "sshguard" 链中添加一条丢弃违规者所有数据包的条目来实现的。封禁操作随后会被记录到 syslog 中,并最终出现在 /var/log/auth.log 中,或者在使用 systemd journal 的情况下记录在 journal 中。
你必须配置以下防火墙之一与 sshguard 配合使用,才能使拦截生效。
firewalld
sshguard 可以与 firewalld 配合工作。请确保你已首先启用、配置并设置好 firewalld。为了让 sshguard 写入你偏好的区域(zone),请执行以下命令
# firewall-cmd --permanent --zone=public --add-rich-rule="rule source ipset=sshguard4 drop"
如果你使用 ipv6,可以执行相同的命令,但将 sshguard4 替换为 sshguard6。最后执行
# firewall-cmd --reload
你可以通过以下命令验证上述操作
# firewall-cmd --info-ipset=sshguard4
最后,在 /etc/sshguard.conf 中,找到 BACKEND 这一行并修改如下
/etc/sshguard.conf
BACKEND="/usr/lib/sshguard/sshg-fw-firewalld"
UFW
如果安装并启用了 UFW,必须授予它将 DROP 控制传递给 sshguard 的能力。这可以通过修改 /etc/ufw/before.rules 和 /etc/ufw/before6.rules 来实现,在环回设备(loopback devices)部分之后插入以下行。
/etc/ufw/before.rules
# allow all on loopback -A ufw-before-input -i lo -j ACCEPT -A ufw-before-output -o lo -j ACCEPT # hand off control for sshd to sshguard :sshguard - [0:0] -A ufw-before-input -p tcp --dport 22 -j sshguard
/etc/ufw/before6.rules
# allow all on loopback -A ufw6-before-input -i lo -j ACCEPT -A ufw6-before-output -o lo -j ACCEPT # hand off control for sshd to sshguard :sshguard - [0:0] -A ufw6-before-input -p tcp --dport 22 -j sshguard
进行此修改后,请重启 ufw。
iptables
主要需要的配置是创建一个名为 sshguard 的链,sshguard 会自动在其中插入规则以丢弃来自恶意主机的数据包
# iptables -N sshguard
然后添加一条从 INPUT 链跳转到 sshguard 链的规则。此规则必须在处理 sshguard 保护端口的任何其他规则之前添加。使用以下行来保护 FTP 和 SSH,或参阅 [1] 获取更多示例。
# iptables -A INPUT -m multiport -p tcp --destination-ports 21,22 -j sshguard
保存规则
# iptables-save > /etc/iptables/iptables.rules
/etc/iptables/ip6tables.rules。nftables
将 BACKEND 的值更改为以下内容
/etc/sshguard.conf
BACKEND="/usr/lib/sshguard/sshg-fw-nft-sets"
当你启动/启用 sshguard.service 时,会在 ip 和 ip6 地址族中添加两个名为 sshguard 的新表,通过 sshguard 的 IP 地址列表过滤传入流量。sshguard 表中的链优先级为 -10,将在其他较低优先级的规则之前被处理。有关更多信息,请参阅 sshguard-setup(7) 和 nftables。
用法
systemd
syslog-ng
如果你安装了 syslog-ng,你可以改为直接从命令行启动 sshguard。
/usr/sbin/sshguard -l /var/log/auth.log -b /var/db/sshguard/blacklist.db
配置
配置在 /etc/sshguard.conf 中完成,这是 sshguard 启动所必需的。带注释的示例位于 /usr/share/doc/sshguard/sshguard.conf.sample,也可以在 Bitbucket sshguard.conf.sample 中找到。
黑名单阈值
在 Arch 提供的默认配置文件中,违规者一旦达到 120 的“危险”级别(或 12 次登录失败;详见攻击危险度),将被永久封禁。这种行为可以通过在黑名单文件前添加危险级别来修改。
/etc/sshguard.conf
BLACKLIST_FILE=200:/var/db/sshguard/blacklist.db
本例中的 200: 告诉 sshguard 在主机达到 200 的危险级别后将其永久封禁。
最后,重启 sshguard.service。
适度封禁示例
这里提出了一个比默认规则稍微激进一点的封禁规则,以演示各种选项
- 它通过 systemd/Journal 的日志监控 sshd 和 vsftpd
- 它在 2 次尝试后(每次代价为 10,因此
THRESHOLD参数值为20)封禁攻击者 180 秒,随后的封禁时间按 1.5 倍增加。请注意,这个 1.5 倍的乘法延迟是内部的,无法在设置中控制 - 攻击者在 10 次尝试后被永久列入黑名单(10 次尝试每次代价为 10,因此
BLACKLIST_FILE参数值为100) - 它不仅封禁攻击者的 IP,还封禁整个 IPv4 子网 24(CIDR 表示法)
/etc/sshguard.conf
# Full path to backend executable (required, no default) BACKEND="/usr/lib/sshguard/sshg-fw-iptables" # Log reader command (optional, no default) LOGREADER="LANG=C.UTF-8 /usr/bin/journalctl -afb -p info -n1 -t sshd-session -t vsftpd -o cat" # How many problematic attempts trigger a block THRESHOLD=20 # Blocks last at least 180 seconds BLOCK_TIME=180 # The attackers are remembered for up to 3600 seconds DETECTION_TIME=3600 # Blacklist threshold and file name BLACKLIST_FILE=100:/var/db/sshguard/blacklist.db # IPv6 subnet size to block. Defaults to a single address, CIDR notation. (optional, default to 128) IPV6_SUBNET=64 # IPv4 subnet size to block. Defaults to a single address, CIDR notation. (optional, default to 32) IPV4_SUBNET=24
激进封禁
对于一些处于持续攻击下的用户,可以采用更激进的封禁策略。如果你确信不太可能发生意外的登录失败,你可以指示 SSHGuard 在一次登录失败后就永久封禁主机。按以下方式修改配置文件中的参数
/etc/sshguard.conf
THRESHOLD=10 BLACKLIST_FILE=10:/var/db/sshguard/blacklist.db
最后 重启 sshguard.service。
此外,为了防止在单次连接中进行多次身份验证尝试,你可能想要通过定义以下内容来更改 /etc/ssh/sshd_config
/etc/ssh/sshd_config
MaxAuthTries 1
重启 sshd.service 使此更改生效。
技巧与提示
解封
如果你封禁了你自己,你可以等待自动解封,或使用 iptables 或 nftables 来解封自己。
你还需要从 /var/db/sshguard/blacklist.db 中删除该 IP 地址,以使解封持久化。
iptables
首先检查你的 IP 是否被 sshguard 封禁
# iptables --list sshguard --line-numbers --numeric
然后使用以下命令解封,其中行号为前一条命令中确定的行号
# iptables --delete sshguard line-number
nftables
从 attackers 集合中删除你的 IP 地址
# nft delete element family sshguard attackers { ip_address }
其中 family 为 ip 或 ip6。
日志记录
要查看传递给 sshguard 的内容,请检查 /usr/lib/systemd/scripts/sshguard-journalctl 脚本和 systemd 服务 sshguard.service。在终端查看日志的等效命令为
# journalctl -afb -p info SYSLOG_FACILITY=4 SYSLOG_FACILITY=10