ToolkitX
知识库工具箱

安全配置

访问控制、限流、WAF 基础

25min·高级

01. 访问控制——IP 黑白名单

Nginx 可以基于 IP 地址做访问控制——允许或拒绝特定 IP 的访问。这在限制管理后台只能内网访问、封禁恶意 IP 等场景特别好用。 allow——允许哪些 IP。deny——拒绝哪些 IP。规则按顺序执行,第一个匹配的生效。通常 deny all 放最后(白名单模式),或者 allow all 放最后(黑名单模式)。 IP 范围可以用 CIDR:192.168.1.0/24 表示 192.168.1.0 到 192.168.1.255。 注意:如果你的 Nginx 前面有 CDN 或反向代理,Nginx 看到的 IP 是 CDN 的 IP 而不是用户真实 IP。需要用 real_ip 模块或从 X-Forwarded-For 头里取。
nginx
# 白名单模式——只允许内网
deny all;
allow 192.168.0.0/16;
allow 10.0.0.0/8;

# 黑名单模式——封禁几个恶意 IP
deny 1.2.3.4;
deny 5.6.7.0/24;
allow all;

# 在 location 内部限制管理后台
location /admin/ {
  allow 192.168.1.0/24;
  deny all;
}

02. 限流——保护后端不被冲垮

限流是保护后端服务的重要手段——防止单个 IP 恶意刷接口、防止突发流量打垮服务。Nginx 有两种限流方式: 速率限制——limit_req,控制每秒允许多少个请求。用令牌桶算法:桶以固定速率产生令牌,每个请求消耗一个令牌,没令牌的请求排队或被拒绝。 并发限制——limit_conn,控制单个 IP 同时最多多少个连接。防止单个 IP 占用过多连接资源。 limit_req_zone 定义限制规则(按什么 key 限),limit_req 在 location 里应用。burst 参数允许短时间的突增请求排队(不加 burst 就直接拒绝超出的)。nodelay 参数让排队请求也立即处理。
nginx
# 在 http 块定义
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=connlimit:10m;

# 在 server 或 location 里应用
location /api/ {
  limit_req zone=mylimit burst=20 nodelay;
  limit_conn connlimit 10;
  proxy_pass http://backend;
}

# 对不同 API 不同限速
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
location /api/login {
  limit_req zone=login burst=3 nodelay;
}
登录接口限速要低(1r/s),防止暴力破解。一般 API 可以高一点(10~100r/s),看后端承受能力。

03. 安全响应头

Nginx 可以通过 add_header 给响应加上安全头,让浏览器做好防御: X-Content-Type-Options: nosniff——防止浏览器 MIME 类型嗅探,严格用 Content-Type。 X-Frame-Options: SAMEORIGIN——防止你的网页被别的网站用 iframe 嵌入(点击劫持攻击)。 X-XSS-Protection: 1; mode=block——开启浏览器内置的 XSS 过滤器。 Content-Security-Policy——限制页面可以加载哪些来源的资源(script、style、img、font 等)。这是最强的 Web 安全策略。 Referrer-Policy——控制 Referer 头里带多少信息。 这些安全头可以在 Nginx 层统一加,不需要每个应用自己处理。
nginx
# 全局安全头
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

# CSP(根据你的应用定制)
add_header Content-Security-Policy "
  default-src 'self';
  script-src 'self' 'unsafe-inline' https://cdn.example.com;
  style-src 'self' 'unsafe-inline';
  img-src 'self' data: https:;
" always;
CSP 配置先设成 report-only 模式(Content-Security-Policy-Report-Only),只报错不拦截。调好了再去掉 Report-Only。

04. 防止 DDoS 与暴力破解

Nginx 虽然不是专业的 WAF,但可以做基础的防护: 1. 限制请求速率——登录接口设 1~3r/s,防止暴力破解。 2. 限制 body 大小——client_max_body_size 10m,防止上传超大文件撑爆磁盘。 3. 限制请求头大小——防止恶意构造超大头。 4. 超时配置——client_body_timeout、client_header_timeout 设置短的超时,防止慢速攻击(Slowloris)。 5. 隐藏版本号——server_tokens off,不让攻击者知道你的 Nginx 版本。 6. 阻止不认识的 Host 头——防止 DNS 重绑定攻击。 对于专业攻击,Nginx 的这些手段不够——需要配合专业的 WAF(如 ModSecurity)、CDN(Cloudflare)或 iptables 层的防护。
nginx
# 基础防护配置
client_max_body_size 10m;
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;

client_body_timeout 10s;
client_header_timeout 10s;
send_timeout 10s;

server_tokens off;

# 阻止不认识的 Host
server {
  listen 80 default_server;
  server_name _;
  return 444;  # Nginx 特殊状态码——直接关连接不回复
}
return 444 是 Nginx 特有的状态码——直接断开 TCP 连接不回复任何内容。适合给恶意 IP 用——TCP 连接直接掐断。

05. Basic Auth——简单密码保护

Nginx 内置 HTTP Basic Auth,可以在开发环境、内网工具、临时公开页等场景加一层简单的用户名密码保护。 两步:1. 用 htpasswd 创建用户名密码文件。2. 在 Nginx location 里用 auth_basic 指令引用。 Basic Auth 的密码是 Base64 编码(不是加密),所以一定要配合 HTTPS 使用——不然密码明文就暴露了。 对于内部管理工具(如 kibana、grafana),用 Basic Auth 加 IP 白名单双重保护是不错的组合。
nginx
# 创建密码文件
sudo apt install apache2-utils  # 得到 htpasswd 命令
sudo htpasswd -c /etc/nginx/.htpasswd admin
# -c 创建新文件(第一次用),之后再添加用户不要加 -c

# Nginx 配置
location /admin/ {
  auth_basic "Restricted Area";
  auth_basic_user_file /etc/nginx/.htpasswd;
  
  proxy_pass http://kibana:5601;
}
Basic Auth 的密码是 Base64 编码不是加密。不配 HTTPS 的话中间人完全可以解码拿到密码。生产环境 Basic Auth 必须配合 HTTPS。

知识测验

1/5正确 0

Nginx 限流 limit_req 的 burst 参数什么意思?

下一节

性能优化

下一节