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后,才将includeSubDomains或preload添加到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方法
如果某个端点只接受GET和POST,则在那里拒绝其他方法。在每个location上执行此操作,以免破坏CORS预检请求或合法使用PUT、PATCH或DELETE的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的安全性还取决于其所在的主机:
- 仅在
ufw、firewalld、云安全组或网络ACL中允许必要的端口。 - 监控
/var/log/nginx/access.log和/var/log/nginx/error.log,查找峰值、重复的401/403响应和可疑路径。 - 当日志模式可以识别恶意客户端时,使用Fail2ban或类似工具。
- 在每次重新加载之前运行
sudo nginx -t,以确保安全更改不会导致站点离线。
要点
从HTTPS、更新、限制端口、安全标头和敏感路径(如/login)的速率限制开始。然后定期检查您的日志。大多数Nginx安全成果来自于稳定的维护和清晰的配置,而不是从其他站点复制一个大型加固文件。