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
相关推荐
穿条秋裤到处跑4 小时前
前端连接websocket服务报错 Unexpected response code: 301
websocket·网络协议·nginx
YJQ99676 小时前
Nginx防盗链及HTTPS:保护网站内容安全与加密传输
nginx·安全·https
猿java9 小时前
什么是Nginx?它有哪些应用场景?
java·nginx·面试
绝顶少年9 小时前
反向代理、负载均衡与镜像流量:原理剖析、区别对比及 Nginx 配置实践
运维·nginx·负载均衡
天下·第二1 天前
【Nginx】负载均衡配置详解
运维·nginx·负载均衡
Hello.Reader1 天前
洞悉 NGINX ngx_http_access_module基于 IP 的访问控制实战指南
tcp/ip·nginx·http
PWRJOY1 天前
在 Ubuntu 24.04 系统上安装和管理 Nginx
linux·nginx·ubuntu
菠萝崽.2 天前
安装docker,在docker上安装mysql,docker上安装nginx
java·mysql·nginx·docker·软件工程·springboot·开发
java1234_小锋2 天前
什么是WebSocket?NGINX如何支持WebSocket协议?
websocket·网络协议·nginx
Hello.Reader2 天前
基于 Nginx 的 WebSocket 反向代理实践
运维·websocket·nginx