如何使用Nginx和fail2ban确保WordPress安全

・9 分钟阅读

Nginx 3

在Nginx中,你需要添加新的日志格式,这将包含所有被阻塞的请求,包括IP地址;这应该进入http { }块。

/etc/nginx/nginx.confhttp部分:

log_format blocked '$time_local: Blocked request from $remote_addr $request';

你还需要在设置保护的站点的服务器{}块中使用以下规则:


# note: if you have posts with title matching these, turn them off or fine-tune
# them to exclude those

## Block SQL injections
location ~* union.*select.*( {
 access_log /var/log/nginx/blocked.log blocked;
 deny all;
}
location ~* union.*all.*select.* {
 access_log /var/log/nginx/blocked.log blocked;
 deny all;
}
location ~* concat.*( {
 access_log /var/log/nginx/blocked.log blocked;
 deny all;
}

## Block common exploits
location ~* (<|%3C).*script.*(>|%3E) {
 access_log /var/log/nginx/blocked.log blocked;
 deny all;
}
location ~* base64_(en|de)code(.*) {
 access_log /var/log/nginx/blocked.log blocked;
 deny all;
}
location ~* (%24&x) {
 access_log /var/log/nginx/blocked.log blocked;
 deny all;
}
location ~* (%0|%A|%B|%C|%D|%E|%F|127.0) {
 access_log /var/log/nginx/blocked.log blocked;
 deny all;
}
location ~* ../ {
 access_log /var/log/nginx/blocked.log blocked;
 deny all;
}
location ~* ~$ {
 access_log /var/log/nginx/blocked.log blocked;
 deny all;
}
location ~* proc/self/environ {
 access_log /var/log/nginx/blocked.log blocked;
 deny all;
}
location ~* /.(htaccess|htpasswd|svn) { log_not_found off;
 access_log /var/log/nginx/blocked.log blocked;
 deny all;
}

## Block file injections
location ~* [a-zA-Z0-9_]=(..//?)+ {
 access_log /var/log/nginx/blocked.log blocked;
 deny all;
}
location ~* [a-zA-Z0-9_]=/([a-z0-9_.]//?)+ {
 access_log /var/log/nginx/blocked.log blocked;
 deny all;
}

## Block access to internal WordPress assets that isn't queried under normal
## circumstances
location ~* wp-config.php {
 access_log /var/log/nginx/blocked.log blocked;
 deny all;
}
location ~* wp-admin/includes {
 access_log /var/log/nginx/blocked.log blocked;
 deny all;
}
location ~* wp-app.log {
 access_log /var/log/nginx/blocked.log blocked;
 deny all;
}
location ~* (licence|readme|license).(html|txt) {
 access_log /var/log/nginx/blocked.log blocked;
 deny all;
}

## In case you have anything using sqlite as database you probably want to block
## direct access to those as well
location ~* .sqlite$ {
 access_log /var/log/nginx/blocked.log blocked;
 deny all;
}
location ~* ^/(SQLite|sqlite) {
 access_log /var/log/nginx/blocked.log blocked;
 deny all;
}
location ~* .sqlite-journal$ {
 access_log /var/log/nginx/blocked.log blocked;
 deny all;
}

fail2ban 4

将此监狱添加到jails配置:

/etc/fail2ban/jail.conf


[nginx-blocked]
enabled = true
port = 80,443
filter = nginx-blocked
logpath = /var/log/nginx/blocked.log
bantime = 3600
maxretry = 3
backend = auto
findtime = 86400
banaction = iptables-multiport
protocol = tcp
chain = INPUT

注意:logpath接受*作为通配符,如果你有更多的屏蔽日志。

并添加过滤器

/etc/fail2ban/filter.d/nginx-blocked.conf


[Definition]
failregex = ^.* Blocked request from .*$
ignoreregex =

对于nat banaction请参见fail2ban主机5

可选:syslog

如果你有多个网络服务器,你可能想集中这个。最简单的方法是让fail2ban运行在负载均衡上,Nginx登录到syslog,syslog推送到负载均衡的syslog ,对于那些熟悉syslog的人来说,这是一个例子,你可以替换上面的集合中的access_log行,其中的内容类似于:

access_log syslog:server=unix:/dev/log,facility=local7,tag=nginx,severity=warn blocked;

在nginx.conf和:

local7.warn /var/log/nginx/blocked.log

在你的rsyslog.conf中。

问题处理

注意:这些都应该作为root运行。

检查fail2ban是否正在运行

ps aux | grep fail2ban 应该显示一些类似 /usr/bin/python /usr/bin/fail2ban-server (或类似的)。

bantimefindtime

在我的示例中,bantime设置为一个小时,findtime设置为一天,你可能需要根据你的需要和流量来调整这个。

验证你的规则

如果你运行 fail2ban-regex -v [path-to-log] [path-to-filter-rule] 它应该输出如下内容:


Running tests
=============

Use failregex file : /etc/fail2ban/filter.d/nginx-blocked.conf
Use log file : /var/log/nginx.blocked.log


Results
=======

Failregex: 1452 total
|- #) [# of hits] regular expression
| 1) [1452] ^.*?Blocked request from  .*$
| 51.255.65.41 Sun Feb 19 06:31:05 2017

[ ... lots of IPs here ...]

| 157.55.39.20 Thu Feb 23 12:30:23 2017
`-

Ignoreregex: 0 total

Date template hits:
|- [# of hits] date format
| [2125] ISO 8601
| [2] Year/Month/Day Hour:Minute:Second
| [0] WEEKDAY MONTH Day Hour:Minute:Second[.subsecond] Year
| [0] WEEKDAY MONTH Day Hour:Minute:Second Year
| [0] WEEKDAY MONTH Day Hour:Minute:Second
| [0] MONTH Day Hour:Minute:Second
| [0] Day/Month/Year Hour:Minute:Second
| [0] Day/Month/Year2 Hour:Minute:Second
| [0] Day/MONTH/Year:Hour:Minute:Second
| [0] Month/Day/Year:Hour:Minute:Second
| [0] Year-Month-Day Hour:Minute:Second[,subsecond]
| [0] Year-Month-Day Hour:Minute:Second
| [0] Year.Month.Day Hour:Minute:Second
| [0] Day-MONTH-Year Hour:Minute:Second[.Millisecond]
| [0] Day-Month-Year Hour:Minute:Second
| [0] Month-Day-Year Hour:Minute:Second[.Millisecond]
| [0] TAI64N
| [0] Epoch
| [0] Hour:Minute:Second
| [0] 
| [0] YearMonthDay Hour:Minute:Second
| [0] Month-Day-Year Hour:Minute:Second
`-

Lines: 2127 lines, 0 ignored, 1452 matched, 675 missed

如果没有这些,正规表达式就不工作了。

查询fail2ban

Fail2ban提供一个程序名fail2ban-client来请求状态,因此:

fail2ban-client status nginx-blocked


Status for the jail: nginx-blocked
|- filter
| |- File list: /var/rlog/mekare.petermolnar.eu/nginx.blocked.log
| |- Currently failed: 68
| `- Total failed: 586
`- action
 |- Currently banned: 6
 | `- IP list: 122.167.147.40 176.93.112.88 193.154.116.218 203.118.160.75 79.122.16.39 157.55.39.20
 `- Total banned: 139

如果这是返回一些错误,那么客户端不能与服务器(检查套接字,也许将-s [socketpath]添加到客户端)通讯,或者service/jail没有运行。

转储iptables

当你确定IP应该已被阻止或被阻塞时,你还可以使用iptables-save检查iptables 。


  1. http://www-personal.umich.edu/~markmont/awp/

  2. http://wpscan.org/

  3. http://nginx.org/

  4. http://www.fail2ban.org/wiki/index.php/Main_Page

  5. https://petermolnar.net/linux-tech-coding/fail2ban-nat-hosts/

  6. http://aaronparecki.com/

Zhongy0410 profile image