Nginx 安全最佳实践:保护您的 Web 服务器

利用必要的安全最佳实践保护您的 Nginx Web 服务器。本指南涵盖了保护 SSL/TLS 连接、实施有效的速率限制以防止滥用、缓解常见的 Web 攻击(如 XSS 和 SQL 注入),以及保持 Nginx 更新的关键重要性。了解可操作的步骤和配置示例,以增强服务器的安全性并保护您的在线形象。

Nginx安全最佳实践:保护您的Web服务器

您的Nginx服务器通常是用户和攻击者能够访问的第一个公共服务。这些Nginx安全最佳实践侧重于Nginx实际能够执行的控件:TLS、请求限制、标头、访问规则、更安全的默认设置和定期更新。

Nginx本身无法修复易受攻击的应用程序代码。将其视为应用程序、数据库、身份验证系统和主机防火墙之前的一层防护。

使用TLS保护连接

TLS加密浏览器与服务器之间的流量。使用受信任的证书,将HTTP重定向到HTTPS,并禁用过时的协议版本。

获取证书

对于公共网站,Let's Encrypt很常见,但任何受信任的证书颁发机构都可以使用。在许多Linux服务器上,Certbot将文件存储在/etc/letsencrypt/live/your_domain.com/下。

配置HTTPS

编辑您域名的服务器块。路径通常在Debian/Ubuntu系统上为/etc/nginx/sites-available/,在RHEL风格系统上为/etc/nginx/conf.d/

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;

    server_name your_domain.com www.your_domain.com;

    ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem;

    # 包含共享的TLS设置
    include /etc/nginx/snippets/ssl-params.conf;

    # ... 其他配置(根目录、location块等)
}

server {
    listen 80;
    listen [::]:80;
    server_name your_domain.com www.your_domain.com;

    # 将HTTP重定向到HTTPS
    return 301 https://$host$request_uri;
}

使用保守的TLS参数

您可以将共享的TLS设置保存在一个片段文件中,例如/etc/nginx/snippets/ssl-params.conf

# /etc/nginx/snippets/ssl-params.conf

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:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

# 启用HSTS(HTTP严格传输安全)
# 如果适用,添加includeSubDomains
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

# 启用OCSP装订以加快证书检查
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

# Diffie-Hellman参数(如果需要,生成一个强参数)
# ssl_dhparam /etc/nginx/ssl/dhparams.pem;

ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;

仅在您确认每个子域都支持HTTPS后,才将includeSubDomainspreload添加到HSTS。错误的HSTS部署可能会将用户锁定在旧子域之外。

实施速率限制

速率限制有助于减缓暴力破解尝试、爬虫和意外的请求洪泛。它不是完整的DDoS解决方案,但可以为您的应用程序提供更多的喘息空间。

基本速率限制示例

limit_req_zone定义共享状态,limit_req将限制应用于某个location。

http {
    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=5r/s;

    server {
        # ...

        location /login {
            limit_req zone=mylimit burst=10 nodelay;
            # ... 您的登录处理程序配置
        }

        location / {
            limit_req zone=mylimit burst=20 nodelay;
            # ... 您的主站点配置
        }
    }
}

在此示例中: $binary_remote_addr根据客户端IP地址进行限制。burst=10允许在平均速率之上有一个短暂的突发,nodelay拒绝过多的请求而不是延迟它们。

在负载均衡器或CDN后面要小心。如果Nginx只看到代理的IP地址,通过$binary_remote_addr进行速率限制可能会将所有用户视为一个客户端。在依赖基于客户端的限制之前,配置受信任的真实IP处理。

减少常见攻击面

Nginx可以减少暴露,但您的应用程序仍然需要输入验证、输出编码、参数化SQL、身份验证检查和依赖项修补。

添加安全标头

安全标头可以降低浏览器端风险:

add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

内容安全策略可以帮助防止XSS,但它必须与您的应用程序的脚本、样式、图像和第三方服务匹配。在将其应用于生产站点之前,先从仅报告模式开始。

谨慎阻止明显的扫描器

简单的模式匹配可以阻止嘈杂的扫描器,但它们不能替代WAF。保持规则狭窄,以免阻止合法用户。

http {
    # 定义用于阻止恶意机器人/扫描器的映射
    map $http_user_agent $bad_bot {
        default 0;
        "~*malicious_bot_pattern" 1;
        "~*another_suspicious_agent" 1;
    }

    server {
        # ...
        if ($bad_bot) {
            return 403;
        }
        # ...
    }
}

限制敏感路径

使用try_files,除非需要目录列表,否则保持autoindex off,并拒绝对永远不应提供的隐藏文件的访问。

location / {
    root /var/www/html;
    index index.html index.htm;
    try_files $uri $uri/ =404;
    autoindex off; # 禁用目录列表
}

# 限制对敏感文件访问的示例
location ~ /\.ht {
    deny all;
}

隐藏Nginx版本

server_tokens off从生成的错误页面中删除Nginx版本,并减少Server响应标头中的详细信息。

http {
    server_tokens off;
    # ...
}

在适当的地方限制HTTP方法

如果某个端点只接受GETPOST,则在那里拒绝其他方法。在每个location上执行此操作,以免破坏CORS预检请求或合法使用PUTPATCHDELETE的API端点。

location /api/ {
    # 只允许GET和POST
    if ($request_method !~ ^(GET|POST)$) {
        return 405;
    }
    # ...
}

保持Nginx更新

安全修复通常通过您的Linux发行版的软件包存储库提供。保持Nginx和OpenSSL相关软件包的修补,并在更新后测试重新加载。

对于Debian/Ubuntu:

sudo apt update
sudo apt upgrade nginx

对于CentOS/RHEL:

sudo dnf update nginx

在仍使用yum的较旧RHEL/CentOS版本上,使用yum update nginx

添加主机级保护

Nginx的安全性还取决于其所在的主机:

  • 仅在ufwfirewalld、云安全组或网络ACL中允许必要的端口。
  • 监控/var/log/nginx/access.log/var/log/nginx/error.log,查找峰值、重复的401/403响应和可疑路径。
  • 当日志模式可以识别恶意客户端时,使用Fail2ban或类似工具。
  • 在每次重新加载之前运行sudo nginx -t,以确保安全更改不会导致站点离线。

要点

从HTTPS、更新、限制端口、安全标头和敏感路径(如/login)的速率限制开始。然后定期检查您的日志。大多数Nginx安全成果来自于稳定的维护和清晰的配置,而不是从其他站点复制一个大型加固文件。