全网段nginx站点hsts合规率需通过外部扫描器(如nmap、httpx、curl)实现,nginx仅作为被测对象;流程含批量发现、hsts头提取验证(需200响应、含max-age≥31536000且无unsafe)、聚合统计与报告输出。

直接对全网段扫描 Nginx 站点并统计 HSTS 合规率,不能靠 Nginx 自身实现——Nginx 是服务端组件,不负责主动探测其他站点。真正可行的方案是:用外部扫描器(如 Nmap、httpx、curl + Bash)批量探测目标 IP/域名,提取响应头中的 Strict-Transport-Security 字段,再按规则判定是否合规。Nginx 的角色仅限于“被测对象”:它必须正确配置并生效 HSTS 头,才能被识别为合规。
以下是可落地的自动化流程,覆盖发现、采集、判定、统计四步:
-
批量发现目标站点
先获取待测网段或资产清单(如192.168.1.0/24或域名列表domains.txt):# 扫描存活主机(跳过 ICMP 封禁环境) nmap -sn -n -T4 192.168.1.0/24 | grep "Nmap scan report" | awk '{print $5}' > ips.txt # 或从域名列表发起 HTTPS 探测(推荐 httpx,快且支持 header 提取) cat domains.txt | httpx -status-code -header -threads 100 -timeout 5 -o results.json -
精准提取并验证 HSTS 响应头
对每个可达目标,检查Strict-Transport-Security是否存在、格式合法、参数达标:
必须同时满足以下三项才算合规:- 响应状态码为
200(或301/302且重定向链最终含 HSTS) - Header 中存在
Strict-Transport-Security字段(大小写不敏感) - 值中包含
max-age=且数值 ≥31536000(即 ≥ 1 年),且不含unsafe关键字
示例判断逻辑(Bash + curl):
curl -I -k -s -m 3 https://$host 2>/dev/null | awk -v host="$host" ' /^HTTP// { code=$2 } /^[Ss][Tt][Rr][Ii][Cc][Tt]-[Tt][Rr][Aa][Nn][Ss][Pp][Oo][Rr][Tt]-[Ss][Ee][Cc][Uu][Rr][Ii][Tt][Yy]:/ { hsts = substr($0, index($0, ":") + 2) } END { if (code == 200 && hsts != "" && hsts ~ /max-age=[0-9]+/ && hsts !~ /unsafe/) { age = hsts; sub(/.*max-age=([0-9]+).*/, "\1", age) if (age >= 31536000) print host, "PASS" else print host, "AGE_TOO_SMALL" } else print host, "MISSING_OR_INVALID" }' - 响应状态码为
-
聚合统计与输出报告
将所有结果汇总为结构化数据,便于追踪趋势:# 输出 CSV 格式:host,status,max_age(若可提取) # 最终生成:总站点数、合规数、合规率、常见问题分类(如 missing / age_too_small / includes_unsafe) awk '{cnt[$2]++} END {for (k in cnt) print k "," cnt[k]}' results.csv -
Nginx 配置侧需确保自身可被正确识别
若你管理的 Nginx 是被测对象之一,务必确认其 HSTS 配置已生效且无覆盖冲突:# 在 server 块中(HTTPS 下),且加 always 参数,确保 4xx/5xx 也携带 if ($scheme = https) { add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; }验证方式:
curl -I https://your-site.com | grep -i strict,确认输出唯一、无重复、无空格截断。
不复杂但容易忽略:HSTS 合规率统计本质是资产治理指标,不是技术功能。重点不在“怎么扫”,而在于“扫谁、按什么标准判、结果如何驱动整改”。建议将该脚本纳入每周资产巡检流水线,输出自动推送到运维看板。











