86 lines
4.0 KiB
Bash
86 lines
4.0 KiB
Bash
|
|
#!/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"
|