如何通过Nginx配置实现安全防护

avatar
作者
筋斗云
阅读量:2

Nginx 安全防护配置清单

一 基础加固

  • 非 root用户运行:在 nginx.conf 设置user nginx;,确保工作进程无特权。
  • 隐藏版本信息:在http块设置server_tokens off;,避免泄露 Nginx 版本。
  • 禁用目录列表:在需要的http/server/location中设置autoindex off;
  • 禁用 SSI:确保ssi off;,防止服务端包含执行。
  • 隐藏后端技术标识:对反向代理场景使用proxy_hide_header X-Powered-By;
  • 重定向不暴露端口:在http段设置port_in_redirect off;
  • 绑定特定接口:监听时明确指定listen 10.0.0.1:443;,避免默认0.0.0.0
  • 自定义错误页面:使用error_page 404 /404.html; location = /404.html { root html; },并准备友好的错误页面(建议**>512字节**,避免 IE 自带的友好页)。
  • 仅允许域名访问:设置默认 server 拦截非法 Host 头,返回403
  • 文件与日志权限:Nginx 根目录与配置仅nginx用户可写;日志文件属主为nginx,权限640,上级目录仅 nginx 可写。

二 访问控制与请求限制

  • IP 白名单/黑名单:在需要的location中使用allow/deny,规则自上而下匹配;可全局引入黑名单文件。
  • 限制 HTTP 方法:仅允许业务必需的GET/POST/HEAD,其余返回403/405
  • 请求频率限制:使用limit_req_zonelimit_req限制单 IP 请求速率,缓解暴力破解与爬虫。
  • 并发连接限制:使用limit_conn_zonelimit_conn限制单 IP 并发连接数。
  • 恶意特征拦截:对**$request_uri/$args中的 SQL 注入、XSS、路径遍历等特征以及异常User-Agent直接返回403**。
  • 可选增强:启用ngx_http_stub_status_module监控连接状态,结合日志分析异常。

三 传输加密与协议安全

  • 启用 HTTPS:配置ssl_certificate/ssl_certificate_key,监听443 ssl
  • 现代协议与套件:仅启用TLSv1.2/TLSv1.3,使用ECDHE等前向保密套件,设置ssl_prefer_server_ciphers on;
  • 会话复用与缓存:ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m;
  • HTTP 强制跳转:listen 80; return 301 https://$host$request_uri;
  • 证书管理:优先使用Let’s Encrypt等可信 CA,定期续期。

四 安全响应头与内容防护

  • 推荐安全头:
    • X-Frame-Options SAMEORIGIN(防点击劫持)
    • X-Content-Type-Options nosniff(防 MIME 嗅探)
    • X-XSS-Protection “1; mode=block”(浏览器 XSS 防护)
    • Strict-Transport-Security “max-age=31536000; includeSubDomains”(HSTS,建议开启)
    • 可选:Content-Security-Policy(按站点策略收紧资源加载)

五 快速可用的示例片段

# 1) 基础安全与错误页面
http {
  server_tokens off;
  autoindex off;
  ssi off;
  port_in_redirect off;

  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;

  # 2) 频率与并发限制
  limit_req_zone $binary_remote_addr zone=req:10m rate=10r/s;
  limit_conn_zone $binary_remote_addr zone=conn:10m;

  # 3) 黑名单示例(可单独文件引入)
  include /etc/nginx/blacklist_ip.conf;

  server {
    listen 80 default_server;
    server_name _;
    return 403;
  }

  server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate     /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:
                       ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:
                       ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
    ssl_prefer_server_ciphers on;
    ssl_session_timeout 1d;
    ssl_session_cache shared:MozSSL:10m;

    # 安全响应头
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # 仅允许域名访问(已在默认 server 拦截)

    # 管理后台 IP 白名单
    location /admin {
      allow 192.168.1.0/24;
      allow 203.0.113.10;
      deny all;
      # proxy_pass http://backend_admin;
    }

    # 限制方法
    if ($request_method !~ ^(GET|POST|HEAD)$) {
      return 405;
    }

    # 频率限制(突发 5,超阈值立即拒绝)
    location / {
      limit_req zone=req burst=5 nodelay;
      limit_conn conn 20;
      # proxy_pass http://backend;
    }

    # 恶意参数拦截
    set $block 0;
    if ($args ~* "(union|select|insert|update|delete|drop|truncate|or|and|exec)") { set $block 1; }
    if ($request_uri ~* "
                            jindouyun.cn. All Rights Reserved. 筋斗云 版权所有 |
                            粤ICP备13013545号 | 增值电信业务经营许可证:
                            粤B1-20215235 |
                            公网安备粤公网安备 44070302000974号
                            
违法和不良信息举报中心违法和不良信息举报中心   24 小时违法和不良信息举报热线:4006783389,举报邮箱:jubao@jindouyun.cn
ipv6
嘿,我是微信客服!