服务安全详解#


Nginx 作为全球使用最广泛的 Web 服务器之一,承载着无数网站和应用的流量入口。然而,默认配置往往存在安全隐患。本文将结合实际生产环境经验,系统性地讲解 Nginx 安全加固的各个维度,帮助读者构建一个安全可靠的 Web 服务。

⚠️ 声明:本文所有配置示例均为通用模板,请根据实际环境调整,切勿直接照搬。


一、基础安全配置#

1.1 以非特权用户运行#

Nginx master 进程以 root 启动,但 worker 进程应使用普通用户:

# 使用专用用户运行 worker 进程
user nginx nginx;

# 或者使用 www-data
user www-data www-data;

即使 worker 进程被攻破,攻击者也仅有普通用户权限,无法控制系统核心。

1.2 隐藏版本信息#

暴露具体版本号会给攻击者提供定向攻击的依据:

# 关闭版本号显示
server_tokens off;

# 同时在编译时可以修改版本标识
# ./configure --with-cc-opt='-DNGX_HTTP_SERVER_STRING="Server: Custom"'

1.3 限制进程打开文件数#

# 单个 worker 进程最大打开文件数
worker_rlimit_nofile 65535;

二、访问控制与请求限制#

2.1 限制请求方法和大小#

# 只允许常见的 HTTP 方法
if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE)$) {
    return 405;
}

# 限制请求体大小(防止大文件上传攻击)
client_max_body_size 10M;

# 限制请求头缓冲区
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;

2.2 速率限制#

防止暴力破解和 CC 攻击的核心配置:

# 定义限流区域(http 块中)
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

# 应用限流(server 或 location 块中)
location /api/ {
    limit_req zone=api_limit burst=20 nodelay;
    limit_conn conn_limit 10;
    proxy_pass http://backend;
}

# 针对登录接口更严格的限制
location /login {
    limit_req zone=api_limit burst=5 nodelay;
    # 额外增加延迟验证
    auth_request /auth;
}

参数说明

参数 说明
rate=10r/s 每秒允许 10 个请求
burst=20 允许突发 20 个请求排队
nodelay 突发请求立即处理,否则会延迟

2.3 连接数限制#

# 限制同一 IP 的并发连接数
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn perip 10;

# 限制同一虚拟服务器的总连接数
limit_conn_zone $server_name zone=perserver:10m;
limit_conn perserver 1000;

三、敏感路径与文件保护#

3.1 禁止访问隐藏文件#

# 禁止所有以点开头的文件/目录(.git, .env, .htaccess 等)
location ~ /\. {
    deny all;
    access_log off;
    log_not_found off;
}

3.2 保护敏感文件类型#

# 禁止访问备份、配置、日志等文件
location ~* \.(bak|config|sql|log|sh|inc|swp|old|save|orig|tmp)$ {
    deny all;
    return 404;
}

# 保护系统文件
location ~* (composer\.json|composer\.lock|package\.json|package-lock\.json|Dockerfile|\.env) {
    deny all;
    return 404;
}

3.3 限制目录列表#

# 禁止自动列出目录内容
autoindex off;

# 针对特定目录可开启(如文件下载站)
location /downloads/ {
    autoindex on;
    autoindex_exact_size off;
    autoindex_localtime on;
}

3.4 防止图片盗链#

location ~* \.(jpg|jpeg|png|gif|webp)$ {
    valid_referers none blocked *.example.com example.com;
    if ($invalid_referer) {
        return 403;
        # 或者返回防盗链图片
        # rewrite ^/.*$ /images/hotlink.jpg break;
    }
}

四、HTTPS 与 SSL/TLS#

4.1 强制 HTTPS 跳转#

# HTTP 强制跳转 HTTPS
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 301 https://$host$request_uri;
}

4.2 现代 SSL/TLS 配置#

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com;

    # 证书配置
    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/private.key;

    # 只启用 TLS 1.2 和 1.3
    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;

    # Session 缓存
    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    # OCSP Stapling(加快证书验证)
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /path/to/chain.pem;

    # DNS 解析器(用于 OCSP)
    resolver 8.8.8.8 1.1.1.1 valid=300s;
    resolver_timeout 5s;
}

4.3 HSTS 配置(可选)#

# 严格传输安全(分阶段启用)
# 阶段1:测试期(5分钟)
add_header Strict-Transport-Security "max-age=300" always;

# 阶段2:短期(1天)
add_header Strict-Transport-Security "max-age=86400" always;

# 阶段3:正式期(1年,包含子域名)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

⚠️ 重要提示:启用 preload 前请确保:

  • 所有子域名均支持 HTTPS
  • 证书长期有效且不会间断
  • 确定永远不会回退到 HTTP

五、安全响应头#

这是经常被忽视但极其重要的安全层:

server {
    # 防止点击劫持
    add_header X-Frame-Options "SAMEORIGIN" always;

    # 启用 XSS 过滤器
    add_header X-XSS-Protection "1; mode=block" always;

    # 防止 MIME 类型嗅探
    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;

    # 内容安全策略(根据实际需求定制)
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:" always;

    # 跨域资源策略
    add_header Cross-Origin-Resource-Policy "same-origin" always;

    # 跨域嵌入策略
    add_header Cross-Origin-Embedder-Policy "require-corp" always;

    # 跨域打开策略
    add_header Cross-Origin-Opener-Policy "same-origin" always;
}

六、日志监控#

6.1 合理的日志配置#

# 自定义日志格式(包含更多安全相关信息)
log_format security '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    '$request_time $upstream_response_time '
                    '$ssl_protocol $ssl_cipher '
                    '"$http_x_forwarded_for"';

# 访问日志
access_log /var/log/nginx/access.log security buffer=32k flush=5s;

# 错误日志级别:warn(记录警告及以上)
error_log /var/log/nginx/error.log warn;

6.2 异常请求监控#

# 记录 404 请求(用于发现扫描行为)
location / {
    # ... 正常配置
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
}

# 单独记录攻击尝试
map $status $log_4xx {
    ~^4  1;
    default 0;
}

access_log /var/log/nginx/attack.log combined if=$log_4xx;

6.3 日志分析#

#!/bin/bash
# 分析扫描行为

# 查找可疑的 404 扫描
echo "=== 可疑扫描 IP TOP10 ==="
grep " 404 " /var/log/nginx/access.log |     awk '{print $1}' | sort | uniq -c | sort -rn | head -10

# 查找暴力破解尝试
echo "=== 登录接口请求 TOP10 ==="
grep "POST /login" /var/log/nginx/access.log |     awk '{print $1}' | sort | uniq -c | sort -rn | head -10

# 查找 SQL 注入尝试
echo "=== SQL 注入特征请求 ==="
grep -i "select\|union\|insert\|drop\|--\|#" /var/log/nginx/access.log

七、防御常见攻击#

7.1 防止 SQL 注入(WAF 级规则)#

# 基础 SQL 注入过滤规则
set $block_sql_inject 0;
if ($query_string ~* "(\bselect\b.*\bfrom\b|\bunion\b.*\bselect\b|information_schema|benchmark\()") {
    set $block_sql_inject 1;
}
if ($block_sql_inject = 1) {
    return 403;
}

7.2 防止路径遍历#

# 禁止目录遍历
location ~* \.(\.|%2e|%2E){2}(/|%2f|%2F) {
    deny all;
    return 404;
}

# 规范化 URI
location ~* (\.\./|\.\.\\) {
    deny all;
}

7.3 防止 User-Agent 扫描#

# 拦截常见扫描工具
if ($http_user_agent ~* (nikto|sqlmap|nessus|nmap|acunetix|wpscan|dirbuster|gobuster)) {
    return 444;  # Nginx 特殊状态码,直接断开连接
}

7.4 慢速攻击防护#

# 设置客户端请求超时
client_body_timeout 10s;   # 读取请求体超时
client_header_timeout 10s; # 读取请求头超时
send_timeout 10s;          # 发送响应超时

# 限制请求体大小(防大包攻击)
client_max_body_size 1M;

八、代理安全#

Nginx 反向代理#

location /api/ {
    proxy_pass http://backend;

    # 传递真实客户端 IP
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # 隐藏后端服务器信息
    proxy_hide_header X-Powered-By;
    proxy_hide_header Server;

    # 限制代理超时(防慢连接)
    proxy_connect_timeout 5s;
    proxy_send_timeout 10s;
    proxy_read_timeout 10s;

    # 缓冲响应(防内存溢出)
    proxy_buffering on;
    proxy_buffer_size 4k;
    proxy_buffers 8 4k;
}

九、监控告警#

9.1 关键指标#

#!/bin/bash
# Nginx 安全监控脚本

# 监控异常状态码比例
TOTAL=$(tail -10000 /var/log/nginx/access.log | wc -l)
ERRORS=$(tail -10000 /var/log/nginx/access.log | grep -E " 40[0-9]| 50[0-9]" | wc -l)
ERROR_RATE=$((ERRORS * 100 / TOTAL))

if [ $ERROR_RATE -gt 20 ]; then
    echo "警告:错误率过高 ${ERROR_RATE}%"
    # 发送告警
fi

# 监控单个 IP 请求频率
tail -10000 /var/log/nginx/access.log |     awk '{print $1}' | sort | uniq -c | sort -rn |     awk '$1 > 200 {print "可疑 IP: "$2" 请求数:"$1}'

9.2 自动化封禁#

#!/bin/bash
# 自动封禁攻击 IP

# 封禁 5 分钟内请求超过 100 次的 IP
tail -5000 /var/log/nginx/access.log |     awk '{print $1}' | sort | uniq -c |     awk '$1 > 100 {print $2}' |     while read IP; do
        iptables -I INPUT -s $IP -j DROP
        echo "$(date): Banned $IP" >> /var/log/nginx/ban.log
    done

总结#

Nginx 安全加固是一个持续的过程,而非一次性的配置。随着攻击技术的演进和业务需求的变化,安全策略也需要不断调整和优化。

核心原则#

原则 说明
最小权限 只开放必要的端口和功能
纵深防御 不要依赖单一安全措施
持续监控 日志是最好的安全传感器
定期评估 定期检查和更新安全配置

🛡️ 记住:没有绝对的安全,只有相对的安全。重要的是建立及时发现、快速响应、持续改进的安全机制。