加入我们,共同推进 FreeBSD 之中国化与亚洲化。FreeBSD 绝不大败亡!!

第 15.5 节 Fail2Ban(基于 IPFW、PF、IPF)

根据开发者官方说明,Fail2Ban 可封禁多次身份验证错误的主机,即通过更新系统防火墙规则来拒绝来自那些 IP 地址的新连接。Fail2Ban 几乎完全由 Python 写就(Python 96.0%)。

安装 Fail2Ban

  • 使用 pkg 安装:

# pkg install security/py-fail2ban
    • 或者使用 Ports 安装:

# cd /usr/ports/security/py-fail2ban/ 
# make install clean
  • 配置服务:

# service fail2ban enable

查看 fail2ban 安装后说明

# pkg info -D security/py-fail2ban
py311-fail2ban-1.1.0_1:
On install:
Please do not edit the fail2ban.conf, jail.conf, or any other
files in the distributen as they will be overwritten upon each
upgrade of the port. Instead, create new files named *.local e.g.
fail2ban.local or jail.local.
# 请不要直接修改 fail2ban.conf、jail.conf 或其他官方提供的配置文件,
# 因为它们会在每次升级该软件包时被覆盖。
# 应该创建 *.local 文件,如 fail2ban.local 或 jail.local,来自定义配置。

For more information, see the official manual:
http://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Configuration
# 更多信息可参见官方手册。

If you have custom filters or actions and you are upgrading from
0.9.x please check them.
# 如果你定义了自定义过滤器或操作,且从 0.9.x 升级而来,请检查其兼容性。

Users of pf: please read the notes in action.d/pf.conf and the
discussion at https://github.com/fail2ban/fail2ban/pull/1925
# 使用 pf 防火墙的用户请阅读 action.d/pf.conf 中的注释,
# 以及上面 GitHub 讨论链接中的相关说明。

Please note that fail2ban will put curly braces '{}' around the
ports in the action so you shouldn't do it yourself.
# 注意:fail2ban 会自动在动作命令中将端口号用大括号 {} 包裹,
# 因此你自己不需要再加。

Fail2Ban 配置解释

注意

这个 jail,不是 BSD 里那个 jail(一种容器)。这个 jail 就是“封禁”这个字面意思。

配置实例在 /usr/local/etc/fail2ban/jail.conf(勿直接编辑,参见上文)。仅列出本文所需内容:

# DEFAULT 是全局定义的配置,之后每个 jail 都可以单独覆盖这些设置。

[DEFAULT]

# "ignoreip" 可以是一个 IP 地址、CIDR 子网掩码或 DNS 主机的列表。Fail2ban  
# 不会封禁与该列表中地址匹配的主机。可以使用空格(和/或逗号)分隔符定义多个地址。
# "ignoreip" 即白名单
# ignoreip = 127.0.0.1/8 ::1

# "maxretry" 默认重试次数
maxretry = 5

# 如果主机在过去的 "findtime" 秒内产生了 "maxretry" 次失败,主机将被封禁。
# 即定义封禁频率。
findtime  = 10m

# "bantime" 是主机被封禁的时间,单位为秒的整数或时间缩写格式(m - 分钟,h - 小时,d - 天,w - 周,mo - 月,y - 年)。  
# 即多长时间后可重试。
bantime  = 10m

[sshd]
# enabled = true
#
# 参见 jail.conf(5)

# "filter" 定义了 jail 所使用的过滤器。 ①
# 在默认情况下,jail 的名称与其过滤器名称相匹配。
#
filter = %(__name__)s[mode=%(mode)s]
# 例如:
# filter = sshd[mode=aggressive]
#  
# 操作快捷方式。用于定义 action 参数。  

# Fail2Ban 还需要防火墙来执行封禁动作。
# 默认封禁操作(例如 iptables、iptables-new、iptables-multiport、shorewall 等)。 ②
# 它用于定义 action_* 变量,可以在 jail.local 文件的全局或特定部分中覆盖。  
# banaction = iptables-multiport  
# banaction_allports = iptables-allports
  • ① 可用的过滤器名称:

root@ykla:/home/ykla # ls /usr/local/etc/fail2ban/filter.d/
……省略一部分输出……
bsd-sendmail.conf		mssql-auth.conf			slapd.conf
bsd-sshd.conf			murmur.conf			softethervpn.conf
bsdftp.conf			mysqld-auth.conf		sogo-auth.conf
courier-auth.conf		nginx-botsearch.conf		sshd.conf

需要注意,以 bsd- 开头的文件(如 bsd-sshd.conf)是 FreeBSD Port 维护者打的补丁。但是疏于维护?应该直接使用 sshd.conf。已经报告 bug。security/py-fail2ban: Is it possible to remove patch-config_filter.d_bsd-sshd.conf from py-fail2ban?

  • ② 查看 Fail2Ban 支持的防火墙:

# ls /usr/local/etc/fail2ban/action.d/
bsd-ipfw.conf				ipfw.conf				ipfilter.conf
……省略其他防火墙……

Fail2Ban 封禁配置

创建并编辑文件 /usr/local/etc/fail2ban/jail.d/sshd.conf,写入如下内容:

[DEFAULT]
ignoreip=192.168.0.0/24
maxretry = 3
findtime = 10m
bantime = 8h

[sshd]
enabled=true
filter=sshd
action=bsd-ipfw

配置解释:

  • 192.168.0.0/24192.168.0.0192.168.0.254

  • bsd-ipfw 是示例防火墙。你可自选。参见下文。

警告

若你使用 IPFW,则必须使用 bsd-ipfw。因为 ipfw 不会生效!

配置防火墙

先启动 fail2ban:

# service fail2ban start

IPFW

Fail2Ban 配置见上节。

配置自启服务

# sysrc firewall_enable="YES"

警告

不要 顺手 start 了。否则你将连不上 ssh 了。

默认允许通过

  • IPFW 规则是“默认拒绝”,我们改成“默认允许”

# echo net.inet.ip.fw.default_to_accept="1" >> /boot/loader.conf
# reboot # 重启生效
  • 查看 IPFW 规则

# ipfw list
……省略一部分……
65535 allow ip from any to any

参考文献

PF

fail2ban 配置文件

将上方配置文件 /usr/local/etc/fail2ban/jail.d/sshd.confaction=bsd-ipfw 改为 action = pf[port={22 23}, name=ssh],其他不需要改。

服务

# kldload pf # 加载内核模块,后边就不需要了
# cp /usr/share/examples/pf/pf.conf /etc # 复制示例文件,否则 PF 无法启动。
# service pf enable # 开机自启
# service pf start # 启动 PF 防火墙!

修改 PF 配置文件

编辑 /etc/pf.conf,写入:

table <f2b> persist
anchor "f2b/*"
block drop in log quick on em0 from <f2b> to any
  • em0:上面的 em0 是我的网卡名,你要改成你自己的。

参考文献

测试 pf

root@ykla:/home/ykla # pfctl -a "f2b/sshd" -t f2b-sshd -Ts
   192.168.179.1

IPFILTER (IPF)

fail2ban 配置文件

将上方配置文件 /usr/local/etc/fail2ban/jail.d/sshd.confaction=bsd-ipfw 改为 action=ipfilter,其他不需要改。

服务

  • 复制示例文件作为默认配置规则集文件,否则 ipfilter 启动后会没有规则。示例文件自带的规则不影响使用

# cp /usr/share/examples/ipfilter/ipf.conf.sample /etc/ipf.rules
  • 启动 ipfilter

# service ipfilter enable
# service ipfilter start

即可。终于不用再配置了,默认就可以用

测试效果

  • 测试主动拉黑 IP 以查看效果

# fail2ban-client set sshd banip 192.168.179.1
  • TTY 输出

Mar 25 15:27:B8 gkla sshd[970]: error : maximum authentication attempts exceeded for ykla from 192.168.179.1 port 8652 ssh2 [ preauth ]

已经链接的 ssh 服务也会被强制断开。

查看状态

# fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed:	1
|  |- Total failed:	4
|  `- File list:	/var/log/auth.log
`- Actions
   |- Currently banned:	1
   |- Total banned:	1
   `- Banned IP list:	192.168.179.1

解禁 IP

# fail2ban-client set sshd unbanip 192.168.179.1
1
# fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed:	1
|  |- Total failed:	4
|  `- File list:	/var/log/auth.log
`- Actions
   |- Currently banned:	0
   |- Total banned:	1
   `- Banned IP list:

故障排除与未竟事宜

  • fail2ban 的日志在 /var/log/fail2ban.log

最后更新于