FORMA

安全基础

本文文件名为 se.md(security 缩写),对应本目录学习路径中「阶段 10:调优与安全」的安全部分;姊妹篇 seror.md(service error 缩写)为常见故障排查思路。核心概念见 Nginx 核心概念

Nginx 作为流量的总入口,安全配置是防线第一关。以下从六个基础维度加固你的服务,既实用又立竿见影。

一、隐藏版本信息

风险:报错页面或响应头中的 Server: nginx/1.xx.x 会暴露软件版本,方便攻击者利用已知漏洞。

配置

nginx
http {
    server_tokens off;
}

效果:响应头变为 Server: nginx,不再含有具体版本。可选地,通过第三方模块 headers-more-nginx-module 可以更彻底地修改或清除该头。

二、IP 访问控制

场景:管理后台、内部接口仅允许特定 IP 或网段访问;屏蔽已知恶意 IP。

指令allow / deny,从上到下依次匹配。

配置示例

nginx
location /admin {
    allow 192.168.1.0/24;
    allow 10.0.0.0/8;
    deny all;                 # 拒绝其余所有
}

location /internal-api {
    deny 192.168.1.100;       # 拒绝特定 IP
    allow all;
}

注意:在 CDN 或反向代理之后,客户端 IP 可能被隐藏,需配合 ngx_http_realip_module 获取真实 IP 后再做控制。

三、限制速率(防 CC 攻击)

通过限制单个 IP 的请求速率,防止恶意刷接口、撞库、CC 攻击。

1. 限制请求速率:limit_req_zone + limit_req

原理:基于共享内存的漏斗算法(leaky bucket),以固定速率处理请求,超过的返回 503 或延迟处理。

配置示例

nginx
http {
    # 定义限流区域:以客户端 IP 为键,10m 内存空间,每秒最多 10 个请求
    limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;

    server {
        location /api/ {
            limit_req zone=api_limit burst=20 nodelay;
            proxy_pass http://backend;
        }
    }
}
  • burst=20:允许瞬间突发 20 个请求排队,超过的直接拒绝。
  • nodelay:立即处理突发请求而不引入延迟,适合保持响应速度。

2. 限制并发连接:limit_conn

针对某个 IP 同时占用的连接数量,防止单 IP 占满所有连接。

配置示例

nginx
http {
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

    server {
        limit_conn conn_limit 10;         # 每个 IP 最多 10 个并发连接
        limit_conn_log_level warn;        # 达到限制时的日志级别
        limit_conn_status 503;            # 返回的状态码
    }
}

组合使用limit_req 控制请求速度,limit_conn 控制连接总数,能有效缓解大部分应用层 DDoS。

四、请求方法限制

目标:RESTful API 通常仅使用 GET/POST/PUT/DELETE 等,禁用 TRACE/TRACK 等危险方法,减少攻击面。

推荐方式一limit_except(专门用于限制方法)

nginx
location /api/ {
    limit_except GET POST PUT DELETE OPTIONS {
        deny all;
    }
}

limit_except 内的指令仅对其所列方法之外的方法生效,这里禁止了所有不允许的方法。

推荐方式二:简单 if 判断(注意 if 在 location 中的谨慎使用)

nginx
location /api/ {
    if ($request_method !~ ^(GET|POST|HEAD|OPTIONS)$) {
        return 405;            # 方法不被允许
    }
}

405 Method Not Allowed 比直接丢包更合规范。

五、HTTPS 安全头

全站 HTTPS 基础上,增加安全响应头,大幅提升浏览器安全防护等级。

1. HSTS(HTTP Strict-Transport-Security)

强制浏览器在指定时间内仅通过 HTTPS 访问该域名,杜绝 SSL 剥离攻击。

nginx
server {
    listen 443 ssl;
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
}
  • max-age=63072000:两年内强制 HTTPS。
  • includeSubDomains:对所有子域名也生效。
  • preload:允许加入浏览器内置 HSTS 预加载列表。 注意:首次启用前请确保所有子域名都已支持 HTTPS,否则会造成访问故障。

2. CSP(Content-Security-Policy)

限制页面能加载哪些资源,是防御 XSS 的核心手段。

nginx
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://trusted-cdn.com; style-src 'self' 'unsafe-inline'; img-src * data:; font-src 'self' data:; frame-ancestors 'none';";

策略需要根据业务定制,过严可能影响正常功能,建议先在报告模式测试。

3. 其他常用安全头

nginx
# 防止页面被嵌在 frame 中(防点击劫持)
add_header X-Frame-Options "SAMEORIGIN" always;

# 禁止浏览器猜测资源类型(防 MIME 混淆)
add_header X-Content-Type-Options "nosniff" always;

# 开启浏览器 XSS 过滤器并强制阻断
add_header X-XSS-Protection "1; mode=block" always;

# 限制 Referer 传递范围
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

最佳实践小结

  1. 在 http 块全局设置通用安全头,个别站点可覆盖。
  2. 限速配置务必测试,错杀正常用户会降低体验,可先设为较大值再逐步收紧。
  3. IP 控制前确认真实 IP 获取正确,在代理后面一定要用 real_ip_headerset_real_ip_from
  4. 安全头和限速生效后,可借助 curl -I 和浏览器 DevTools → Network 校验。

打好这些安全基础,你的 Nginx 就能从容应对绝大多数脚本小子和常见攻击,让后端服务安心运行。

七、验证安全配置是否生效

配置完成后,别只凭“看起来对”就上线,用命令实际核对:

bash
# 确认版本信息已隐藏
curl -I https://yourdomain | grep -i server

# 确认安全响应头齐全
curl -I https://yourdomain | grep -iE "strict-transport|x-frame|x-content-type"

# 简单压测确认限流生效(观察是否出现 503)
for i in $(seq 1 30); do curl -s -o /dev/null -w "%{http_code}\n" https://yourdomain/api/; done

也可以借助在线工具如 Mozilla ObservatorySSL Labs 对线上域名做一次外部视角的安全评分,弥补本地配置检查的盲区。

延伸阅读

参考文献

资料说明
nginx 文档官方
运维导读学习路径
Mozilla Observatory安全头在线评分