<p>Nginx 无法在 access 日志中直接记录 Strict-Transport-Security 响应头内容,因其由 add_header 注入且不进入 $senthttp* 变量;可通过 is_hsts=1 标记 HTTPS 请求日志来审计 HSTS 生效情况。</p>

Nginx 本身不会直接记录响应头内容到 access 日志中,包括 Strict-Transport-Security 响应头。$sent_http_* 变量虽可获取已发送的响应头(如 $sent_http_strict_transport_security),但 HSTS 头是浏览器强制执行的安全策略,不是由后端动态生成或可被日志变量捕获的常规响应头——它由 Nginx 的 add_header 指令在响应发出前注入,*不经过后端应用,也不落进 `$senthttp` 变量链**。
所以,“记录带有 HSTS 响应头的访问日志”,实际含义是:
✅ 记录那些确实收到了 HSTS 响应头的 HTTPS 请求(即配置生效的请求);
❌ 无法在日志里直接看到 "Strict-Transport-Security: max-age=..." 这一字符串。
要达成可审计、可分析的目标,推荐以下三类实用做法:
确保 HSTS 已启用并只对 HTTPS 请求生效
HSTS 头只能且必须从 443 端口的 server { listen 443 ssl; } 块中发出。
在该块内添加:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
⚠️ 注意:
always参数确保即使返回 4xx/5xx 错误,HSTS 头仍会携带——这对日志归因很关键:你希望所有 HTTPS 响应(无论成功失败)都被视为“HSTS 生效路径”。
在日志中标识“本次响应属于 HSTS 生效范围”
利用 Nginx 变量和条件日志,打上明确标记:
# 自定义日志格式:增加 is_hsts 字段
log_format hsts_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'is_hsts=$hsts_flag';
# 在 HTTPS server 块中设置标记变量
map $scheme $hsts_flag {
https "1";
default "0";
}
server {
listen 443 ssl;
server_name example.com;
# 启用 HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# 使用带标记的日志
access_log /var/log/nginx/hsts_access.log hsts_log;
location / {
proxy_pass http://backend;
# 其他配置...
}
}这样每条日志末尾会出现 is_hsts=1,代表该请求走的是 HTTPS 通道、且 HSTS 头已发出。
补充验证:用 $sent_http_strict_transport_security?不可靠,但可尝试(仅限调试)
理论上,若你在 add_header 后立即读取 $sent_http_strict_transport_security,Nginx 会返回空值——因为 add_header 不赋值给该变量,它只是“追加响应头”。
但你可以反向验证是否命中 HTTPS server 块:
# 更严谨的标记:不仅看 scheme,还确认 SSL 已启用
map $https $hsts_flag {
"on" "1";
default "0";
}这个方式比 $scheme 更准确,能排除某些代理透传 HTTP 请求却伪造 https 的异常情况。
配合外部工具做真实 HSTS 状态归因
单靠 Nginx 日志无法知道浏览器是否“已缓存 HSTS 策略”或“是否因 HSTS 自动升级了请求”。这时需结合:
-
客户端上报字段:前端 JS 检测
window.location.protocol === 'https:'并带上x-hsts-active: true发起请求,Nginx 用$http_x_hsts_active记录; -
curl 或监控脚本定期探测:
curl -I https://example.com 2>/dev/null | grep -i "strict-transport-security"
结果可写入时间序列日志,用于比对 Nginx access 日志中的
is_hsts=1是否持续一致。
不复杂但容易忽略


















