Nginx 安全加固详细配置指南

一、IP 白名单配置

nginx 复制代码
http {
    # 定义允许访问的 CIDR 地址列表
    geo $whitelist {
        default 0;
        192.168.1.0/24 1;
        10.0.0.0/8 1;
        2001:db8::/32 1; # IPv6 示例
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            # 白名单验证逻辑
            if ($whitelist = 0) {
                return 403;
            }

            # 反向代理配置
            proxy_pass http://backend;
        }
    }
}

关键点说明

  1. geo 模块优于 allow/deny 指令,支持 CIDR 格式
  2. IPv4/IPv6 双栈需分开配置
  3. 生产环境建议将 IP 列表存储在单独文件用 include 引入

二、基础认证配置

nginx 复制代码
server {
    listen 80;
    server_name secure.example.com;

    # 生成密码文件命令:sudo htpasswd -c /etc/nginx/auth/.htpasswd user1
    auth_basic "Restricted Area";
    auth_basic_user_file /etc/nginx/auth/.htpasswd;

    location /admin {
        # 对特定路径加强认证
        auth_basic "Admin Panel";
        allow 192.168.1.100;  # 叠加 IP 白名单
        deny all;
    }
}

安全建议

  1. 密码文件应存储在非 web 目录
  2. 文件权限设置为 640(chmod 640 .htpasswd
  3. 配合 SSL 使用避免密码明文传输

三、DDoS 防护配置

1. 全局请求频率限制

nginx 复制代码
http {
    # 定义共享内存区(1MB 存储约 16,000 个状态)
    limit_req_zone $binary_remote_addr zone=global_rate:10m rate=100r/s;

    server {
        location / {
            # 基础限速配置
            limit_req zone=global_rate burst=200 nodelay;
        }

        location /api/ {
            # 敏感接口更严格限制
            limit_req zone=global_rate burst=50 delay=20;
            limit_req_status 429;
        }
    }
}

2. 连接数限制

nginx 复制代码
http {
    # 连接数共享内存区
    limit_conn_zone $binary_remote_addr zone=addr_conn:10m;

    server {
        limit_conn addr_conn 20;  # 单 IP 最大连接数
        limit_conn_status 444;    # 返回特定状态码

        location /download/ {
            # 下载专用连接限制
            limit_conn addr_conn 5;
            limit_rate_after 10m; # 下载限速策略
        }
    }
}

3. 多维度防护策略组合

nginx 复制代码
http {
    # 定义不同防护区域
    limit_req_zone $binary_remote_addr zone=search_rate:10m rate=2r/s;
    limit_conn_zone $binary_remote_addr zone=search_conn:10m;

    server {
        location /search {
            # 复合防护策略
            limit_req zone=search_rate burst=10 nodelay;
            limit_conn search_conn 5;
            limit_conn_log_level warn;  # 记录警告级别日志
        }
    }
}

四、最佳实践建议

  1. 渐进式配置

    nginx 复制代码
    # 分阶段实施限流策略
    limit_req zone=global_rate burst=50 nodelay;
    # 监控后逐步调整为:
    limit_req zone=global_rate burst=30 delay=10;
  2. 动态白名单管理

    bash 复制代码
    # 使用 fail2ban 动态更新白名单
    fail2ban-regex /var/log/nginx/access.log '<HOST>.* 444'
  3. 日志分析配置

    nginx 复制代码
    log_format security '$remote_addr - $http_x_forwarded_for - [$time_local] '
                        '"$request" $status $body_bytes_sent '
                        '"$http_referer" "$http_user_agent" '
                        'Rate: $limit_req_status Conn: $limit_conn_status';
    
    access_log /var/log/nginx/security.log security;
  4. 压力测试验证

    bash 复制代码
    # 使用 siege 进行压力测试
    siege -c 100 -t 2M http://example.com/api/v1

五、常见问题解决方案

  1. 误拦截合法流量

    • 使用 map 模块排除 CDN IP
    • 配置 limit_req_dry_run on 进行试运行
  2. 性能优化

    nginx 复制代码
    # 调整共享内存大小(每个 IP 约占用 128 bytes)
    limit_req_zone $binary_remote_addr zone=api_rate:20m rate=100r/s;
  3. 云环境适配

    nginx 复制代码
    # 获取真实客户端 IP(适用于 Cloudflare 等 CDN)
    set_real_ip_from 103.21.244.0/22;
    real_ip_header CF-Connecting-IP;
  4. 状态码自定义

    nginx 复制代码
    # 返回 JSON 格式错误信息
    error_page 429 = @ratelimit;
    location @ratelimit {
        default_type application/json;
        return 429 '{"error": "Too Many Requests", "code": 429}';
    }

六、完整配置示例

nginx 复制代码
http {
    # 全局防护设置
    limit_req_zone $binary_remote_addr zone=global_req:10m rate=50r/s;
    limit_conn_zone $binary_remote_addr zone=global_conn:10m;

    # IP 白名单
    geo $whitelist {
        default 0;
        include /etc/nginx/conf.d/ip_whitelist.conf;
    }

    server {
        listen 443 ssl;
        server_name example.com;

        # SSL 配置
        ssl_certificate /etc/ssl/certs/example.com.crt;
        ssl_certificate_key /etc/ssl/private/example.com.key;

        # 全局限制
        limit_conn global_conn 100;
        limit_req zone=global_req burst=100 nodelay;

        location / {
            # 白名单验证
            if ($whitelist = 0) {
                return 403;
            }

            # 基础认证
            auth_basic "Restricted Access";
            auth_basic_user_file /etc/nginx/auth/.htpasswd;

            # 反向代理
            proxy_pass http://backend;
        }

        location /api/ {
            # 加强防护
            limit_req zone=global_req burst=20 delay=5;
            limit_conn global_conn 10;
            limit_rate 500k;

            # 访问日志记录
            access_log /var/log/nginx/api_access.log;
        }
    }
}

七、维护建议

  1. 定期审查访问日志:

    bash 复制代码
    # 分析限流触发情况
    grep "429" /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -nr
  2. 动态调整策略:

    bash 复制代码
    # 热更新配置(需编译时包含 --with-http_stub_status_module)
    nginx -s reload
  3. 系统级优化:

    bash 复制代码
    # 调整文件描述符限制
    sysctl -w fs.file-max=100000
    ulimit -n 65535
  4. 安全审计工具:

    bash 复制代码
    # 使用 naxsi 进行 WAF 防护
    git clone https://github.com/nbs-system/naxsi.git
相关推荐
PanZonghui5 小时前
Centos项目部署之Nginx 的安装与卸载
linux·nginx
charlee4416 小时前
nginx部署发布Vite项目
nginx·性能优化·https·部署·vite
CRMEB定制开发18 小时前
【实战】CRMEB Pro 企业版安装教程(附 Nginx 反向代理配置 + 常见问题解决)
nginx·商城系统·微信商城·crmeb
孙克旭_1 天前
day045-nginx跳转功能补充与https
linux·运维·nginx·https
博同学2 天前
Nginx + ELK + Grafana 全球访问热力图
nginx·elk·grafana
RW~2 天前
Minio安装配置,桶权限设置,nginx代理 https minio
运维·nginx·https·minio
CodeWithMe2 天前
Nginx入门进阶:从零到高手的实战指南
运维·nginx
Ahlson2 天前
【fnNAS】docker的nginx配置html
nginx·docker·容器·fnnas
斯普信专业组2 天前
K8s环境下基于Nginx WebDAV与TLS/SSL的文件上传下载部署指南
nginx·kubernetes·ssl
亦舒.2 天前
宝塔面板Nginx手动配置负载均衡实战指南
运维·nginx·负载均衡