Nginx 安全配置规范

Nginx 是一款功能强大且高效的 Web 服务器与反向代理服务器,广泛应用于各种生产环境。然而,默认配置可能无法满足高安全性的需求。本文将从多个方面探讨如何通过安全配置来提升 Nginx 的防护能力,确保服务器和应用的安全性。

为什么需要安全配置?

默认配置的 Nginx 虽然可以正常运行,但可能会暴露一些潜在的安全隐患,例如:

  • 泄露服务器版本信息
  • 缺乏对非法请求的过滤
  • 不安全的 SSL/TLS 配置

通过优化配置,可以显著减少攻击面,提升整体安全性。

基础安全配置

隐藏 Nginx 版本号

默认情况下,Nginx 会在响应头中暴露版本号信息。攻击者可利用该信息针对已知漏洞发动攻击。可以通过以下配置隐藏版本号:

http {
    server_tokens off;
}

设置文件与目录权限

确保 Nginx 的配置文件和日志文件仅对必要用户可读写:

sudo chmod 640 /etc/nginx/nginx.conf
sudo chmod 640 /var/log/nginx/*
sudo chown -R root:nginx /etc/nginx /var/log/nginx

此外,避免直接将敏感目录(如 /etc/var/www)暴露给外部访问。

限制访问范围

通过 IP 白名单或黑名单限制访问敏感资源:

location /admin {
    allow 192.168.1.0/24;
    deny all;
}

防止信息泄露

自定义错误页面

默认的错误页面可能暴露服务器信息或路径结构。可以通过自定义错误页面减少信息泄露:

error_page 404 /custom_404.html;
location = /custom_404.html {
    root /var/www/errors;
    internal;
}

禁用未使用的 HTTP 方法

关闭未使用的 HTTP 方法,如 TRACE,以防止跨站脚本攻击:

if ($request_method !~ ^(GET|POST|HEAD)$ ) {
    return 405;
}

HTTPS 安全配置

启用强制 HTTPS

通过 HTTP 强制重定向到 HTTPS:

server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

配置强加密算法

使用现代加密协议和算法:

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;

配置 HSTS

启用 HTTP 严格传输安全(HSTS):

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";

防止 DDoS 攻击

限制请求速率 (limit_req)

作用:控制来自同一来源(例如一个IP地址)的请求数量在一定时间内的最大值。 通过 limit_req 模块限制单个客户端的请求速率:

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
    server {
        location / {
            limit_req zone=one burst=20 nodelay;
        }
    }
}

配置参数解释

  • zone=one:引用了之前定义的一个速率限制区,该区设定了每秒允许的最大请求数(如 rate=10r/s)。
  • burst=5:允许超过设定速率的额外请求数量,这些请求将被暂时排队处理而不是立即拒绝。一旦有空闲的时间窗口,队列中的请求就会被处理。
  • nodelay:当设置了这个参数后,任何超过突发缓冲区的请求将立即返回错误状态码,而不会等待缓冲区有空位。这可以减少延迟,适用于对响应时间敏感的应用场景。

并发连接限制(limit_conn)

作用:限制单个客户端(通常基于IP地址)在同一时间内可以与服务器建立的最大活动连接数。

配置参数解释

  • addr:引用了一个定义好的并发连接限制区,这里指的是根据客户端IP地址来限制。
  • 5:表示每个客户端最多只能同时保持5个活动连接。

通过 limit_conn 模块限制每个 IP 的最大并发连接数:

http {
    limit_conn_zone $binary_remote_addr zone=addr:10m;
    server {
        location / {
            limit_conn addr 10;
        }
    }
}

区别总结

limit_req 主要用来防止爬虫或其他自动化工具通过快速发送大量请求来淹没服务器,它关注的是单位时间内请求的数量。 limit_conn 则是用来确保任何一个客户端不会占用过多的资源,特别是对于那些可能会长时间维持连接的应用(如WebSocket、长轮询等),它关注的是同一时刻活跃连接的数量。 是否需要设置 burst=5 nodelay?

这取决于您的具体需求:

如果您希望对短时间内爆发式增长的请求做出即时反应,并且您的应用程序能够容忍一定程度上的高频率请求突然出现,那么设置 burst=5 nodelay 是合理的。它可以防止合法用户的偶尔峰值流量导致不必要的失败,同时也保证了系统的即时响应性。 然而,如果您担心某些用户或自动化工具可能会利用突发机制绕过速率限制,或者您的应用对延迟非常敏感,那么您可以考虑不使用 burst 或者去掉 nodelay 参数。这样,所有超出速率限制的请求都会被排队,直到有可用的“令牌”为止。

通常情况下,结合使用这两种限制方法能更全面地保护您的网站免受滥用。以下是一个综合配置的例子:

http {
    # 定义速率限制区
    limit_req_zone $binary_remote_addr zone=req_zone:10m rate=10r/s;

    # 定义并发连接限制区
    limit_conn_zone $binary_remote_addr zone=conn_zone:10m;

    server {
        location / {
            # 应用速率限制,允许短暂爆发并即时响应
            limit_req zone=req_zone burst=5 nodelay;

            # 应用并发连接限制
            limit_conn conn_zone 5;

            # 其他配置...
        }
    }
}

这种配置既能有效地限制请求速率,又能控制并发连接数量,从而更好地抵御恶意行为,同时不影响正常用户的体验。请根据实际应用场景调整这些数值以找到最适合您网站需求的平衡点。

日志与监控

启用详细日志

记录所有访问和错误信息:

access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;

配置日志轮替

防止日志文件占用过多磁盘空间,可使用 Linux 的 logrotate 工具配置日志轮替。

其他安全建议

使用最新版本

定期更新 Nginx 以获取最新的安全补丁:

sudo apt update && sudo apt upgrade nginx

使用 WAF(Web 应用防火墙)

集成如 ModSecurity 的 WAF 工具,为 Nginx 增加额外的攻击防护。

隔离运行环境

建议以低权限用户运行 Nginx,并使用 chroot 或容器技术进一步隔离运行环境。

阻止恶意 IP

  1. 分析访问日志:
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head(前10条,可以去掉查询所有)

加入黑名单: 在 Nginx 配置中添加

deny 1.2.3.4; # 恶意 IP
deny 5.6.7.8;

总结

通过上述配置,可以显著提升 Nginx 的安全性,减少潜在风险。在实际生产环境中,需根据具体需求和场景灵活调整配置。安全是一个持续优化的过程,定期审计与更新是确保系统安全的关键。