如何使用Nginx和fail2ban确保WordPress安全
Zhongy0410
・9 分钟阅读
Nginx 3
在Nginx中,你需要添加新的日志格式,这将包含所有被阻塞的请求,包括IP地址;这应该进入http { }块。
/etc/nginx/nginx.conf
,http
部分:
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
(或类似的)。
bantime
和findtime
在我的示例中,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 。