Blacklistd 是一个守护程序,监听套接字,等待从其他守护程序接收有关连接尝试成功或失败的通知。它在阻止太多在开放ports上的连接尝试中被广泛使用。一个主要例子是在互联网上运行的 SSH 收到大量来自机器人或脚本尝试猜测密码并获取访问权限的请求。使用 blacklistd,守护程序可以通知防火墙创建一个过滤规则,在若干次尝试后,阻止来自单个源的过多连接尝试。Blacklistd 最初在 NetBSD 上开发,并在那里出现在第 7 版中。FreeBSD 11 从 NetBSD 导入了 blacklistd。
本章介绍如何设置 blacklistd,配置它,并提供如何使用它的示例。读者应熟悉基本的防火墙概念,如规则。详细信息,请参阅防火墙章节。示例中使用了 PF,但 FreeBSD 上可用的其他防火墙也应能够与 blacklistd 一起使用。
blacklistd 的主要配置存储在 blacklistd.conf(5)中。还可以使用各种命令行选项来更改 blacklistd 的运行时行为。跨重启的持久配置应存储在/etc/blacklistd.conf 中。要在系统启动期间启用守护进程,请在/etc/rc.conf 中添加一行 blacklistd_enable,如下所示:
要手动启动服务,请运行此命令:
Blacklistd 的规则在 blacklistd.conf(5) 中配置,每行一个条目。每个规则包含由空格或制表符分隔的元组。规则属于 local 或 remote,分别适用于运行 blacklistd 的机器或外部来源。
一个本地规则的示例 blacklistd.conf 条目看起来像这样:
遵循 [local] 部分的所有规则都被视为本地规则(这是默认设置),适用于本地机器。当遇到 [remote] 部分时,其后的所有规则将被视为远程机器规则。
由空格或制表符分隔的七个字段定义一条规则。前四个字段标识应被列入黑名单的流量。接下来的三个字段定义了 backlistd 的行为。通配符用星号( * )表示,在该字段中匹配任何内容。第一个字段定义了位置。在本地规则中,这些是网络 ports。位置字段的语法如下:
地址可以以数字格式的 IPv4 或方括号中的 IPv6 指定。也可以使用类似 em0 的接口名。
第二个字段定义了套接字类型。TCP 套接字的类型为 stream,而 UDP 则表示为 dgram。上面的示例使用了 TCP,因为 SSH 正在使用该协议。
协议可以在 blacklistd 规则的第三个字段中使用。可以使用以下协议: tcp,udp,tcp6,udp6,或数字。通配符,就像在示例中一样,通常用于匹配所有协议,除非有理由通过特定协议来区分流量。
在第四个字段中,定义了报告事件的守护进程的有效用户或所有者。用户名或 UID 可以在这里使用,以及通配符(参见上面的示例规则)。
包过滤规则名称由第五个字段声明,这开始了规则的行为部分。默认情况下,blacklistd 将所有阻止操作放在类似这样的 pf.conf 中的 pf 锚点 blacklistd 下:
对于独立的封锁列表,可以在该字段中使用锚点名称。在其他情况下,通配符就足够了。当名称以连字符( - )开头时,这意味着应使用带有默认规则名称前缀的锚点。使用连字符的修改后示例将如下所示:
带有此规则,任何新的封锁列表规则都会添加到名为 blacklistd-ssh 的锚点。
要针对单个规则违例封锁整个子网,可以在规则名称中使用 /。这将导致名称的其余部分被解释为要应用于规则中指定的地址的掩码。例如,该规则将封锁紧邻 /24 的每个地址。
此规则定义,如果网络中的任何一个主机表现不端,那么该网络中的所有其他内容也将被阻止。
第六字段称为 nfail,设置触发将远程 IP 加入阻止列表所需的登录失败次数。当在此位置使用通配符时,意味着永远不会发生阻止。在上述示例规则中,定义了三次尝试在一个连接上登录 SSH 后,IP 将被阻止。
黑名单规则定义中的最后一个字段指定主机被列入黑名单的持续时间。默认单位是秒,但也可以为分钟、小时和天指定后缀,如 m 、 h 和 d。
完整的示例规则意味着 SSH 认证三次后将导致该主机的新 PF 阻止规则。规则匹配是通过首先按照从最具体到最不具体的顺序依次检查本地规则进行的。当匹配发生时,应用 remote 规则,并且名称、 nfail 和禁用字段将被匹配的 remote 规则更改。
远程规则用于指定黑名单更改其行为的方式,具体取决于当前正在评估的远程主机。远程规则中的每个字段与本地规则中的相同。唯一的区别在于 blacklistd 使用它们的方式。为了解释这一点,使用以下示例规则:
地址字段可以是 IP 地址(v4 或 v6),port或两者兼有。这能让为特定远程地址范围设置特殊规则,就像这个示例中一样。套接字类型、协议和所有者的字段与本地规则中的解释方式完全相同。
但是,名称字段不同:远程规则中的等号( = )告诉 blacklistd 使用与匹配的本地规则的值。这意味着防火墙规则条目被取并添加了 /25 前缀(一个 255.255.255.128 的网络掩码)。当来自该地址范围的连接被列入黑名单时,整个子网都会受到影响。在这里还可以使用 PF 锚名称,这样 blacklistd 将为该名称的锚点添加此地址块的规则。当指定通配符时使用默认表。
可以为地址定义 nfail 列中的自定义失败次数。这对于特定规则的例外情况非常有用,可能能让某人对规则的应用不那么严格,或者在登录尝试中稍微宽容一些。当在第六字段中使用星号时,阻止功能将被禁用。
远程规则能让对登录尝试的限制比来自本地网络(如办公室)的尝试更加严格。
FreeBSD 中有一些软件包可以利用 blacklistd 的功能。最突出的两个是 ftpd(8)和 sshd(8),用于阻止过多的连接尝试。要在 SSH 守护程序中激活 blacklistd,请在/etc/ssh/sshd_config 中添加以下行:
之后重启 sshd 以使这些更改生效。
ftpd(8)的黑名单使用 -B 启用,可以在/etc/inetd.conf 中,也可以作为/etc/rc.conf 中的标志,如下:
这就是使这些程序与 blacklistd 通信所需的全部内容。
Blacklistd 提供了一个名为 blacklistctl(8)的管理实用程序给用户。它显示由 blacklistd.conf(5)中定义的规则所列入黑名单的被阻止的地址和网络。要查看当前被阻止主机的列表,请使用 dump 与 -b 结合使用,就像这样。
这个例子显示了来自地址范围 213.0.123.128/25 的port 22 在三次允许尝试中的六次尝试。列出的尝试次数超过允许的次数,因为 SSH 允许客户端在单个 TCP 连接上尝试多次登录。黑名单不会阻止当前正在进行的连接。最后一次连接尝试列在输出的 last access 列。
要查看此主机将在阻止列表上剩余的时间,请将 -r 添加到前一个命令中。
在这个例子中,还有 36 秒钟,此主机将不再被阻止。
有时需要在剩余时间到期之前从阻止列表中移除主机。不幸的是,blacklistd 中没有这样的功能。但是,可以使用 pfctl 将地址从 PF 表中移除。对于每个被阻止的 port,在 /etc/pf.conf 中定义的 blacklistd 锚点内有一个子锚点。例如,如果有一个用于阻止 port 22 的子锚点,则称为 blacklistd/22。在该子锚点内有一个包含被阻止地址的表。该表称为 port 后跟 port 号码。在这个例子中,它将被称为 port22。有了这些信息,现在可以使用 pfctl(8) 显示所有列出的地址:
在确定要从列表中解锁的地址之后,以下命令将其从列表中移除:
地址现在已从 PF 中删除,但仍将显示在 blacklistctl 列表中,因为它不知道在 PF 中进行的任何更改。blacklistd 数据库中的条目将最终过期,并从其输出中删除。如果主机再次匹配 blacklistd 中的阻止规则之一,则将再次添加条目。