Fail2Ban 教程

简介

Fail2Ban 是一个 Linux 系统的应用软件,用来防止系统入侵,主要是防止暴力破解系统密码。它是用 Python 开发的。

它主要通过监控日志文件(比如/var/log/auth.log/var/log/apache/access.log等)来生效。一旦发现恶意攻击的登录请求,它会封锁对方的 IP 地址,使得对方无法再发起请求。

Fail2Ban 可以防止有人反复尝试 SSH 密码登录,但是如果 SSH 采用的是密钥登录,禁止了密码登录,就不需要 Fail2Ban 来保护。

Fail2Ban 的安装命令如下。

  1. # ubuntu & Debian
  2. $ sudo apt install fail2ban
  3. # Fedora
  4. $ sudo dnf install epel-release
  5. $ sudo dnf install fail2ban
  6. # Centos & Red hat
  7. $ yum install fail2ban

安装后,使用下面的命令查看 Fail2Ban 的状态。

  1. $ systemctl status fail2ban.service

如果没有启动,就启动 Fail2Ban。

  1. $ sudo systemctl start fail2ban

重新启动 Fail2Ban。

  1. $ sudo systemctl restart fail2ban

设置 Fail2Ban 重启后自动运行。

  1. $ sudo systemctl enable fail2ban

fail2ban-client

Fail2Ban 自带一个客户端 fail2ban-client,用来操作 Fail2Ban。

  1. $ fail2ban-client

上面的命令会输出 fail2ban-client 所有的用法。

下面的命令查看激活的监控目标。

  1. $ fail2ban-client status
  2. Status
  3. |- Number of jail: 1
  4. `- Jail list: sshd

下面的命令查看某个监控目标(这里是 sshd)的运行情况。

  1. $ sudo fail2ban-client status sshd
  2. Status for the jail: sshd
  3. |- Filter
  4. | |- Currently failed: 1
  5. | |- Total failed: 9
  6. | `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
  7. `- Actions
  8. |- Currently banned: 1
  9. |- Total banned: 1
  10. `- Banned IP list: 0.0.0.0

下面的命令输出一个简要的版本,包括所有监控目标被封的 IP 地址。

  1. $ sudo fail2ban-client banned
  2. [{'sshd': ['192.168.100.50']}, {'apache-auth': []}]

下面的命令可以解封某个 IP 地址。

  1. $ sudo fail2ban-client set sshd unbanip 192.168.1.69

配置

主配置文件

Fail2Ban 主配置文件是在/etc/fail2ban/fail2ban.conf,可以新建一份副本/etc/fail2ban/fail2ban.local,修改都针对副本。

  1. $ sudo cp /etc/fail2ban/fail2ban.conf /etc/fail2ban/fail2ban.local

下面是设置 Fail2Ban 的日志位置。

  1. [Definition]
  2. logtarget = /var/log/fail2ban/fail2ban.log

修改配置以后,需要重新启动fail2ban.service,让其生效。

封禁配置

Fail2Ban 封禁行为的配置文件是/etc/fail2ban/jail.conf。为了便于修改,可以把它复制一份/etc/fail2ban/jail.local,后面的修改都针对jail.local这个文件。

  1. $ sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

你也可以在目录/etc/fail2ban/jail.d里面,新建单独的子配置文件,比如/etc/fail2ban/jail.d/sshd.local

同样地,修改配置以后,需要重新启动fail2ban.service,让其生效。

配置文件里面,[DEFAULT]标题行表示对于所有封禁目标生效。举例来说,如果封禁时间修改为1天,/etc/fail2ban/jail.local里面可以写成:

  1. [DEFAULT]
  2. bantime = 1d

如果某人被封时,对站长发送邮件通知,可以如下设置。

  1. [DEFAULT]
  2. destemail = yourname@example.com
  3. sender = yourname@example.com
  4. # to ban & send an e-mail with whois report to the destemail.
  5. action = %(action_mw)s
  6. # same as action_mw but also send relevant log lines
  7. #action = %(action_mwl)s

如果配置写在其他标题行下,就表示只对该封禁目标生效,比如写在[sshd]下面,就表示只对 sshd 生效。

默认情况下,Fail2Ban 对各种服务都是关闭的,如果要针对某一项服务开启,需要在配置文件里面声明。

  1. [sshd]
  2. enabled = true

上面声明表示,Fail2Ban 对 sshd 开启。

配置项

下面是配置文件jail.local的配置项含义,所有配置项的格式都是key=value

(1)bantime

封禁的时间长度,单位m表示分钟,d表示天,如果不写单位,则表示秒。Fail2Ban 默认封禁10分钟(10m 或 600)。

  1. [DEFAULT]
  2. bantime = 10m

(2)findtime

登录失败计算的时间长度,单位m表示分钟,d表示天,如果不写单位,则表示秒。Fail2Ban 默认封禁 10 分钟内登录 5 次失败的客户端。

  1. [DEFAULT]
  2. findtime = 10m
  3. maxretry = 5

(3)maxretry

尝试登录的最大失败次数。

(4)destemail

接受通知的邮件地址。

  1. [DEFAULT]
  2. destemail = root@localhost
  3. sender = root@<fq-hostname>
  4. mta = sendmail

(5)sendername

通知邮件的“发件人”字段的值。

(6)mta

发送邮件的邮件服务,默认是sendmail

(7)action

封禁时采取的动作。

  1. [DEFAULT]
  2. action = $(action_)s

上面的action_是默认动作,表示拒绝封禁对象的流量,直到封禁期结束。

下面是 Fail2Ban 提供的一些其他动作。

  1. # ban & send an e-mail with whois report to the destemail.
  2. action_mw = %(action_)s
  3. %(mta)s-whois[sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]
  4. # ban & send an e-mail with whois report and relevant log lines
  5. # to the destemail.
  6. action_mwl = %(action_)s
  7. %(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
  8. # See the IMPORTANT note in action.d/xarf-login-attack for when to use this action
  9. #
  10. # ban & send a xarf e-mail to abuse contact of IP address and include relevant log lines
  11. # to the destemail.
  12. action_xarf = %(action_)s
  13. xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"]
  14. # ban IP on CloudFlare & send an e-mail with whois report and relevant log lines
  15. # to the destemail.
  16. action_cf_mwl = cloudflare[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"]
  17. %(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]

(8)ignoreip

Fail2Ban 可以忽视的可信 IP 地址。多个 IP 地址之间使用空格分隔。

  1. ignoreip = 127.0.0.1/8 192.168.1.10 192.168.1.20

(9)port

指定要监控的端口。可以设为任何端口号或服务名称,比如ssh222200等。

ssh 配置

下面是 sshd 的设置范例。

  1. [sshd]
  2. enabled = true
  3. port = ssh
  4. filter = sshd
  5. banaction = iptables
  6. backend = systemd
  7. maxretry = 5
  8. findtime = 1d
  9. bantime = 2w
  10. ignoreip = 127.0.0.1/8

首先需要注意,为了让 Fail2Ban 能够完整发挥作用,最好在/etc/ssh/sshd_config里面设置LogLevel VERBOSE,保证日志有足够的信息。