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 参数什么意思?
下一节
下一节 性能优化