4. Nginx安全配置:隐藏版本号、限制请求速率、配置白名单与黑名单、防止DDoS攻击的限流策略

聊到Nginx安全,很多人第一反应就是配个SSL证书完事。说实话,这远远不够。我在生产环境里见过太多Nginx裸奔的情况——版本号明晃晃地暴露着,请求速率不设限,黑白名单形同虚设。嗯,今天咱们就把这几个硬骨头啃下来。

4.1 隐藏版本号:别把底牌亮给对手

为什么要隐藏版本号?你想想看,攻击者知道你用的是Nginx 1.18.0,他直接去搜这个版本的已知漏洞,一打一个准。说白了,这就是在帮黑客缩小攻击范围。

核心配置:在 http 块或 server 块中添加:

server_tokens off;

我个人习惯再加一层保险,把默认的404页面也改掉:

# 隐藏版本号
server_tokens off;

# 自定义错误页面,避免泄露Nginx信息
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;

验证方法:配置完后,用 curl -I 你的域名 看看响应头里还有没有 Server: nginx/1.18.0 这样的信息。如果只剩 Server: nginx,说明配置生效了。

4.2 限制请求速率:别让一个IP拖垮整个服务

我在项目中遇到过,某个客户的后台接口被一个爬虫脚本疯狂调用,每秒发几百个请求,直接把数据库连接池打满了。后来怎么解决的?就是靠Nginx的限流模块。

Nginx的限流核心是 limit_req_zonelimit_req 指令。前者定义限流规则,后者在具体位置应用规则。

# 定义限流区域:每个IP每秒最多5个请求,超出部分延迟处理
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=5r/s;

server {
    location /api/ {
        limit_req zone=mylimit burst=10 nodelay;
        proxy_pass http://backend;
    }
}

这里解释一下参数:

  • rate=5r/s:每秒最多5个请求
  • burst=10:允许瞬间超过限制的请求数,最多10个
  • nodelay:超出burst的请求直接返回503,不排队等待

避坑指南:我曾经把burst设得太大,结果限流形同虚设。记住,burst是缓冲,不是让你敞开了用的。一般建议burst不超过rate的2-3倍。

4.3 配置白名单与黑名单:把门看好了

白名单和黑名单,说白了就是「谁可以进」和「谁不能进」的问题。我建议优先用白名单——只允许信任的IP访问敏感接口,其他的一律挡在外面。

4.3.1 IP黑名单

# 在 http 块或 server 块中
deny 192.168.1.100;
deny 10.0.0.0/8;
allow all;

4.3.2 IP白名单(更推荐)

# 只允许公司VPN IP访问管理后台
location /admin/ {
    allow 10.10.10.0/24;
    allow 172.16.0.0/12;
    deny all;
    proxy_pass http://admin_backend;
}

我的习惯:把黑白名单单独写到一个文件里,比如 block_ips.conf,然后在主配置里用 include 引入。这样维护起来方便,不用每次都改主配置文件。

4.4 防止DDoS攻击的限流策略

DDoS攻击,说白了就是拿海量请求把你的带宽或计算资源打满。Nginx虽然不能完全防住大流量DDoS,但对付应用层的CC攻击(Challenge Collapsar,挑战黑洞,即应用层慢速攻击)还是很有效的。

4.4.1 连接数限制

# 限制每个IP的并发连接数
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

server {
    location / {
        limit_conn conn_limit 10;
        # 每个IP最多10个并发连接
        proxy_pass http://backend;
    }
}

4.4.2 综合限流策略

我个人习惯把几种限流手段组合使用,效果更好:

# 1. 限制请求速率
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;

# 2. 限制并发连接数
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

# 3. 限制带宽(可选)
limit_rate 1m;

server {
    listen 80;
    server_name example.com;

    location / {
        limit_req zone=req_limit burst=20 nodelay;
        limit_conn conn_limit 10;
        limit_rate 500k;  # 每个连接限速500KB/s
        proxy_pass http://backend;
    }
}

4.4.3 应对慢速攻击

慢速攻击是DDoS的一种变种——攻击者建立连接后,慢慢发数据,拖住你的连接池。我遇到过最夸张的一次,2000个慢连接就把一台4核8G的服务器拖垮了。

# 设置客户端超时时间
client_body_timeout 10s;
client_header_timeout 10s;
send_timeout 10s;

# 限制请求体大小
client_max_body_size 1m;

注意:超时时间别设太短,否则正常用户上传大文件时会断连。10秒是个比较合理的值,你可以根据业务场景调整。

知识体系总览

下面这张图把Nginx安全配置的核心逻辑串起来了,你可以对照着检查自己的配置:

Nginx安全配置核心逻辑 Nginx安全配置 隐藏版本号 限制请求速率 黑白名单 DDoS防护 server_tokens off 自定义错误页 limit_req_zone burst + nodelay allow / deny include 独立文件 连接数限制 超时设置 带宽限制 组合使用效果更佳,不要只配一项

实战检查清单

最后,给你一份我平时用的检查清单,照着做基本不会漏:

检查项 配置指令 推荐值 优先级
隐藏版本号 server_tokens off
请求速率限制 limit_req_zone + limit_req 5-10 r/s
并发连接限制 limit_conn_zone + limit_conn 10-20
黑白名单 allow / deny 按需配置
超时设置 client_body_timeout 等 10s
带宽限制 limit_rate 500k-1m

最后说一句:配置完一定要测试。我见过太多人配完就扔那不管了,结果限流把自己正常用户给限了。用 ab 或 wrk 压一下,看看效果对不对。

专注资料整理