用 Nginx 日志监控网络攻击的实操方案
一 基础准备与日志规范
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log;
二 快速发现攻击的常用方法
tail -f /var/log/nginx/access.loggrep -E " 404|403|500 " /var/log/nginx/access.log | tail -n 50tail -n 200 /var/log/nginx/error.log三 自动化检测与封禁
[nginx-http-auth]
enabled = true
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 5
bantime = 3600
[nginx-badbots]
enabled = true
filter = nginx-badbots
logpath = /var/log/nginx/access.log
maxretry = 100
findtime = 600
bantime = 86400
LOG_FILE="/var/log/nginx/access.log"
TIME_WINDOW=$(date --date='1 minute ago' "+%d/%b/%Y:%H:%M")
THRESHOLD=200
BAN_TIME=3600
WHITELIST=("127.0.0.1" "192.168.0.0/24")
is_whitelisted() {
local ip=$1
for w in "${WHITELIST[@]}"; do
if [[ $w == *"/"* ]]; then
ipcalc -nb "$w" "$ip" 2>/dev/null | grep -q "YES" && return 0
elif [[ $ip == $w ]]; then
return 0
fi
done
return 1
}
grep "$TIME_WINDOW" "$LOG_FILE" | awk '{print $1}' | sort | uniq -c | sort -nr | while read cnt ip; do
if ! is_whitelisted "$ip" && [ "$cnt" -gt "$THRESHOLD" ]; then
iptables -C INPUT -s "$ip" -j DROP 2>/dev/null || {
iptables -A INPUT -s "$ip" -j DROP
echo "$(date) BAN $ip ($cnt req/min)" >> /var/log/nginx/ban.log
(sleep "$BAN_TIME"; iptables -D INPUT -s "$ip" -j DROP) &
}
fi
done
四 集中化监控与可视化
五 防护加固与最佳实践