mirror of
https://github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker.git
synced 2025-09-02 02:29:58 +00:00
Added wp-login filter and jail for Fail2Ban
This commit is contained in:
parent
8288e272dd
commit
7946acf381
7 changed files with 235 additions and 1 deletions
8
.travis.yml
Normal file
8
.travis.yml
Normal file
|
@ -0,0 +1,8 @@
|
|||
language: python
|
||||
cache:
|
||||
- directories:
|
||||
- nginx-cache
|
||||
rvm:
|
||||
- 2.1
|
||||
script: ./test-nginx-config.sh
|
||||
sudo: false
|
|
@ -1,4 +1,5 @@
|
|||
# Fail2Ban Blacklist for Repeat Offenders of Nginx (action.d)
|
||||
#### also includes wp-login attack filter using [nginx-limit-req] - see lower down
|
||||
|
||||
### Author: Mitchell Krog <mitchellkrog@gmail.com>
|
||||
### Version: 1.1
|
||||
|
@ -50,4 +51,12 @@ findtime = 604800 ; 1 week
|
|||
maxretry = 20
|
||||
```
|
||||
|
||||
# Blocking wp-login.php attacks on Wordpress Sites
|
||||
See the included /filter.d/nginx-limit-req.conf jail and filter for detecting and blocking wp-login attacks
|
||||
The original /filter.d/nginx-limit-req.conf file from Fail2Ban is included including a /filter.d/nginx-limit-req.local file with the settings you need to detect and block wp-logins.
|
||||
An example of the jail settings for your jail.local file is included in the jail.local sample.
|
||||
This works great at picking up wp-login attacks.
|
||||
Be sure to add the rate limiting zone to your nginx.conf as per instructions in /filter.d/nginx-limit-req.local
|
||||
|
||||
|
||||
### If this helps you why not [buy me a beer](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=XP2AZ4S5HNAWQ):beer:
|
44
Fail2Ban/filter.d/nginx-limit-req.conf
Normal file
44
Fail2Ban/filter.d/nginx-limit-req.conf
Normal file
|
@ -0,0 +1,44 @@
|
|||
# Fail2ban filter configuration for nginx :: limit_req
|
||||
# used to ban hosts, that were failed through nginx by limit request processing rate
|
||||
#
|
||||
# Author: Serg G. Brester (sebres)
|
||||
#
|
||||
# To use 'nginx-limit-req' filter you should have `ngx_http_limit_req_module`
|
||||
# and define `limit_req` and `limit_req_zone` as described in nginx documentation
|
||||
# http://nginx.org/en/docs/http/ngx_http_limit_req_module.html
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# http {
|
||||
# ...
|
||||
# limit_req_zone $binary_remote_addr zone=lr_zone:10m rate=1r/s;
|
||||
# ...
|
||||
# # http, server, or location:
|
||||
# location ... {
|
||||
# limit_req zone=lr_zone burst=1 nodelay;
|
||||
# ...
|
||||
# }
|
||||
# ...
|
||||
# }
|
||||
# ...
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
||||
# Specify following expression to define exact zones, if you want to ban IPs limited
|
||||
# from specified zones only.
|
||||
# Example:
|
||||
#
|
||||
# ngx_limit_req_zones = lr_zone|lr_zone2
|
||||
#
|
||||
ngx_limit_req_zones = [^"]+
|
||||
|
||||
# Use following full expression if you should range limit request to specified
|
||||
# servers, requests, referrers etc. only :
|
||||
#
|
||||
# failregex = ^\s*\[error\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(, referrer: "\S+")?\s*$
|
||||
|
||||
# Shortly, much faster and stable version of regexp:
|
||||
failregex = ^\s*\[error\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>
|
||||
|
||||
ignoreregex =
|
16
Fail2Ban/filter.d/nginx-limit-req.local
Normal file
16
Fail2Ban/filter.d/nginx-limit-req.local
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Fail2ban filter for detecting abuse against wp-login.php attempts
|
||||
# Author: Serg G. Brester (sebres)
|
||||
# https://github.com/fail2ban/fail2ban
|
||||
|
||||
# Add into your nginx.conf file the following rate limiting zone
|
||||
|
||||
# limit_req_zone $binary_remote_addr zone=wp-login:10m rate=1r/s;
|
||||
|
||||
# see jail.local example for the config of this jail
|
||||
[Definition]
|
||||
|
||||
ngx_limit_req_zones = wp-login
|
||||
|
||||
failregex = ^\s*\[error\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>
|
||||
|
||||
ignoreregex =
|
|
@ -11,4 +11,13 @@ filter = nginxrepeatoffender
|
|||
banaction = nginxrepeatoffender
|
||||
bantime = 86400 ; 1 day
|
||||
findtime = 604800 ; 1 week
|
||||
maxretry = 20
|
||||
maxretry = 20
|
||||
|
||||
# This is the jail setting for using the Fail2Ban limit-req filter for detecting wp-login attacks
|
||||
|
||||
[nginx-limit-req]
|
||||
enabled = true
|
||||
port = http,https
|
||||
filter = nginx-limit-req
|
||||
logpath = %(nginx_error_log)s
|
||||
maxretry = 1
|
114
nginx.conf
Normal file
114
nginx.conf
Normal file
|
@ -0,0 +1,114 @@
|
|||
user www-data;
|
||||
worker_processes auto;
|
||||
error_log /tmp/error.log;
|
||||
pid /tmp/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
multi_accept on;
|
||||
use epoll;
|
||||
}
|
||||
|
||||
http {
|
||||
|
||||
##
|
||||
# Basic Settings
|
||||
##
|
||||
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
keepalive_timeout 90s;
|
||||
keepalive_requests 1000;
|
||||
server_tokens off;
|
||||
client_body_buffer_size 32k;
|
||||
client_header_buffer_size 1k;
|
||||
client_max_body_size 50M;
|
||||
types_hash_max_size 2048;
|
||||
server_names_hash_bucket_size 64;
|
||||
server_names_hash_max_size 4096;
|
||||
large_client_header_buffers 4 16k;
|
||||
|
||||
# Our request limiter zone for wp-login attacks
|
||||
limit_req_zone $binary_remote_addr zone=wp-login:10m rate=1r/s;
|
||||
|
||||
# DDos Mitigation
|
||||
# ***************
|
||||
# https://www.nginx.com/blog/mitigating-ddos-attacks-with-nginx-and-nginx-plus/
|
||||
# Limiting the Rate of Requests
|
||||
limit_req_zone $ratelimited zone=flood:50m rate=90r/s;
|
||||
# Limiting the Number of Connections
|
||||
limit_conn_zone $ratelimited zone=addr:50m;
|
||||
# End Slow conections
|
||||
#client_body_timeout 5s;
|
||||
#client_header_timeout 5s;
|
||||
|
||||
|
||||
# use any of the following two
|
||||
real_ip_header CF-Connecting-IP;
|
||||
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
##
|
||||
# Logging Settings
|
||||
##
|
||||
log_format custom '$remote_addr - $http_x_forwarded_for $remote_user $server_port [$time_local] "$request" '
|
||||
'$status "$http_referer" "$http_user_agent" "$http_header"'
|
||||
'"$body_bytes_sent" - "$gzip_ratio"';
|
||||
|
||||
log_format timedcombined '$remote_addr - $http_cf_connecting_ip $remote_user [$time_local] '
|
||||
'"$request" $status $body_bytes_sent '
|
||||
'"$http_referer" "$http_user_agent" '
|
||||
'PORT:$server_port $request_time $upstream_response_time $pipe "$gzip_ratio"';
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
log_format wordpress '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"'
|
||||
'PORT:$server_port $request_time $upstream_response_time $pipe "GZIP:$gzip_ratio"';
|
||||
|
||||
access_log /var/log/nginx/access.log timedcombined;
|
||||
error_log /var/log/nginx/error.log;
|
||||
|
||||
##
|
||||
# Gzip Settings
|
||||
##
|
||||
|
||||
gzip on;
|
||||
gzip_disable "MSIE [1-6]\.";
|
||||
gzip_vary on;
|
||||
gzip_static on;
|
||||
gzip_min_length 20;
|
||||
gzip_proxied expired no-cache no-store private auth;
|
||||
gzip_comp_level 7;
|
||||
gzip_buffers 32 4k;
|
||||
gzip_http_version 1.1;
|
||||
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
#gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml;
|
||||
|
||||
##
|
||||
# Virtual Host Configs
|
||||
##
|
||||
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
include /etc/nginx/sites-enabled/*;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name fakedomain.com;
|
||||
root /var/www;
|
||||
limit_conn conn_limit_per_ip 10;
|
||||
limit_req zone=req_limit_per_ip burst=10 nodelay;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
34
test-nginx.sh
Executable file
34
test-nginx.sh
Executable file
|
@ -0,0 +1,34 @@
|
|||
#!/bin/bash
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
NGINX_CONFIG="${DIR}/nginx.conf"
|
||||
NGINX_CONFIG_LOG="/tmp/nginx-config-check.log"
|
||||
NGINX_CACHE_DIR="${DIR}/nginx-cache"
|
||||
NGINX_BINARY="${NGINX_CACHE_DIR}/nginx"
|
||||
NGINX_DEB_URL="https://nginx.org/packages/ubuntu/pool/nginx/n/nginx/nginx_1.10.0-1~trusty_amd64.deb"
|
||||
#NGINX_DEB_URL="https://launchpad.net/~ondrej/+archive/ubuntu/nginx-mainline/+build/10448355/+files/nginx-light_1.11.2-1~exp1+deb.sury.org~trusty+3_amd64.deb"
|
||||
|
||||
# Download nginx binary, if necessary
|
||||
mkdir -p ${NGINX_CACHE_DIR}
|
||||
if [[ ! -f "${NGINX_BINARY}" ]]; then
|
||||
DEB_TMP_PATH="/tmp/nginx.deb.$$"
|
||||
DEB_TMP_UNPACKED="/tmp/nginx-deb/"
|
||||
wget "${NGINX_DEB_URL}" -O "${DEB_TMP_PATH}"
|
||||
pushd /tmp
|
||||
mkdir -p "${DEB_TMP_UNPACKED}"
|
||||
dpkg-deb -R "${DEB_TMP_PATH}" $(basename "${DEB_TMP_UNPACKED}")
|
||||
cp "${DEB_TMP_UNPACKED}/usr/sbin/nginx" "${NGINX_BINARY}"
|
||||
popd
|
||||
fi
|
||||
|
||||
chmod +x ${NGINX_CACHE_DIR}/nginx
|
||||
${NGINX_CACHE_DIR}/nginx -t -c "${NGINX_CONFIG}" 2>${NGINX_CONFIG_LOG}
|
||||
|
||||
if [[ $(cat $NGINX_CONFIG_LOG | egrep "syntax is ok" | wc -l) -eq 1 ]]; then
|
||||
echo "Nginx configuration OK!"
|
||||
exit 0
|
||||
else
|
||||
echo -e "Nginx configuration invalid:\n"
|
||||
cat ${NGINX_CONFIG_LOG}
|
||||
exit 1
|
||||
fi
|
Loading…
Add table
Reference in a new issue