Nginx 配置 IP 黑名单的完整指南
在 Nginx 中配置 IP 黑名单是保护网站免受恶意访问的有效方法。以下是三种主要实现方式:
方法 1:使用 deny 指令(简单直接)
nginx
http {
# 创建黑名单IP列表
geo $blocked_ip {
default 0; # 默认允许访问
8.153.202.105 1;
106.14.196.31 1;
# 添加更多IP...
}
server {
listen 80;
server_name yourdomain.com;
# 应用IP黑名单
if ($blocked_ip) {
return 403; # 或者 return 444; (直接关闭连接)
}
location / {
# 正常配置...
}
}
}方法 2:使用单独的黑名单文件(推荐)
步骤 1:创建黑名单文件
bash
sudo nano /etc/nginx/conf.d/ip_blacklist.conf文件内容:
nginx
# /etc/nginx/conf.d/ip_blacklist.conf
geo $blocked_ip {
default 0;
include /etc/nginx/ip_blacklist; # 包含实际IP列表
}步骤 2:创建实际IP列表文件
bash
sudo nano /etc/nginx/ip_blacklist文件内容:
# 每行一个IP或网段
8.153.202.105 1;
106.14.196.31 1;
123.45.67.0/24 1; # 封禁整个网段步骤 3:在 Nginx 配置中应用
nginx
http {
include /etc/nginx/conf.d/ip_blacklist.conf;
server {
listen 80;
server_name yourdomain.com;
# 应用IP黑名单
if ($blocked_ip) {
# 可选:记录到单独日志
access_log /var/log/nginx/blocked.log;
return 403;
}
# 其他配置...
}
}方法 3:直接在 location 中使用 deny
nginx
server {
listen 80;
server_name yourdomain.com;
# 直接拒绝特定IP
deny 8.153.202.105;
deny 106.14.196.31;
deny 123.45.67.0/24;
# 允许所有其他IP
allow all;
location / {
# 正常配置...
}
}动态更新黑名单(无需重启 Nginx)
- 编辑黑名单文件:
bash
sudo nano /etc/nginx/ip_blacklist- 添加新IP:
8.153.202.105 1;
106.14.196.31 1;
# 新增IP
203.0.113.45 1;
198.51.100.0/24 1;- 重新加载 Nginx:
bash
sudo nginx -t && sudo nginx -s reload自动化脚本管理黑名单
bash
#!/bin/bash
# auto_block.sh - 自动添加恶意IP到Nginx黑名单
LOG_PATH="/var/log/nginx/access.log"
BLACKLIST="/etc/nginx/ip_blacklist"
# 提取10分钟内404错误超过10次的IP
malicious_ips=$(awk -vDate=$(date -d '10 minutes ago' +'%d/%b/%Y:%H:%M:%S') '$4 > Date && $9 == 404 {print $1}' $LOG_PATH | sort | uniq -c | awk '$1 > 10 {print $2}')
# 添加到黑名单
for ip in $malicious_ips; do
if ! grep -q "$ip" $BLACKLIST; then
echo "封禁恶意IP: $ip"
echo "$ip 1;" >> $BLACKLIST
fi
done
# 重新加载Nginx
nginx -t && nginx -s reload高级配置:按国家封禁
- 安装 GeoIP 模块:
bash
# Ubuntu
sudo apt install libnginx-mod-http-geoip
# CentOS
sudo yum install nginx-mod-http-geoip- 下载 GeoIP 数据库:
bash
mkdir -p /usr/share/GeoIP
wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.tar.gz
tar -zxvf GeoLite2-Country.tar.gz -C /usr/share/GeoIP --strip-components=1- Nginx 配置:
nginx
http {
geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
$geoip2_data_country_code country iso_code;
}
map $geoip2_data_country_code $blocked_country {
default 0;
CN 1; # 封禁中国IP
RU 1; # 封禁俄罗斯IP
# 添加更多国家代码...
}
server {
if ($blocked_country) {
return 403 "Access from your country is restricted";
}
}
}验证配置
bash
# 测试配置语法
sudo nginx -t
# 测试封禁效果
curl -I http://yourdomain.com -H "X-Forwarded-For: 8.153.202.105"
# 应返回 403 Forbidden
# 查看封禁日志
tail -f /var/log/nginx/blocked.log最佳实践
分层防御:
- 在 Nginx 前使用 Cloudflare 或 AWS WAF
- 结合服务器防火墙(iptables)
- 应用层添加额外验证
监控与分析:
bash# 实时监控黑名单访问 tail -f /var/log/nginx/access.log | grep ' 403 ' # 统计被封IP awk '{print $1}' /var/log/nginx/blocked.log | sort | uniq -c | sort -nr定期维护:
- 每月审查黑名单,移除不再活跃的IP
- 更新 GeoIP 数据库(每月一次)
- 备份黑名单配置
性能考虑:
- 对于超过 10,000 个IP的大名单,考虑使用
ipset+ iptables - 避免在Nginx中使用复杂正则表达式匹配
- 对于超过 10,000 个IP的大名单,考虑使用
通过以上配置,你可以有效地管理和维护Nginx的IP黑名单,保护网站免受恶意流量的侵扰。