如何在香港服务器的Windows Server 2019中启用Shielded VM保护虚拟化环境?

凌晨两点,香港葵涌的数据中心的 NOC 电话打过来,说有台用于测试的 VM 被人“好心”替换了模板磁盘,系统里多了莫名的管理员账户。所幸还在灰度环境。这种“误操作+人祸”的组合拳,我见得太多。
我抬头看机柜里那一排 1U/2U 服务器,心里盘算:必须上 Shielded VM(受防护的虚拟机),把 VM 的磁盘、状态和启动过程都锁进“密室”,让 Hyper-V 管理员(包括我自己)拿不到 VM 内部的秘密。这一夜,我把 HGS(Host Guardian Service)和受防护主机做到了可用状态,模板盘、密钥、证书、加固策略一条条串起来。这里把全过程写下来。
1. 场景与目标
目标:在香港机房基于 Windows Server 2019 Datacenter 的 Hyper-V 集群上启用 Shielded VM,采用 TPM(硬件)信任证明 模式的 HGS。实现:
让 VM 使用 vTPM + BitLocker,加密操作系统盘与敏感数据;
在 HGS 授权前提下才能解密并启动;
禁止控制台注入恶意 ISO/交换模板盘导致的篡改;
管理员可运维宿主机,但无法“拿走”VM 的密钥与磁盘内容。
2. 逻辑拓扑与命名
结构:
┌───────────────────────────────────────────┐
│ HGS Forest (隔离域) │
│ HGS01 (Windows Server 2019) │
│ Host Guardian Service (Attestation/KPS)│
└───────────────▲───────────────▲──────────┘
│ │
Attestation URL ─┘ └─ Key Protection URL
│ (HTTPS/443)
│
┌───────────────────────┴───────────────────────────┐
│ Fabric Domain (生产域) │
│ HV01/HV02/HV03 ... (Windows Server 2019) │
│ Hyper-V + Host Guardian Hyper-V Support │
│ Failover Cluster + SMB/CSV 存储 │
└──────────────────────────────────────────────────┘
域与命名(示例)
HGS Forest:hgs.local,HGS 服务主机 HGS01.hgs.local
Fabric(生产域):corp.hk.local,Hyper-V 宿主 HV01.corp.hk.local 等
HGS 端点(生产上请用 HTTPS):
- Attestation:https://hgs01.hgs.local/Attestation
- Key Protection:https://hgs01.hgs.local/KeyProtection
3. 硬件与系统参数(现场实际/参考)
| 角色 | 型号/配置 | 关键点 |
|---|---|---|
| HGS01 | 1U 单路/双路服务器(如 Xeon Silver/Gold),64GB RAM,RAID1 SSD | 独立/隔离域,TLS 证书,至少 2 块硬盘,开启 UEFI/Secure Boot |
| HV01..HV03 | 2U 双路,256GB–512GB RAM,NVMe 缓存 + SATA SSD,TPM 2.0 芯片 | 必须支持 TPM 2.0(硬件模块),UEFI + Secure Boot |
| 交换机 | 10GbE TOR,VLAN 隔离 | HGS/管理/存储 网络独立 VLAN,ACL 放通 443/LDAP/DNS/NTP |
| 存储 | SMB3/CSV,后端 RAID10 | 主机间低延迟,保证集群漂移时 HGS 访问可达 |
系统版本
- 全部 Windows Server 2019 Datacenter(HGS 与 Shielded VM 需要数据中心版)
- 宿主启用 Hyper-V、Failover Clustering、Host Guardian 客户端工具
- VM 必须为 Generation 2
4. 先决条件与准备
- 两套 AD 林:HGS Forest 与 Fabric Forest 建议物理/逻辑隔离。HGS 林权限最小化。
- PKI/证书:HGS 的签名证书与加密证书(生产上建议使用企业 CA 颁发,本文示例用自签发快速落地)。
- 时间同步:HGS 与 Hyper-V 宿主时间误差 < 5 分钟(TPM 证明对时间很敏感)。
- DNS/NTP:双向可达;Fabric 能解析 hgs.local;HGS 能解析宿主 FQDN。
- 网络:放通 443(Key Protection)、Attestation(建议也走 HTTPS/443),以及必要的 LDAP/DNS/NTP。
- 宿主硬件 TPM:必须有 TPM 2.0 并在 BIOS 开启;UEFI + Secure Boot 开启。
5. 实施步骤(逐步可回放)
所有 PowerShell 请在 以管理员身份 打开,且在对应机器执行。
5.1 在 HGS 服务器上部署隔离域与 HGS
5.1.1 安装 AD DS 并创建 HGS 林
# HGS01 上
Install-WindowsFeature AD-Domain-Services -IncludeManagementTools
# 创建新林:hgs.local(会重启,注意安全密码)
Install-ADDSForest -DomainName "hgs.local" -DomainNetbiosName "HGS" `
-SafeModeAdministratorPassword (Read-Host -AsSecureString "DSRM Password") `
-InstallDNS
重启后以 hgs\Administrator 登录。
5.1.2 安装 Host Guardian Service 角色并初始化
# HGS 角色
Install-WindowsFeature HostGuardianServiceRole -IncludeManagementTools
# 生成签名/加密证书(生产建议用企业 CA)
$signCert = New-SelfSignedCertificate -DnsName "HgsSigning.hgs.local" `
-KeyUsage DigitalSignature -CertStoreLocation "Cert:\LocalMachine\My"
$encCert = New-SelfSignedCertificate -DnsName "HgsEncryption.hgs.local" `
-KeyUsage KeyEncipherment,DataEncipherment -CertStoreLocation "Cert:\LocalMachine\My"
# 初始化 HGS 服务(创建 HGS 服务对象)
Install-HgsServer -HgsServiceName "HGS" `
-SigningCertificate $signCert -EncryptionCertificate $encCert
注:生产中请将 $signCert/$encCert 替换为企业 CA 颁发证书,并妥善保管私钥。Key Protection(KPS)端点必须走 HTTPS 并符合证书链。
5.1.3 选择证明模式(TPM)并启动服务
# 启用 TPM(硬件)信任证明
Initialize-HgsAttestation -TrustTpm
# 查看服务状态/URL
Get-HgsServer
你会得到类似:
- Attestation:https://hgs01.hgs.local/Attestation
- KeyProtection:https://hgs01.hgs.local/KeyProtection
小贴士:若用自签证书,Fabric 侧需要信任 HGS 证书链(导入根证书到受信任的根)。
5.2 在 Hyper-V 宿主上安装必要功能与注册 HGS
5.2.1 安装 Hyper-V 与 Host Guardian 客户端
# HV01 上
Install-WindowsFeature Hyper-V -IncludeManagementTools -Restart
# 安装 Host Guardian Hyper-V 支持/工具
Install-WindowsFeature HostGuardian -IncludeAllSubFeature
Install-WindowsFeature RSAT-HostGuardianServiceTools
5.2.2 设置 HGS 端点并校验联通
# 设置 HGS 端点 URL(使用你的实际 FQDN/HTTPS)
Set-HgsClientConfiguration `
-AttestationServerUrl "https://hgs01.hgs.local/Attestation" `
-KeyProtectionServerUrl "https://hgs01.hgs.local/KeyProtection"
# 检查配置/连通性
Get-HgsClientConfiguration
5.2.3 采集宿主的 TPM 平台标识并在 HGS 上授权
在 HV01 上:
# 生成平台标识(TPM 证据)
$pid = (Get-PlatformIdentifier -Name "HV01").Identifier
$pid | Out-File C:\Temp\HV01.pid.txt
把 HV01.pid.txt 复制到 HGS01,在 HGS01 上执行授权:
# HGS 上将 HV01 加入受信任清单
$pid = Get-Content C:\Temp\HV01.pid.txt
Add-HgsAttestationTpmHost -Name "HV01" -Identifier $pid
对所有宿主(HV02/HV03...)重复一次各自授权。
验证:在 HV01 上 Test-HgsClientConfiguration(如果有该工具)或尝试创建/启动受防护 VM,看能否成功向 KPS 请求密钥。
5.3 准备受信任的模板磁盘与 Shielding Data(.pdk)
Shielded VM 强依赖“可信模板盘(VHDX)+ Shielding Data 文件(.pdk)”。
5.3.1 制作模板 VHDX(建议离线 Sysprep)
用干净 ISO 安装一台 Gen2 虚机(不加域),打补丁、安装基础代理(如 VM Agent),不要放置敏感账户。
执行:
# VM 内
%windir%\System32\Sysprep\Sysprep.exe /oobe /generalize /shutdown
关机后将其 VHDX 作为模板保存到 “模板库”。
5.3.2 生成模板盘签名(确保模板不可被掉包)
在拥有模板盘的管理机上(可用 RSAT):
# 生成模板盘哈希(示例用 SHA256)
$tmpl = "D:\Templates\WS2019-Base.vhdx"
$hash = (Get-FileHash -Path $tmpl -Algorithm SHA256).Hash
$hash | Out-File D:\Templates\WS2019-Base.vhdx.sha256.txt
生产中更佳做法是使用 Volume Signature Catalog (VSC) 或配套工具生成磁盘签名并在 .pdk 中引用,确保模板一旦变更就无法被信任。
5.3.3 获取 Guardian(守护者)并生成 .pdk
在 HGS01 上导出 Fabric Guardian 公钥(或直接在管理机通过 RSAT 获取):
# HGS 上
$guardian = Get-HgsGuardian -Name "HGS"
$guardian | Export-HgsGuardian -Path C:\Temp\HGS_Guardian.xml
在管理机上(安装了 RSAT-HGS 工具)创建 Owner Guardian(拥有者守护者——用于日后“解封/迁移/恢复”权限)并生成 .pdk:
# 管理机(非 HGS)上
# 1) 创建本地 Owner Guardian
$owner = New-HgsGuardian -Name "Owner" -GenerateCertificates
# 2) 导入 HGS Guardian(Fabric Guardian)
$fabric = Import-HgsGuardian -Path C:\Temp\HGS_Guardian.xml
# 3) 生成 Shielding Data File(绑定模板签名、无人值守等)
New-ShieldingDataFile `
-Owner $owner `
-Guardian $fabric `
-ShieldingDataFilePath "C:\Shielding\WS2019_Base.pdk" `
-TemplateDiskDigestFile "D:\Templates\WS2019-Base.vhdx.sha256.txt" `
-WinUnattend "C:\Shielding\Unattend.xml" `
-RemoteDesktopEnabled $false
说明:
- .pdk 内含允许解密/启动 VM 的策略、密钥及模板签名白名单(磁盘哈希/签名)。
- Owner Guardian 是你的“主密钥”,妥善保管(可以导出证书+私钥并离线存储)。
- Unattend.xml 可定义计算机名前缀、产品密钥、加入域(建议通过后置脚本),以及本地管理员随机密码策略。
5.4 将现有 VM 加固为 Shielded VM(或从模板新建)
方案 A:现有 Gen2 VM 加固
$vm = "APP01"
# 1) 开启安全启动(Microsoft UEFI CA)
Set-VMSecurity -VMName $vm -EnableSecureBoot On `
-SecureBootTemplate "MicrosoftUEFICertificateAuthority"
# 2) 启用 vTPM(虚拟 TPM,受 HGS 保护)
Enable-VMTPM -VMName $vm
# 3) 应用 Shielding Data(关键一步)
Protect-VM -VMName $vm -ShieldingDataFilePath "C:\Shielding\WS2019_Base.pdk"
# 4)(可选)VM 内部再启用 BitLocker(使用 vTPM)
# 这一步在 VM 启动后,通过 GPO 或脚本执行:
# Enable-BitLocker -MountPoint "C:" -TpmProtector -UsedSpaceOnly
方案 B:从模板直接创建 Shielded VM
New-ShieldedVM `
-Name "APP02" `
-TemplateDiskPath "D:\Templates\WS2019-Base.vhdx" `
-ShieldingDataFilePath "C:\Shielding\WS2019_Base.pdk" `
-Path "E:\VMs\APP02"
成功后,该 VM 的 VHDX 即使被复制到外部,也无法在没有 HGS 授权的环境中解密或启动。
6. 运行维护与验证
6.1 快速健康检查
# 宿主侧
Get-HgsClientConfiguration
# (如有)测试连通
# Test-HgsClientConfiguration
- Hyper-V 管理器里,受防护 VM 的“安全性”标签会显示 受防护。
- 迁移(Live Migration)至其它已授权宿主同样可解密启动。
6.2 事件日志定位
- 宿主:Applications and Services Logs > Microsoft > Windows > HostGuardianClient/Operational
- HGS:Microsoft-Windows-HostGuardianService-*
- Hyper-V:Microsoft-Windows-Hyper-V-VMMS/Admin
遇到“无法向 Key Protection 服务请求密钥”或“Attestation 失败”,先看这三处。
7. 关键策略与表格参数(可抄作业)
7.1 HGS / Fabric 端口与 ACL(最小放通)
| 来源 | 目的 | 端口/协议 | 用途 |
|---|---|---|---|
| Fabric 宿主 | HGS01 | TCP 443 | Key Protection(必须,HTTPS) |
| Fabric 宿主 | HGS01 | TCP 443(或 80/可选) | Attestation(建议 HTTPS) |
| 双方 | DNS/NTP/LDAP | 53/123/389(636)/88 | 解析、授时、Kerberos/LDAP(按需最小化) |
真实部署中,我把 HGS 独立 VLAN,仅开放至宿主管理网的必要端口;CRL/OCSP 若使用企业 CA,需要确保 HGS 与宿主都能访问证书吊销/状态端点。
7.2 BIOS/固件与 OS 要求
| 项 | 要求 |
|---|---|
| 宿主固件 | UEFI + Secure Boot 开启 |
| TPM | TPM 2.0 并在 BIOS 打开 |
| OS 版本 | Windows Server 2019 Datacenter(HGS 与 Hyper-V 宿主) |
| VM | Generation 2,支持 vTPM |
8. 这些坑,我都踩过(当晚解决记录)
时间偏差导致 TPM 证明失败
现象:Attestation failed,宿主 HostGuardianClient/Operational 日志提示时间/证书问题。
处理:统一 NTP,HGS 与所有宿主对齐,偏差 < 5 分钟。香港机房我直接对齐同一对 Stratum2;再用 GPO 强制更新时间。
证书链不受信
现象:Key Protection HTTPS 访问报证书错误。
处理:把 HGS 用的根/中级证书链导入宿主的“受信任的根证书颁发机构”;生产上使用企业 CA 或公共可信 CA。
模板盘签名不匹配
现象:Template disk not trusted,Protect-VM 时报错。
处理:模板一旦重打补丁、重新 Sysprep,哈希或签名就变了,必须重新生成签名并更新 .pdk。我的做法是把模板盘放只读 CIFS 共享,并用 Git 追踪 .sha256.txt 的版本。
HGS 林与生产林 DNS 解析混乱
现象:宿主解析不到 hgs.local 或走了错误的转发器。
处理:在 Fabric DNS 上为 hgs.local 建条件转发;HGS DNS 仅解析自身域名,避免交叉污染。
宿主未开启 Secure Boot / TPM
现象:Enable-VMTPM 报不支持;受防护 VM 无法启动。
处理:重启进入 BIOS 开启 TPM 2.0 与 Secure Boot;注意部分老服务器需要升级 BIOS/TPM 固件。
网络 ACL 漏放 CRL/OCSP(使用企业 CA 时)
现象:偶发证书验证失败。
处理:放通企业 CA 的 CRL/OCSP 访问;或在离线/隔离环境准备好 CRL 分发。
9. 日常运维建议(我后来都这么做)
- 把 HGS 当“金库”:独立管理账号、独立跳板机,日志长保留,定期备份 HGS 数据库与证书私钥。
- 模板盘流程化:模板修改→Sysprep→签名→生成/更新 .pdk→发版。任何一步自动化(PowerShell + GitLab CI)都能减少“人祸”。
- Owner Guardian 离线保管:把拥有者证书/私钥导出并离线加密存储,模拟灾备恢复流程至少做一遍。
- 监控 HGS 延迟与可用性:在香港机房里,我给 HGS 做了 30 秒粒度的健康探针,告警阈值 1 分钟,避免“密钥服务挂了全场起不来”的尴尬。
- 合规审计:定期导出受信宿主清单(Get-HgsAttestationTpmHost),核对平台标识与资产台账。
10. 附:常用命令速查(可直接贴脚本)
# HGS 侧
Get-HgsServer
Get-HgsGuardian
Export-HgsGuardian -Path C:\Temp\HGS_Guardian.xml
Add-HgsAttestationTpmHost -Name "HV01" -Identifier "<PID>"
# 宿主侧
Set-HgsClientConfiguration -AttestationServerUrl "https://hgs01.hgs.local/Attestation" `
-KeyProtectionServerUrl "https://hgs01.hgs.local/KeyProtection"
Get-HgsClientConfiguration
Get-PlatformIdentifier -Name "HV01"
# VM 安全
Set-VMSecurity -VMName "APP01" -EnableSecureBoot On `
-SecureBootTemplate "MicrosoftUEFICertificateAuthority"
Enable-VMTPM -VMName "APP01"
Protect-VM -VMName "APP01" -ShieldingDataFilePath "C:\Shielding\WS2019_Base.pdk"
# 模板与签名
$hash = (Get-FileHash -Path "D:\Templates\WS2019-Base.vhdx" -Algorithm SHA256).Hash
$hash | Out-File D:\Templates\WS2019-Base.vhdx.sha256.txt
New-ShieldingDataFile -Owner (New-HgsGuardian -Name "Owner" -GenerateCertificates) `
-Guardian (Import-HgsGuardian -Path C:\Temp\HGS_Guardian.xml) `
-ShieldingDataFilePath "C:\Shielding\WS2019_Base.pdk" `
-TemplateDiskDigestFile "D:\Templates\WS2019-Base.vhdx.sha256.txt" `
-WinUnattend "C:\Shielding\Unattend.xml"
那天清晨三点多,机房灯忽明忽暗,维护人员在更换老旧灯管。我在 Hyper-V 管理器里看着几台关键业务 VM 迁移起来仍旧顺滑,日志里 Key Protection 请求一条条成功。那台“被好心人动过”的测试 VM,我重新按模板发布了 Shielded 版本——这次,没有谁能再随手换个 VHDX 就把它打开。
做安全,永远没有“万无一失”。但Shielded VM + HGS 把“人祸”的空间压到了最小。在香港这个高并发、跨区域延迟敏感的环境里,它是一层必要的“铁门”。你不需要每晚都睡在机房里盯着日志——只要把流程搭好、证书管好、模板盘走规程,你就可以安稳地坐在地铁上,手机里收到的只是健康检查的绿色勾。
如果你要在自己的香港服务器环境里落地 Shielded VM,就按这份清单一步步抄吧;等你把第一台受防护 VM 启动起来,听到它“咔哒”一声锁住密钥的那一刻,你会明白:值了。