Skip to content

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)

  1. 编辑黑名单文件:
bash
sudo nano /etc/nginx/ip_blacklist
  1. 添加新IP:
8.153.202.105 1;
106.14.196.31 1;
# 新增IP
203.0.113.45 1;
198.51.100.0/24 1;
  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

高级配置:按国家封禁

  1. 安装 GeoIP 模块:
bash
# Ubuntu
sudo apt install libnginx-mod-http-geoip

# CentOS
sudo yum install nginx-mod-http-geoip
  1. 下载 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
  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

最佳实践

  1. 分层防御

    • 在 Nginx 前使用 Cloudflare 或 AWS WAF
    • 结合服务器防火墙(iptables)
    • 应用层添加额外验证
  2. 监控与分析

    bash
    # 实时监控黑名单访问
    tail -f /var/log/nginx/access.log | grep ' 403 '
    
    # 统计被封IP
    awk '{print $1}' /var/log/nginx/blocked.log | sort | uniq -c | sort -nr
  3. 定期维护

    • 每月审查黑名单,移除不再活跃的IP
    • 更新 GeoIP 数据库(每月一次)
    • 备份黑名单配置
  4. 性能考虑

    • 对于超过 10,000 个IP的大名单,考虑使用 ipset + iptables
    • 避免在Nginx中使用复杂正则表达式匹配

通过以上配置,你可以有效地管理和维护Nginx的IP黑名单,保护网站免受恶意流量的侵扰。