香港服务器如何配置Windows Server 2022的TLS 1.3策略,满足跨境支付安全标准?

我在香港机房里,为一家跨境支付客户把 Windows Server 2022 的 TLS 1.3 策略从“能用”调到“像样,这次变更窗口从凌晨 1:00 开到 3:00。香港葵涌机房 12 楼的冷风一开,我把变更工单贴在机柜门上,确认回滚点,导出当前 TLS 配置做快照。今晚的目标很简单也很挑剔:把一台承载跨境支付入口的 Windows Server 2022,从“能连得上”调到“合规、稳定、还得快”——禁掉 TLS 1.0/1.1,只保留 TLS 1.2 的 AEAD 套件,开启并校准 TLS 1.3,顺手把 HSTS 和 HTTP/3 也理顺。下面就是我在这台服务器上一步步落地的全过程,连同当场踩过的坑,以及我是怎么把它们填平的。
硬件/系统基线(实站一台):
| 角色 | 规格 |
|---|---|
| 位置 | 香港葵涌机房(双上联,CN2 + IPLC 回内地) |
| 型号 | 1× 1U 机:HPE DL360 Gen10(同等规格均可) |
| CPU | Intel Xeon Silver 4210R ×1(AES-NI / PCLMULQDQ 支持) |
| 内存 | 64 GB DDR4 |
| 存储 | 2× NVMe SSD(RAID1) |
| 网卡 | Intel X710 10GbE ×2(RSS/Checksum Offload 开启) |
| 系统 | Windows Server 2022 Datacenter,IIS 10.0 |
合规目标(跨境支付常见约束):
- PCI DSS v4.0:禁止使用早期 TLS(SSL/早期 TLS),生产流量至少 TLS 1.2,推荐支持 TLS 1.3;只允许“强加密”(优先 AEAD/GCM,禁用 3DES/CBC/RC4,避免 RSA 密钥交换)。
- HKMA(香港金管局)TRM/电银指引:强调采用强加密与与时俱进的加密套件、渗透测试与持续监测(模块 TM-E-1 2019/2024 修订)。
协议与实现约束(Windows 2022):
- Windows Server 2022 支持 TLS 1.3,其 TLS_AES_256_GCM_SHA384 / TLS_AES_128_GCM_SHA256 默认在优先列表内;TLS 1.3 的 CHACHA20 是“支持但默认未启用”。
- TLS 协议/套件的基线与注册表路径、GPO 与 PowerShell 管理方式,以 Schannel 为准(系统通用)。
- 若要用 HTTP/3/QUIC 优化跨境链路,它强制依赖 TLS 1.3 并需显式开启 EnableHttp3 / EnableAltSvc。
步骤一:盘点现状与快照
确认系统与补丁
确保当月累积更新已打(IIS/HTTP.SYS/SChannel 有关)。
检查 TLS/套件有效顺序
# 以管理员 PowerShell
Get-TlsCipherSuite | Select-Object Name, CipherSuite | Format-Table -Auto
这能列出 Schannel 实际用于协商的顺序(TLS 1.3/1.2 分别管理)。若你曾用 GPO 或第三方工具改过顺序,先记录现状以便回滚。注意:GPO“SSL Cipher Suite Order”存在1023 字符长度限制,列太长会截断。
证书与站点
IIS 使用服务器证书(服务端认证)。跨境支付前端大多是浏览器/APP,RSA 2048/3072 兼容性最好;若你的客户群体全部是现代客户端,可考虑 ECDSA P-256 提升握手与 CPU 效率(IIS 同一站点同一绑定不同时挂 RSA+ECDSA 双证书,需用不同绑定或前置负载来分流)。
步骤二:协议基线——关旧开新(严格按 Schannel 语义)
目标:
- 禁用 TLS 1.0 / 1.1
- 保留 TLS 1.2(仅 AEAD)
- 确认/保留 TLS 1.3(默认即在,必要时“显式开启”)
注册表(Server/Client 双向)——以下脚本可直贴执行:
# 禁用 TLS 1.0 和 1.1
$base = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols"
$toDisable = @("TLS 1.0","TLS 1.1")
foreach ($p in $toDisable) {
New-Item -Path "$base\$p\Server" -Force | Out-Null
New-ItemProperty -Path "$base\$p\Server" -Name "Enabled" -Value 0 -PropertyType "DWord" -Force | Out-Null
New-ItemProperty -Path "$base\$p\Server" -Name "DisabledByDefault" -Value 1 -PropertyType "DWord" -Force | Out-Null
New-Item -Path "$base\$p\Client" -Force | Out-Null
New-ItemProperty -Path "$base\$p\Client" -Name "Enabled" -Value 0 -PropertyType "DWord" -Force | Out-Null
New-ItemProperty -Path "$base\$p\Client" -Name "DisabledByDefault" -Value 1 -PropertyType "DWord" -Force | Out-Null
}
# 确保 TLS 1.2 启用
New-Item -Path "$base\TLS 1.2\Server" -Force | Out-Null
New-ItemProperty -Path "$base\TLS 1.2\Server" -Name "Enabled" -Value 1 -PropertyType "DWord" -Force | Out-Null
New-ItemProperty -Path "$base\TLS 1.2\Server" -Name "DisabledByDefault" -Value 0 -PropertyType "DWord" -Force | Out-Null
New-Item -Path "$base\TLS 1.2\Client" -Force | Out-Null
New-ItemProperty -Path "$base\TLS 1.2\Client" -Name "Enabled" -Value 1 -PropertyType "DWord" -Force | Out-Null
New-ItemProperty -Path "$base\TLS 1.2\Client" -Name "DisabledByDefault" -Value 0 -PropertyType "DWord" -Force | Out-Null
# 明确确保 TLS 1.3 可用(通常 2022 默认已支持并可协商)
New-Item -Path "$base\TLS 1.3\Server" -Force | Out-Null
New-ItemProperty -Path "$base\TLS 1.3\Server" -Name "Enabled" -Value 1 -PropertyType "DWord" -Force | Out-Null
New-ItemProperty -Path "$base\TLS 1.3\Server" -Name "DisabledByDefault" -Value 0 -PropertyType "DWord" -Force | Out-Null
New-Item -Path "$base\TLS 1.3\Client" -Force | Out-Null
New-ItemProperty -Path "$base\TLS 1.3\Client" -Name "Enabled" -Value 1 -PropertyType "DWord" -Force | Out-Null
New-ItemProperty -Path "$base\TLS 1.3\Client" -Name "DisabledByDefault" -Value 0 -PropertyType "DWord" -Force | Out-Null
说明:Schannel 的协议开关采用 Enabled/DisabledByDefault 组合;TLS 1.3 在 Windows Server 2022 本身支持且默认套件在列表中,此处是“防背配/显式确认”。官方协议与注册表语义参考 Schannel/TLS Registry Settings;TLS 1.3 支持与默认套件参见 Windows Server 2022 Cipher Suites。
步骤三:套件策略——只留 AEAD(GCM),清掉 CBC/3DES/RSA-KE
目标:
TLS 1.3:使用内置 AES_GCM(可选开启 CHACHA20 以优化移动/弱 AES-NI 客户端)
TLS 1.2:仅保留 ECDHE_AESGCM(及必要的 DHE_GCM* 兜底),移除 CBC/3DES/纯 RSA 套件
做法(两种等效方式):
A. 组策略(企业首选)
计算机配置 → 管理模板 → 网络 → SSL 配置设置 → SSL Cipher Suite Order,填入你允许的逗号分隔列表(严格的 1023 字符限制),其余未列出的将被禁用。官方说明与路径如下。
B. PowerShell(服务器/自动化)
利用 TLS 模块 Get/Enable/Disable-TlsCipherSuite 调整顺序与可用集(TLS 1.3 的 AES_GCM 套件在默认已启用;若需启用 TLS_CHACHA20_POLY1305_SHA256,请先确保策略由本机控制而非 GPO 覆盖)。
示例:收敛到“仅 AEAD”的 TLS 1.2 集合 +(可选)启用 TLS 1.3 的 CHACHA20
# 1) 禁用所有 CBC/3DES/RSA 密钥交换
$bad = @(
"TLS_RSA_WITH_3DES_EDE_CBC_SHA",
"TLS_RSA_WITH_AES_256_CBC_SHA256","TLS_RSA_WITH_AES_128_CBC_SHA256",
"TLS_RSA_WITH_AES_256_CBC_SHA","TLS_RSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384","TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA","TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"
)
$bad | ForEach-Object { try { Disable-TlsCipherSuite -Name $_ } catch {} }
# 2) 确保优先顺序为 GCM(TLS 1.2)
$goodOrder = @(
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"
)
# 把需要的套件移到最前(位置 0、1、2…)
for ($i=0; $i -lt $goodOrder.Count; $i++) { try { Enable-TlsCipherSuite -Name $goodOrder[$i] -Position $i } catch {} }
# 3) (可选)启用 TLS 1.3 的 CHACHA20(默认未启用)
try { Enable-TlsCipherSuite -Name "TLS_CHACHA20_POLY1305_SHA256" -Position 2 } catch {}
核心依据:Windows Server 2022 的默认与可用 TLS 套件清单;如何用 GPO 或 TLS 模块管理顺序及启停。
步骤四:IIS/HTTP 堆栈与 HSTS/HTTP/3
1) 开启 HSTS(防降级,审计会看)
IIS 10.0(1709+)支持在站点级开启 HSTS,或直接加响应头。示例(web.config):
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
说明与可选 <hsts> 节点参见官方文档。切记:只对 HTTPS 响应返回 HSTS。
2) (可选)启用 HTTP/3/QUIC 以优化跨境首包
Windows 2022 原生支持 HTTP/3(http.sys 基于 MsQuic)。开启:
# 需要管理员权限,修改后重启 http.sys 或重启服务器
reg add "HKLM\SYSTEM\CurrentControlSet\Services\HTTP\Parameters" /v EnableHttp3 /t REG_DWORD /d 1 /f
reg add "HKLM\SYSTEM\CurrentControlSet\Services\HTTP\Parameters" /v EnableAltSvc /t REG_DWORD /d 1 /f
要点:HTTP/3 强制 TLS 1.3,禁用 TLS 1.3 或其套件会导致绑定失败/服务不可用。上线前请确认 TLS 1.3 的 AES_GCM 至少有一条可协商。
3) OCSP Stapling(证书状态)
IIS/Schannel 支持 OCSP Stapling;如使用 SNI/CCS 绑定,可通过 EnableOcspStaplingForSni=1 确保 SNI 场景下也做 Stapling(实测视 CA/网络可达性而定)。
步骤五:.NET 应用“强密码学”与 TLS 版本约束
很多支付链路上的 Web/API 仍是 .NET Framework 应用。如果代码里显式钉死了 SecurityProtocol = Tls12/Tls11/...,那再好的系统策略也白费。建议:
不要在代码里显式指定旧版本,优先使用 SystemDefault 让 OS 按策略协商;.NET Fx 4.8 在 Windows 11/Server 2022 可协商到 TLS 1.3。
若必须兼容旧组件,至少打开 SchUseStrongCrypto/SystemDefaultTlsVersions,让框架用强加密与系统默认。示例(32/64 位位宽都设):
# 64位
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319" -Name "SchUseStrongCrypto" -Value 1 -PropertyType DWord -Force | Out-Null
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319" -Name "SystemDefaultTlsVersions" -Value 1 -PropertyType DWord -Force | Out-Null
# 32位/WOW6432Node
New-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319" -Name "SchUseStrongCrypto" -Value 1 -PropertyType DWord -Force | Out-Null
New-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319" -Name "SystemDefaultTlsVersions" -Value 1 -PropertyType DWord -Force | Out-Null
步骤六:验证与压测(我在线上是这么验的)
1) OpenSSL(TLS 1.3 指定套件)
# 从香港或内地跳板机
openssl s_client -connect pay.example.hk:443 -tls1_3 -ciphersuites TLS_AES_128_GCM_SHA256 -servername pay.example.hk
看协商版本/套件与证书链。
2) 枚举扫描
nmap --script ssl-enum-ciphers -p 443 pay.example.hk
确认无 CBC/3DES/RSA-KE、无 TLS 1.0/1.1。
3) Schannel 事件日志
锁死后,旧客户端连接失败会在系统日志里留下 36874/36888,可用一条命令抓取最近告警:
Get-WinEvent -LogName System -FilterXPath "*[System[Provider[@Name='Schannel'] and (EventID=36874 or EventID=36888)]]" `
-MaxEvents 50 | Format-Table TimeCreated, Id, Message -Auto
这些事件通常意味着客户端/服务端可协商套件不相交或协议被禁用。
4) HTTP/3 验证
浏览器开发者工具看“Protocol = h3”;或 curl --http3 -I https://pay.example.hk。若只见 h2,多半是没发布 Alt-Svc 或 TLS 1.3 套件不满足。
我给支付侧的“最终策略表”(可直接抄作基线)
| 条目 | 策略/数值 | 备注 |
|---|---|---|
| 协议 | 启用:TLS 1.2、TLS 1.3;禁用:TLS 1.0/1.1 | Schannel 注册表如上 |
| TLS 1.3 套件 | TLS_AES_256_GCM_SHA384、TLS_AES_128_GCM_SHA256(默认);可选 TLS_CHACHA20_POLY1305_SHA256 |
CHACHA20 需显式启用或调整顺序 |
| TLS 1.2 套件 | 仅保留 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256、TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256、TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384、TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384(如需再加 DHE_*_GCM) |
禁用所有 CBC/3DES/纯 RSA 套件 |
| 证书 | 首选 RSA 3072(广泛兼容);纯现代客户端可选 ECDSA P-256 | IIS 单绑定无法同时挂 RSA+ECDSA |
| HSTS | max-age=31536000; includeSubDomains |
IIS 10.0 (1709+) 支持;或自定义头 |
| HTTP/3 | EnableHttp3=1,EnableAltSvc=1 |
仅在 TLS 1.3 可用时生效 |
| OCSP Stapling | 默认支持;SNI/CCS 绑定建议 EnableOcspStaplingForSni=1 |
视 CA 可达性与绑定形态 |
| .NET | 不显式钉版本;启用 SchUseStrongCrypto=1、SystemDefaultTlsVersions=1 |
让应用随 OS 协商到 1.3/1.2 |
线上“坑”与现场解法(我踩过的)
IIS/HTTP3 启了但始终只有 h2
后来发现某同事为了“通过某旧扫描器”把 TLS 1.3 套件全移除了……HTTP/3 强依赖 TLS 1.3,自然失败。恢复 AES_GCM 后即正常。
扫描仍报 3DES/CBC
PowerShell 看不到 3DES,但扫描器抓注册表 ...Local\SSL\00010002 旧策略未清。清理该策略键或用 GPO 重置一次再回滚到“未配置”。
部分内地老终端连不上(大量 36874/36888)
和业务确认,这些是 Android 4.x 内嵌 WebView 或旧 Java 堆栈的 TLS 1.0 客户端。合规上必须“劝退”,同时给他们一个“中间层”API 网关专用域名,单独允许 TLS 1.2 严格子集并督促终端升级。
SNI 多域名后 OCSP Stapling 不生效
补上 EnableOcspStaplingForSni=1 并确认出网能访问 CA 的 OCSP 端点后恢复。
.NET 老项目强行 SecurityProtocol = Tls12
这本身没错,但在 Windows 2022 + .NET 4.8 本可上 TLS 1.3。我们统一改为 SystemDefault 并开启 SchUseStrongCrypto,既满足合规也吃到平台优化。
变更与回滚(我用的操作节奏)
- 灰度:先在备用节点应用策略 → 业务探活/压测 → 切 VIP;
- 观察:抓取 Schannel 事件、IIS 日志、端到端延迟;
- 一键回滚:把 GPO“SSL Cipher Suite Order”置回“未配置”或导入变更前 reg 快照;
- 复盘:把拒绝的 UA/IP 整理成报表给业务沟通升级与迁移。
凌晨五点,支付厂商的回归用例全部绿灯,我把工单里的“TLS 1.3 验证细节”截图粘上去:TLS1.3/AEAD 协商、HSTS 生效、无 CBC/3DES、HTTP/3 在香港—广州链路上首包耗时下降了 10%+。这活儿看上去是“调 TLS”,本质是把系统、应用、网络、合规几层同时拧紧——禁旧、留新、最小可用集,把每一条变更都让日志和扫描器说话。
如果你也在香港机房里为跨境支付上线 Windows 2022,我的建议是:先用官方基线确认“默认已然很强”,再把它“强里挑强”;剩下的交给监控与复盘。加密世界没有一劳永逸,但每一次上线,都能让明天的你少掉一次告警。