跳转至内容

sshguard

来自 ArchWiki

警告 使用 IP 黑名单可以阻止简单的攻击,但它依赖于额外的守护进程和成功的日志记录(包含 /var 的分区可能会被填满,尤其是当攻击者猛烈攻击服务器时)。此外,如果攻击者知道你的 IP 地址,他们可以发送带有伪造源头的数据包,导致你被锁定在服务器之外。SSH 密钥为防范暴力破解提供了一个优雅的解决方案,且没有这些问题。

sshguard 是一个守护进程,用于保护 SSH 和其他服务免受暴力破解攻击,类似于 fail2ban

sshguard 与后者的不同之处在于它是用 C 语言编写的,更轻量,使用更简单,功能较少,但在执行其核心功能方面同样出色。

sshguard 不易受到大多数(或可能任何)曾给类似工具带来麻烦的日志分析漏洞的影响。

安装

安装 sshguard 软件包。

配置

sshguard 通过监控 /var/log/auth.logsyslog-ngsystemd journal 中的登录失败尝试来工作。对于每次失败的尝试,违规主机将被禁止在有限的时间内进行进一步通信。违规者被封禁的默认时间从 120 秒开始,每次再次登录失败时,封禁时间将增加 1.5 倍。sshguard 可以配置为永久封禁失败尝试次数过多的主机。

临时和永久封禁都是通过在 iptables 的 "sshguard" 链中添加一条丢弃违规者所有数据包的条目来实现的。封禁操作随后会被记录到 syslog 中,并最终出现在 /var/log/auth.log 中,或者在使用 systemd journal 的情况下记录在 journal 中。

你必须配置以下防火墙之一与 sshguard 配合使用,才能使拦截生效。

firewalld

本文或本章节已过时。

原因: ipset 在 firewalld 中已被弃用,以下步骤会破坏 firewalld 的运行。(在 Talk:Sshguard 中讨论)

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)部分之后插入以下行。

注意 在非标准端口上运行 sshd 的用户应在上述最后一行中替换该端口(22 是标准端口)。
/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

注意 请先参考 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
注意 对于 IPv6,请使用 ip6tables 重复相同步骤,并使用 ip6tables-save 将规则保存到 /etc/iptables/ip6tables.rules

nftables

BACKEND 的值更改为以下内容

/etc/sshguard.conf
BACKEND="/usr/lib/sshguard/sshg-fw-nft-sets"

当你启动/启用 sshguard.service 时,会在 ipip6 地址族中添加两个名为 sshguard 的新表,通过 sshguard 的 IP 地址列表过滤传入流量。sshguard 表中的链优先级为 -10,将在其他较低优先级的规则之前被处理。有关更多信息,请参阅 sshguard-setup(7)nftables

用法

systemd

启用启动 sshguard.service

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 中找到。

注意 sshguard 的 systemd 单元中不支持管道命令和运行时标志。此类标志可以在配置文件中修改。

黑名单阈值

在 Arch 提供的默认配置文件中,违规者一旦达到 120 的“危险”级别(或 12 次登录失败;详见攻击危险度),将被永久封禁。这种行为可以通过在黑名单文件前添加危险级别来修改。

/etc/sshguard.conf
BLACKLIST_FILE=200:/var/db/sshguard/blacklist.db

本例中的 200: 告诉 sshguard 在主机达到 200 的危险级别后将其永久封禁。

最后,重启 sshguard.service

适度封禁示例

这里提出了一个比默认规则稍微激进一点的封禁规则,以演示各种选项

  • 它通过 systemd/Journal 的日志监控 sshdvsftpd
  • 它在 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 }

其中 familyipip6

日志记录

要查看传递给 sshguard 的内容,请检查 /usr/lib/systemd/scripts/sshguard-journalctl 脚本和 systemd 服务 sshguard.service。在终端查看日志的等效命令为

# journalctl -afb -p info SYSLOG_FACILITY=4 SYSLOG_FACILITY=10

© . This site is unofficial and not affiliated with Arch Linux.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.