0

curl批量检测HSTS安全响应头配置:5个实战脚本让网站安全巡检自动化

2026.06.02 | youres | 28次围观

HSTS(HTTP Strict Transport Security)是保护网站 HTTPS 连接的重要安全机制。配置好 HSTS 响应头后,如何快速验证全站域名是否正确返回了该头部?手动逐个访问不现实,curl 批量检测才是高效方案。

本文分享 5 个实战脚本,从最简单的单域名检查到多域名并行检测,覆盖 Shell 和 PowerShell 两大平台,帮你把 HSTS 安全巡检彻底自动化。

一、为什么需要批量检测 HSTS 响应头

在实际运维中,HSTS 配置可能因为以下原因失效:

  • Nginx 配置变更后忘记验证 HSTS 头是否正常返回
  • CDN 层(如 Cloudflare)覆盖或丢弃了源站的 HSTS 头
  • 子域名未配置 includeSubDomains 指令
  • 多环境(测试/预发/生产)配置不一致

用 curl 批量检测,可以在每次部署后快速发现问题,比手动打开浏览器检查效率高几个数量级。

二、基础:用 curl 检测单个域名的 HSTS 头

先用最简单的方式确认方法可行:

curl -sI https://example.com | grep -i "strict-transport-security"

参数说明:

  • -s:静默模式,不显示进度条
  • -I:只发送 HEAD 请求,只获取响应头
  • grep -i:不区分大小写匹配 Strict-Transport-Security 头

如果返回了类似 strict-transport-security: max-age=63072000; includeSubDomains; preload 的内容,说明 HSTS 配置正常。如果没有任何输出,说明 HSTS 头缺失,需要排查。

三、脚本1:Shell 多域名循环检测脚本

把需要检测的域名放到一个文本文件中,用循环逐个检查:

#!/bin/bash
# HSTS 批量检测脚本
DOMAINS_FILE="domains.txt"
TIMEOUT=10

echo "=============================="
echo "HSTS 响应头批量检测报告"
echo "检测时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "=============================="

while IFS= read -r domain; do
    # 跳过空行和注释
    [[ -z "$domain" || "$domain" == \#* ]] && continue
    
    hsts_header=$(curl -sI --connect-timeout "$TIMEOUT" --max-time "$TIMEOUT" "https://$domain" 2>/dev/null | grep -i "strict-transport-security")
    
    if [[ -n "$hsts_header" ]]; then
        echo "[OK] $domain"
        echo "     $hsts_header"
    else
        echo "[缺失] $domain - 未检测到 HSTS 响应头!"
    fi
done < "$DOMAINS_FILE"

echo "=============================="
echo "检测完成"

创建 domains.txt 文件,每行一个域名:

example.com
api.example.com
cdn.example.com
blog.example.com

运行:bash check_hsts.sh

这个脚本的优点是简单直观,适合域名数量不多(几十个以内)的场景。每个域名独立检测,超时设置为 10 秒防止卡住。

四、脚本2:带评分的 HSTS 安全等级评估

光知道有没有 HSTS 头还不够,我们还可以评估安全等级:

#!/bin/bash
# HSTS 安全等级评估脚本
check_hsts() {
    local domain=$1
    local header=$(curl -sI --connect-timeout 8 --max-time 8 "https://$domain" 2>/dev/null | grep -i "strict-transport-security" | tr -d '\r\n')
    
    if [[ -z "$header" ]]; then
        echo "[D] $domain - 未配置 HSTS"
        return
    fi
    
    # 提取 max-age 值
    max_age=$(echo "$header" | grep -oP 'max-age=\K[0-9]+')
    
    # 检查 includeSubDomains
    has_include=$(echo "$header" | grep -ic "includesubdomains")
    
    # 检查 preload
    has_preload=$(echo "$header" | grep -ic "preload")
    
    # 评分
    score=0
    if [[ -n "$max_age" && "$max_age" -ge 31536000 ]]; then
        ((score+=40))
    elif [[ -n "$max_age" && "$max_age" -ge 2592000 ]]; then
        ((score+=20))
    elif [[ -n "$max_age" ]]; then
        ((score+=10))
    fi
    
    [[ "$has_include" -gt 0 ]] && ((score+=30))
    [[ "$has_preload" -gt 0 ]] && ((score+=30))
    
    if [[ $score -ge 90 ]]; then
        grade="A"
    elif [[ $score -ge 70 ]]; then
        grade="B"
    elif [[ $score -ge 40 ]]; then
        grade="C"
    else
        grade="D"
    fi
    
    echo "[$grade] $domain (评分:$score) $header"
}

for domain in "$@"; do
    check_hsts "$domain"
done

用法:./hsts_grade.sh example.com api.example.com cdn.example.com

评分规则:

  • max-age ≥ 1年(31536000秒):+40分
  • max-age ≥ 30天:+20分
  • max-age 有值但 < 30天:+10分
  • includeSubDomains:+30分
  • preload:+30分

五、脚本3:xargs 并行检测(高性能方案)

域名很多时,串行检测太慢。用 xargs -P 实现并行:

#!/bin/bash
# HSTS 并行批量检测
DOMAINS_FILE="domains.txt"
PARALLEL=10  # 并发数

check_one() {
    local domain=$1
    local hsts=$(curl -sI --connect-timeout 5 --max-time 5 "https://$domain" 2>/dev/null | grep -i "strict-transport-security")
    if [[ -n "$hsts" ]]; then
        echo "OK|$domain|$hsts"
    else
        echo "MISS|$domain|"
    fi
}

export -f check_one

echo "开始并行检测... ($(grep -cv '^#\|^$' $DOMAINS_FILE) 个域名, $PARALLEL 并发)"
grep -v '^#\|^$' "$DOMAINS_FILE" | xargs -P "$PARALLEL" -I {} bash -c 'check_one "{}"' | sort

echo "检测完成"

核心是 xargs -P 10,表示同时运行 10 个 curl 进程。对于 100 个域名,5 秒超时下大约 50 秒就能全部完成,而串行需要 500 秒。

注意并发数不要设太高,避免触发目标服务器的连接限制。

六、脚本4:PowerShell 版本批量检测

Windows 环境下可以用 PowerShell 实现:

# HSTS 批量检测 PowerShell 版本
$domains = @(
    "example.com"
    "api.example.com"
    "blog.example.com"
    "cdn.example.com"
)

Write-Host "==============================" -ForegroundColor Cyan
Write-Host "HSTS 响应头批量检测报告"
Write-Host "检测时间: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
Write-Host "==============================" -ForegroundColor Cyan

$results = @()

foreach ($domain in $domains) {
    try {
        $response = Invoke-WebRequest -Uri "https://$domain" -Method HEAD -TimeoutSec 10 -UseBasicParsing -ErrorAction Stop
        $hsts = $response.Headers['Strict-Transport-Security']
        
        if ($hsts) {
            Write-Host "[OK] $domain" -ForegroundColor Green
            Write-Host "     $hsts" -ForegroundColor Gray
            $results += [PSCustomObject]@{
                Domain = $domain
                Status = "OK"
                HSTS   = $hsts
            }
        } else {
            Write-Host "[缺失] $domain" -ForegroundColor Red
            $results += [PSCustomObject]@{
                Domain = $domain
                Status = "缺失"
                HSTS   = "无"
            }
        }
    } catch {
        Write-Host "[错误] $domain - $($_.Exception.Message)" -ForegroundColor Yellow
        $results += [PSCustomObject]@{
            Domain = $domain
            Status = "错误"
            HSTS   = $_.Exception.Message
        }
    }
}

# 导出 CSV 报告
$reportFile = "hsts_report_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"
$results | Export-Csv -Path $reportFile -NoTypeInformation -Encoding UTF8
Write-Host "`n报告已保存: $reportFile" -ForegroundColor Cyan

PowerShell 版本的优势是:

  • 直接导出 CSV 报告,方便用 Excel 打开分析
  • 错误处理更精细,能区分「缺失」和「连接失败」
  • 适合集成到 Windows 任务计划程序中定时执行

七、脚本5:持续监控方案(配合定时任务)

把检测脚本接入 cron 或任务计划,实现每日自动巡检:

Linux cron 配置:

# 每天早上 9 点执行 HSTS 检测,结果发送到邮箱
0 9 * * * /opt/scripts/check_hsts.sh | mail -s "HSTS 每日检测报告" admin@example.com

Windows 任务计划:

# 创建每天 9 点运行的定时任务
$action = New-ScheduledTaskAction -Execute "pwsh.exe" -Argument "-File C:\Scripts\check_hsts.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At 9am
Register-ScheduledTask -TaskName "HSTS每日检测" -Action $action -Trigger $trigger

持续监控的好处是:HSTS 头一旦因为配置变更或 CDN 调整而丢失,你能在当天收到告警,而不是等到安全审计才发现问题。

八、HSTS 检测中的常见问题

1. curl -I 返回 405 Method Not Allowed

部分服务器不支持 HEAD 方法。改用 GET 请求但丢弃响应体:

curl -s -D - -o /dev/null https://example.com | grep -i "strict-transport-security"

2. 检测到 HSTS 头但 max-age 值为 0

max-age=0 表示立即失效,等同于删除 HSTS 策略。这可能是调试残留配置,需要修复。

3. 只在 HTTP 响应中检测不到

HSTS 头只应在 HTTPS 响应中出现,HTTP 响应检测不到是正常的。确保检测 URL 使用 https:// 开头。

4. CDN 层干扰

使用 Cloudflare 等 CDN 时,HSTS 头可能在 CDN 层设置而非源站。此时应检测 CDN 回源后的实际响应,可以用 --resolve 参数绕过 CDN 直接访问源站:

curl -sI --resolve "example.com:443:源站IP" https://example.com | grep -i "strict-transport-security"

九、总结

HSTS 批量检测不难,难的是坚持做。5 个脚本从简单到复杂,根据你的场景选择:

  • 快速检查:脚本1(Shell 多域名循环)
  • 安全评估:脚本2(带评分系统)
  • 大规模扫描:脚本3(xargs 并行)
  • Windows 环境:脚本4(PowerShell + CSV)
  • 持续监控:脚本5(定时任务集成)

建议把 HSTS 检测纳入部署流程的 CI/CD 中,每次发布后自动跑一遍,确保安全配置不会意外丢失。

相关阅读

版权声明

本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论