#!/usr/bin/env bash # ============================================================================= # nginx access_log 脱敏脚本 — 不再记录 Authorization/Cookie 等敏感字段 # ============================================================================= # 背景(2026-06-21 评审): # 当前 nginx 默认 access_log 格式包含 $http_authorization, $http_cookie, # 这些字段含用户 token、session cookie,直接落盘到 /var/log/nginx/access.log。 # 任何能读该日志的运维都能冒充任意用户(严重安全漏洞)。 # # 修复方案(对应 P1 合规): # 1. 自定义 log_format "secure" — 不含 Authorization/Cookie/Set-Cookie # 2. access_log 引用 "secure" 格式 # 3. 部署步骤: 在 nginx.conf http{} 块中插入下面的 log_format, # 然后把 access_log 行的格式从默认改成 "secure"。 # # 用法: # 1. 在堡垒机上编辑 nginx.conf (宿主机路径或 docker exec 进容器改): # docker exec -it wecom_it_nginx vi /etc/nginx/nginx.conf # 2. 把本脚本输出的 "SECURE LOG_FORMAT 块" 插入到 http {} 块顶部 # 3. 把所有 access_log 行的格式参数从默认改成 "secure",例如: # access_log /var/log/nginx/access.log secure; # 4. nginx -t && nginx -s reload # 5. 验证: curl -I https://... 看新日志是否含 "Bearer xxx"(不应该) # # ⚠️ 重要: 不要直接覆盖容器内 nginx.conf! bind mount RO 的话 docker cp 是假成功 # 陷阱回顾: backend/.claude/memory/feedback/docker-cp-readonly-bind-mount-fake-success.md # ============================================================================= set -euo pipefail # 输出需要插入到 nginx.conf http {} 块的 log_format 定义 cat <<'NGINX_SNIPPET' # ---------------------------------------------------------------------------- # SECURE LOG_FORMAT — P1 合规: 不记录 Authorization/Cookie/Set-Cookie # ---------------------------------------------------------------------------- # 与默认 combined 格式对比,删除了: # $http_authorization — Bearer token,直接可冒充 # $http_cookie — Session cookie,直接可劫持 # $sent_http_set_cookie — 服务端下发的 session # # 默认 combined 格式: '$remote_addr - $remote_user [$time_local] ' # '"$request" $status $body_bytes_sent ' # '"$http_referer" "$http_user_agent"' # ---------------------------------------------------------------------------- log_format secure '$remote_addr - $remote_user [$time_local] ' '"$request_method $uri $server_protocol" $status ' '$body_bytes_sent "$http_referer" ' '"$http_user_agent"'; # 关键改动: access_log 第二参数 = log_format 名称(默认 combined → 改 secure) # 注意: 错误日志 error_log 不变(不含敏感字段) access_log /var/log/nginx/access.log secure; NGINX_SNIPPET echo "" echo "==========================================" echo "P1 合规修复 — 操作步骤" echo "==========================================" echo "" echo "1. 进入 nginx 容器(避开 bind mount RO 陷阱):" echo " docker exec -it wecom_it_nginx sh" echo "" echo "2. 备份现有 nginx.conf:" echo " cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak.$(date +%Y%m%d)" echo "" echo "3. 在 http {} 块内顶部插入上面输出的 SECURE LOG_FORMAT 块" echo " (log_format + access_log 两行)" echo "" echo "4. 删除或注释原 access_log /var/log/nginx/access.log; 行(避免冲突)" echo "" echo "5. 测试配置 + 热重载:" echo " nginx -t" echo " nginx -s reload" echo "" echo "6. 验证: 触发一次带 Authorization 头的请求,grep access.log 应找不到 token" echo " curl -H 'Authorization: Bearer TEST_TOKEN_DO_NOT_LOG' https://.../api/.../health" echo " tail -1 /var/log/nginx/access.log # 不应含 TEST_TOKEN" echo "" echo "==========================================" echo "回滚:" echo "==========================================" echo " cp /etc/nginx/nginx.conf.bak.YYYYMMDD /etc/nginx/nginx.conf" echo " nginx -s reload"