简介
如果你的主机在公网上有端口暴露出去,那么总会有一些不怀好意的家伙,会尝试通过各种方式攻击你的机器。常见的服务例如ssh, nginx都会有类似的威胁。
手工将某个ip加入黑名单,这种操作太麻烦,而且效率低。而fail2ban就是一种自动化的解决方案。
fail2ban工作原理
fail2ban的工作原理是监控某个日志文件,然后根据某些关键词,提取出攻击方的IP地址,然后将其加入到黑名单。
fail2ban安装
yum install fail2ban -y
# 如果找不到fail2ban包,就执行下面的命令
yum install epel-release
# 安装fail2ban 完成后
systemctl enable fail2ban # 设置fail2ban开机启动
systemctl start fail2ban # 启动fail2ban
systemctl status fail2ban # 查看fail2ban的运行状态
用fail2ban保护ssh
fail2ban的配置文件位于/etc/fail2ban目录下。
在该目录下建立一个文件 jail.local, 内容如下
- bantime 持续禁止多久
- maxretry 最大多少次尝试
- banaction 拦截后的操作
- findtime 查找时间
看下下面的操作的意思是:监控sshd服务的最近10分钟的日志,如果某个ip在10分钟之内,有2次登录失败,就把这个ip加入黑名单, 24小时之后,这个ip才会被从黑名单中移除。
[DEFAULT]
bantime = 24h
banaction = iptables-multiport
maxretry = 2
findtime = 10m
[sshd]
enabled = true
然后重启fail2ban, systemctl restart fail2ban
fail2ban提供管理工具fail2ban-client
- **fail2ban-client status **显示fail2ban的状态
- **fail2ban-client status sshd **显示某个监狱的配置。从下文的输出来看可以看出来fail2ban已经拦截了一些IP地址了
> fail2ban-client status
Status
|- Number of jail: 1
`- Jail list: sshd
> fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 2
| |- Total failed: 23289
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 9
|- Total banned: 1270
`- Banned IP list: 93.174.93.10 165.22.238.92 23.231.25.234 134.255.219.207 77.202.192.113 120.224.47.86 144.91.70.139 90.3.194.84 217.182.89.87
fail2ban保护sshd的原理
fail2ban的配置文件目录下有个filter.d目录,该目录下有个sshd.conf的文件,这个文件就是对于sshd日志的过滤规则,里面有些正常时用来提取出恶意家伙的IP地址。
配置配置文件很长,我们只看其中一段, 其中**<****HOST>**是个非常重要的关键词,是用来提取出远程的IP地址的。
cmnfailre = ^[aA]uthentication (?:failure|error|failed) for <F-USER>.*</F-USER> from <HOST>( via \S+)?%(__suff)s$
^User not known to the underlying authentication module for <F-USER>.*</F-USER> from <HOST>%(__suff)s$
^Failed publickey for invalid user <F-USER>(?P<cond_user>\S+)|(?:(?! from ).)*?</F-USER> from <HOST>%(__on_port_opt)s(?: ssh\d*)?(?(cond_us
实战:如何自定义一个过滤规则
我的nginx服务器,几乎每隔2-3秒就会收到下面的一个请求。
下面我就写个过滤规则,将类似请求的IP加入黑名单。
165.22.225.238 - - [28/Apr/2020:08:19:38 +0800] "POST /ws/v1/cluster/apps/new-application HTTP/1.1" 502 11 "-" "python-requests/2.6.0 CPython/2.7.5 Linux/3.10.0-957.27.2.el7.x86_64" "-"
165.22.225.238 - - [28/Apr/2020:08:22:48 +0800] "POST /ws/v1/cluster/apps/new-application HTTP/1.1" 502 11 "-" "python-requests/2.6.0 CPython/2.7.5 Linux/3.10.0-957.27.2.el7.x86_64" "-"
165.22.225.238 - - [28/Apr/2020:08:24:08 +0800] "POST /ws/v1/cluster/apps/new-application HTTP/1.1" 502 11 "-" "python-requests/2.6.0 CPython/2.7.5 Linux/3.10.0-957.27.2.el7.x86_64" "-"
165.22.225.238 - - [28/Apr/2020:08:25:45 +0800] "POST /ws/v1/cluster/apps/new-application HTTP/1.1" 502 11 "-" "python-requests/2.6.0 CPython/2.7.5 Linux/3.10.0-957.27.2.el7.x86_64" "-"
165.22.225.238 - - [28/Apr/2020:08:28:01 +0800] "POST /ws/v1/cluster/apps/new-application HTTP/1.1" 502 11 "-" "python-requests/2.6.0 CPython/2.7.5 Linux/3.10.0-957.27.2.el7.x86_64" "-"
step1: 分析日志规则
165.22.225.238 - - [28/Apr/2020:08:19:38 +0800] "POST /ws/v1/cluster/apps/new-application HTTP/1.1" 502 11 "-" "python-requests/2.6.0 CPython/2.7.5 Linux/3.10.0-957.27.2.el7.x86_64" "-"
HOST - - .*" 502 .*
step2: 写规则文件
在filter.d目录下新建文件 banit.conf
[INCLUDES]
[Definition]
failregex = <HOST> - - .*" 502 .*
ignoreregex =
step3: 修改jail.local
[DEFAULT]
bantime = 24h
banaction = iptables-multiport
maxretry = 2
findtime = 10m
[sshd]
enabled = true
[banit]
enabled = true
action = iptables-allports[name=banit, protocol=all]
logpath = /var/log/nginx/access.log
step4: 重启fail2ban
fail2ban-client restart**
step5: 查看效果
可以看出banit的这个监狱,已经加入了一个165.22.225.238这个ip,这个流氓不会在骚扰我们的主机了。
> fail2ban fail2ban-client status banit
Status for the jail: banit
|- Filter
| |- Currently failed: 1
| |- Total failed: 5
| `- File list: /var/log/nginx/access.log
`- Actions
|- Currently banned: 1
|- Total banned: 1
`- Banned IP list: 165.22.225.238
**
fail2ban-client 常用操作
- 重启: **fail2ban systemctl restart fail2ban **
- 查看fail2ban opensips运行状态: **fail2ban-client status opensips **
- 黑名单操作 (注意,黑名单测试时,不要把自己的IP加到黑名单里做测试,否则就连不上机器了)
- IP加入黑名单:**fail2ban-client set opensips banip 192.168.1.8 **
- IP解锁:fail2ban-client set opensips unbanip 192.168.1.8
- 白名单操作
- IP加入白名单:fail2ban-client set opensips addignoreip 192.168.1.8
- IP从白名单中移除:fail2ban-client set opensips delignoreip 192.168.1.8
- 在所有监狱中加入IP白名单:fail2ban-clien unban 192.168.1.8
fail2ban的拦截是基于jail, 如果一个ip在某个jail中,但是不在其他jail中,那么这个ip也是无法访问主机。如果想在所有jail中加入一个白名单,需要fail2ban-client unban ip。
**
fail2ban-client帮助文档
Usage: fail2ban-client [OPTIONS] <COMMAND>
Fail2Ban v0.10.5 reads log file that contains password failure report
and bans the corresponding IP addresses using firewall rules.
Options:
-c <DIR> configuration directory
-s <FILE> socket path
-p <FILE> pidfile path
--loglevel <LEVEL> logging level
--logtarget <TARGET> logging target, use file-name or stdout, stderr, syslog or sysout.
--syslogsocket auto|<FILE>
-d dump configuration. For debugging
--dp, --dump-pretty dump the configuration using more human readable representation
-t, --test test configuration (can be also specified with start parameters)
-i interactive mode
-v increase verbosity
-q decrease verbosity
-x force execution of the server (remove socket file)
-b start server in background (default)
-f start server in foreground
--async start server in async mode (for internal usage only, don't read configuration)
--timeout timeout to wait for the server (for internal usage only, don't read configuration)
--str2sec <STRING> convert time abbreviation format to seconds
-h, --help display this help message
-V, --version print the version (-V returns machine-readable short format)
Command:
BASIC
start starts the server and the jails
restart restarts the server
restart [--unban] [--if-exists] <JAIL> restarts the jail <JAIL> (alias
for 'reload --restart ... <JAIL>')
reload [--restart] [--unban] [--all] reloads the configuration without
restarting of the server, the
option '--restart' activates
completely restarting of affected
jails, thereby can unban IP
addresses (if option '--unban'
specified)
reload [--restart] [--unban] [--if-exists] <JAIL>
reloads the jail <JAIL>, or
restarts it (if option '--restart'
specified)
stop stops all jails and terminate the
server
unban --all unbans all IP addresses (in all
jails and database)
unban <IP> ... <IP> unbans <IP> (in all jails and
database)
status gets the current status of the
server
ping tests if the server is alive
echo for internal usage, returns back
and outputs a given string
help return this output
version return the server version
LOGGING
set loglevel <LEVEL> sets logging level to <LEVEL>.
Levels: CRITICAL, ERROR, WARNING,
NOTICE, INFO, DEBUG, TRACEDEBUG,
HEAVYDEBUG or corresponding
numeric value (50-5)
get loglevel gets the logging level
set logtarget <TARGET> sets logging target to <TARGET>.
Can be STDOUT, STDERR, SYSLOG or a
file
get logtarget gets logging target
set syslogsocket auto|<SOCKET> sets the syslog socket path to
auto or <SOCKET>. Only used if
logtarget is SYSLOG
get syslogsocket gets syslog socket path
flushlogs flushes the logtarget if a file
and reopens it. For log rotation.
DATABASE
set dbfile <FILE> set the location of fail2ban
persistent datastore. Set to
"None" to disable
get dbfile get the location of fail2ban
persistent datastore
set dbmaxmatches <INT> sets the max number of matches
stored in database per ticket
get dbmaxmatches gets the max number of matches
stored in database per ticket
set dbpurgeage <SECONDS> sets the max age in <SECONDS> that
history of bans will be kept
get dbpurgeage gets the max age in seconds that
history of bans will be kept
JAIL CONTROL
add <JAIL> <BACKEND> creates <JAIL> using <BACKEND>
start <JAIL> starts the jail <JAIL>
stop <JAIL> stops the jail <JAIL>. The jail is
removed
status <JAIL> [FLAVOR] gets the current status of <JAIL>,
with optional flavor or extended
info
JAIL CONFIGURATION
set <JAIL> idle on|off sets the idle state of <JAIL>
set <JAIL> ignoreself true|false allows the ignoring of own IP
addresses
set <JAIL> addignoreip <IP> adds <IP> to the ignore list of
<JAIL>
set <JAIL> delignoreip <IP> removes <IP> from the ignore list
of <JAIL>
set <JAIL> ignorecommand <VALUE> sets ignorecommand of <JAIL>
set <JAIL> ignorecache <VALUE> sets ignorecache of <JAIL>
set <JAIL> addlogpath <FILE> ['tail'] adds <FILE> to the monitoring list
of <JAIL>, optionally starting at
the 'tail' of the file (default
'head').
set <JAIL> dellogpath <FILE> removes <FILE> from the monitoring
list of <JAIL>
set <JAIL> logencoding <ENCODING> sets the <ENCODING> of the log
files for <JAIL>
set <JAIL> addjournalmatch <MATCH> adds <MATCH> to the journal filter
of <JAIL>
set <JAIL> deljournalmatch <MATCH> removes <MATCH> from the journal
filter of <JAIL>
set <JAIL> addfailregex <REGEX> adds the regular expression
<REGEX> which must match failures
for <JAIL>
set <JAIL> delfailregex <INDEX> removes the regular expression at
<INDEX> for failregex
set <JAIL> addignoreregex <REGEX> adds the regular expression
<REGEX> which should match pattern
to exclude for <JAIL>
set <JAIL> delignoreregex <INDEX> removes the regular expression at
<INDEX> for ignoreregex
set <JAIL> findtime <TIME> sets the number of seconds <TIME>
for which the filter will look
back for <JAIL>
set <JAIL> bantime <TIME> sets the number of seconds <TIME>
a host will be banned for <JAIL>
set <JAIL> datepattern <PATTERN> sets the <PATTERN> used to match
date/times for <JAIL>
set <JAIL> usedns <VALUE> sets the usedns mode for <JAIL>
set <JAIL> attempt <IP> [<failure1> ... <failureN>]
manually notify about <IP> failure
set <JAIL> banip <IP> ... <IP> manually Ban <IP> for <JAIL>
set <JAIL> unbanip [--report-absent] <IP> ... <IP>
manually Unban <IP> in <JAIL>
set <JAIL> maxretry <RETRY> sets the number of failures
<RETRY> before banning the host
for <JAIL>
set <JAIL> maxmatches <INT> sets the max number of matches
stored in memory per ticket in
<JAIL>
set <JAIL> maxlines <LINES> sets the number of <LINES> to
buffer for regex search for <JAIL>
set <JAIL> addaction <ACT>[ <PYTHONFILE> <JSONKWARGS>]
adds a new action named <ACT> for
<JAIL>. Optionally for a Python
based action, a <PYTHONFILE> and
<JSONKWARGS> can be specified,
else will be a Command Action
set <JAIL> delaction <ACT> removes the action <ACT> from
<JAIL>
COMMAND ACTION CONFIGURATION
set <JAIL> action <ACT> actionstart <CMD>
sets the start command <CMD> of
the action <ACT> for <JAIL>
set <JAIL> action <ACT> actionstop <CMD> sets the stop command <CMD> of the
action <ACT> for <JAIL>
set <JAIL> action <ACT> actioncheck <CMD>
sets the check command <CMD> of
the action <ACT> for <JAIL>
set <JAIL> action <ACT> actionban <CMD> sets the ban command <CMD> of the
action <ACT> for <JAIL>
set <JAIL> action <ACT> actionunban <CMD>
sets the unban command <CMD> of
the action <ACT> for <JAIL>
set <JAIL> action <ACT> timeout <TIMEOUT>
sets <TIMEOUT> as the command
timeout in seconds for the action
<ACT> for <JAIL>
GENERAL ACTION CONFIGURATION
set <JAIL> action <ACT> <PROPERTY> <VALUE>
sets the <VALUE> of <PROPERTY> for
the action <ACT> for <JAIL>
set <JAIL> action <ACT> <METHOD>[ <JSONKWARGS>]
calls the <METHOD> with
<JSONKWARGS> for the action <ACT>
for <JAIL>
JAIL INFORMATION
get <JAIL> logpath gets the list of the monitored
files for <JAIL>
get <JAIL> logencoding gets the encoding of the log files
for <JAIL>
get <JAIL> journalmatch gets the journal filter match for
<JAIL>
get <JAIL> ignoreself gets the current value of the
ignoring the own IP addresses
get <JAIL> ignoreip gets the list of ignored IP
addresses for <JAIL>
get <JAIL> ignorecommand gets ignorecommand of <JAIL>
get <JAIL> failregex gets the list of regular
expressions which matches the
failures for <JAIL>
get <JAIL> ignoreregex gets the list of regular
expressions which matches patterns
to ignore for <JAIL>
get <JAIL> findtime gets the time for which the filter
will look back for failures for
<JAIL>
get <JAIL> bantime gets the time a host is banned for
<JAIL>
get <JAIL> datepattern gets the patern used to match
date/times for <JAIL>
get <JAIL> usedns gets the usedns setting for <JAIL>
get <JAIL> maxretry gets the number of failures
allowed for <JAIL>
get <JAIL> maxmatches gets the max number of matches
stored in memory per ticket in
<JAIL>
get <JAIL> maxlines gets the number of lines to buffer
for <JAIL>
get <JAIL> actions gets a list of actions for <JAIL>
COMMAND ACTION INFORMATION
get <JAIL> action <ACT> actionstart gets the start command for the
action <ACT> for <JAIL>
get <JAIL> action <ACT> actionstop gets the stop command for the
action <ACT> for <JAIL>
get <JAIL> action <ACT> actioncheck gets the check command for the
action <ACT> for <JAIL>
get <JAIL> action <ACT> actionban gets the ban command for the
action <ACT> for <JAIL>
get <JAIL> action <ACT> actionunban gets the unban command for the
action <ACT> for <JAIL>
get <JAIL> action <ACT> timeout gets the command timeout in
seconds for the action <ACT> for
<JAIL>
GENERAL ACTION INFORMATION
get <JAIL> actionproperties <ACT> gets a list of properties for the
action <ACT> for <JAIL>
get <JAIL> actionmethods <ACT> gets a list of methods for the
action <ACT> for <JAIL>
get <JAIL> action <ACT> <PROPERTY> gets the value of <PROPERTY> for
the action <ACT> for <JAIL>
Report bugs to https://github.com/fail2ban/fail2ban/issues
Report bugs to https://github.com/fail2ban/fail2ban/issues