7.8.7 访问控制与安全防护实践

访问控制与安全防护在 Web 应用部署中是保障服务稳定与数据安全的关键环节,应围绕“最小权限、分层防护、可审计”的原则进行设计。下面结合 Nginx 的常用能力给出可落地的配置、命令、排错与练习。

原理草图(请求进入、鉴权、限流与安全头处理):

文章图片

一、安装与准备(含命令解释)
1)安装基础工具与模块(示例以 Ubuntu 为例):

sudo apt update
sudo apt install -y nginx apache2-utils
# nginx: Web 服务
# apache2-utils: 提供 htpasswd,用于 Basic Auth
nginx -v

2)准备访问控制文件与测试目录:

sudo mkdir -p /etc/nginx/conf.d/acl
sudo mkdir -p /var/www/html/admin
echo "admin ok" | sudo tee /var/www/html/admin/index.html

二、基于 IP 的访问控制 + 真实 IP 获取
场景:仅允许内网访问 /admin,且在反向代理后正确识别客户端 IP。

# /etc/nginx/conf.d/acl/real_ip.conf
real_ip_header X-Forwarded-For;
set_real_ip_from 10.0.0.0/8;    # 信任上游代理网段
set_real_ip_from 172.16.0.0/12;
set_real_ip_from 192.168.0.0/16;
real_ip_recursive on;

# /etc/nginx/conf.d/acl/admin_ip.conf
location /admin/ {
    allow 192.168.10.0/24;
    deny  all;
    root /var/www/html;
    index index.html;
}

启用配置并检查:

sudo ln -s /etc/nginx/conf.d/acl/real_ip.conf /etc/nginx/conf.d/real_ip.conf
sudo ln -s /etc/nginx/conf.d/acl/admin_ip.conf /etc/nginx/conf.d/admin_ip.conf
sudo nginx -t   # 语法检查
sudo systemctl reload nginx

预期效果:非 192.168.10.0/24 访问 /admin 返回 403。

三、请求速率与并发限制(限流)
适用于接口、登录、搜索等高频请求控制。

# /etc/nginx/conf.d/acl/limit.conf
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=5r/s;
limit_conn_zone $binary_remote_addr zone=conn_zone:10m;

server {
    listen 80;
    server_name example.com;

    location /api/ {
        limit_req zone=req_zone burst=10 nodelay;
        limit_conn conn_zone 20;
        proxy_pass http://app_backend;
        add_header X-RateLimit "ON";
    }
}

验证限流(并发触发 503/429):

# 50 并发,100 次请求
ab -n 100 -c 50 http://example.com/api/

四、Basic Auth 与统一鉴权子请求
1)Basic Auth(适合内部工具/临时保护):

sudo htpasswd -c /etc/nginx/.htpasswd admin
# 输入密码,生成哈希
# /etc/nginx/conf.d/acl/basic_auth.conf
location /admin/ {
    auth_basic "Admin Zone";
    auth_basic_user_file /etc/nginx/.htpasswd;
    root /var/www/html;
}

2)auth_request 子请求鉴权(推荐统一认证)

# /etc/nginx/conf.d/acl/auth_request.conf
location / {
    auth_request /auth;
    proxy_pass http://app_backend;
}

location = /auth {
    internal;
    proxy_pass http://auth_backend/verify;
    proxy_set_header X-Original-URI $request_uri;
    proxy_set_header X-Real-IP $remote_addr;
}

五、安全响应头与转发头规范

# /etc/nginx/conf.d/acl/security_headers.conf
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Content-Security-Policy "default-src 'self'" always;

# 规范代理头
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;

六、日志审计与限流事件标记

# /etc/nginx/conf.d/acl/logging.conf
log_format access_audit '$remote_addr - $remote_user [$time_local] '
                        '"$request" $status $body_bytes_sent '
                        '"$http_referer" "$http_user_agent" '
                        'rt=$request_time uct=$upstream_connect_time '
                        'urt=$upstream_response_time '
                        'limit=$limit_req_status';

access_log /var/log/nginx/access_audit.log access_audit;

七、排错与常见问题定位
1)真实 IP 未生效,日志仍是代理 IP
排查:确认 set_real_ip_from 是否包含代理网段;检查是否有 X-Forwarded-For。

grep -R "real_ip" -n /etc/nginx
curl -I -H "X-Forwarded-For: 1.2.3.4" http://example.com/

2)限流过严导致 503/429
排查:确认 rate/burst 是否合理;观察 access log 中 limit 字段。

tail -f /var/log/nginx/access_audit.log | grep limit

3)Basic Auth 失败
排查:路径、权限、htpasswd 文件格式。

sudo ls -l /etc/nginx/.htpasswd
sudo nginx -t

4)鉴权子请求 401/403
排查:/auth 是否 internal;鉴权服务响应码是否正确。

curl -I http://auth_backend/verify

八、练习(可执行任务)
1)只允许 10.10.0.0/16 访问 /admin,其余 403。
2)为 /api/login 设置 2r/s 限流,burst=5。
3)为 /tools 加 Basic Auth,并验证访问。
4)配置安全响应头,使用 curl -I 查看是否生效。
5)通过 auth_request 接入鉴权服务,模拟返回 200/401 测试。