7.3.6 访问控制与安全加固
本节围绕反向代理场景下的访问控制与安全加固,重点覆盖来源限制、鉴权、限流、防护头、请求校验与安全基线。目标是在不影响正常业务的前提下,降低恶意访问、扫描与滥用风险,提升边界安全性与稳定性。
原理草图(请求进入Nginx后的安全关卡)
一、基于来源的访问控制#
场景:管理后台仅允许内网访问,外网接口默认放行。
关键指令:allow/deny、geo、map
示例配置(/etc/nginx/conf.d/access.conf)
geo $is_inner {
default 0;
10.0.0.0/8 1;
172.16.0.0/12 1;
192.168.0.0/16 1;
}
map $uri $need_inner {
default 0;
~^/admin 1;
~^/ops 1;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
}
location /admin/ {
if ($is_inner = 0) { return 403; }
proxy_pass http://admin_backend;
}
}
命令解释与验证
nginx -t # 检查配置是否正确
systemctl reload nginx # 平滑重载配置
curl -I http://example.com/ # 验证普通接口
curl -I http://example.com/admin/ # 外网应返回403
排错要点
- 403过多:确认内网网段是否正确;检查是否被上层代理隐藏真实IP。
- 需要真实IP:配合 real_ip 模块设置 set_real_ip_from 与 real_ip_header.
二、鉴权与凭证保护#
场景:对简单管理入口启用 HTTP Basic;API 接口透传 JWT。
关键指令:auth_basic、auth_basic_user_file
安装与准备
# 安装 htpasswd 工具(Ubuntu/Debian)
apt-get install -y apache2-utils
# 或者(CentOS/RHEL)
yum install -y httpd-tools
创建认证用户
htpasswd -c /etc/nginx/.htpasswd admin # 首次创建
htpasswd /etc/nginx/.htpasswd devops # 追加用户
配置示例
location /admin/ {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://admin_backend;
}
命令解释与验证
curl -I http://example.com/admin/ # 返回401
curl -I -u admin:密码 http://example.com/admin/ # 返回200
排错要点
- 401持续出现:确认密码文件路径与权限;Nginx 进程需可读。
- 代理后端鉴权失败:确认 proxy_set_header Authorization $http_authorization; 是否被覆盖。
三、限流与连接保护#
场景:登录接口限速,防止暴力破解;全局并发限制保护后端。
关键指令:limit_req、limit_conn
配置示例
limit_req_zone $binary_remote_addr zone=login_zone:10m rate=5r/s;
limit_conn_zone $binary_remote_addr zone=addr_zone:10m;
server {
listen 80;
server_name example.com;
location /login/ {
limit_req zone=login_zone burst=10 nodelay;
proxy_pass http://auth_backend;
}
location / {
limit_conn addr_zone 50; # 单IP最大并发
proxy_pass http://backend;
}
}
命令解释与验证
ab -n 50 -c 20 http://example.com/login/ # 触发429
tail -f /var/log/nginx/error.log # 观察limit_req日志
排错要点
- 429过多:提高 rate 或 burst,或对特定路径单独放宽。
- 限流不生效:确认请求是否经过Nginx入口;检查 zone 名是否一致。
四、请求大小与方法限制#
场景:上传接口允许较大包体,其余接口限制请求体大小与方法。
关键指令:client_max_body_size、limit_except
配置示例
server {
listen 80;
server_name example.com;
client_max_body_size 2m; # 全局限制
location /upload/ {
client_max_body_size 50m;
proxy_pass http://upload_backend;
}
location /api/ {
limit_except GET POST { deny all; }
proxy_pass http://api_backend;
}
}
验证命令
curl -X PUT http://example.com/api/ # 应返回403
dd if=/dev/zero of=/tmp/3m.bin bs=1M count=3
curl -F "file=@/tmp/3m.bin" http://example.com/upload/ # 应成功
排错要点
- 413 Request Entity Too Large:检查 client_max_body_size 是否生效在对应 location。
- 方法限制未生效:确认 limit_except 在目标 location 内。
五、安全响应头与反向代理隐藏#
目标:减少信息泄露,强化浏览器端安全策略。
关键指令:add_header、server_tokens
配置示例
server {
listen 80;
server_name example.com;
server_tokens off;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'" always;
location / {
proxy_hide_header X-Powered-By;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://backend;
}
}
验证命令
curl -I http://example.com/ | egrep "X-Frame|X-Content|Referrer|Content-Security"
六、日志与审计#
场景:管理接口单独日志;记录真实IP。
关键指令:log_format、access_log、real_ip_header
配置示例
log_format audit '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$http_x_forwarded_for"';
set_real_ip_from 10.0.0.0/8;
real_ip_header X-Forwarded-For;
server {
listen 80;
server_name example.com;
access_log /var/log/nginx/access.log audit;
location /admin/ {
access_log /var/log/nginx/admin_access.log audit;
proxy_pass http://admin_backend;
}
}
排错要点
- 真实IP不准确:确认上游代理是否正确设置 X-Forwarded-For。
- 日志未生成:检查目录权限与Nginx用户(如 www-data/nginx)。
七、基础安全加固清单(含排查命令)#
- 只开放必要端口:
ss -lntp | grep nginx
- 合理超时与缓冲(防慢连接):
proxy_read_timeout 30s;
client_header_timeout 10s;
client_body_timeout 10s;
- 与防火墙/WAF 联动:
# 例:限制管理端口仅内网
iptables -A INPUT -p tcp --dport 80 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j DROP
- 定期升级Nginx与模块:
nginx -v
# 根据发行版更新:apt/yum upgrade nginx
常见故障排查#
- 访问被意外拒绝(403/401)
- 检查allow/deny与auth_basic是否应用到正确的 location。 - 限流导致业务异常(429)
- 调整rate/burst;对登录与API分开限流。 - Header未生效
- 检查add_header是否在server级别或always关键字。
练习#
- 实现
/admin仅内网访问,并启用 Basic Auth。 - 为
/login配置限流 2r/s,burst=5。 - 设置全站
client_max_body_size 1m,为/upload设 20m。 - 添加安全响应头并隐藏
X-Powered-By。 - 使用
curl -I验证响应头与状态码是否符合预期。