启动与虚拟机故障

排查 Azure IMDS 证书链故障 - Virtual Machines

· 52CE 我爱测

适用于:✔️ Linux VM 总结 本文可帮助你排查 Linux VM 上Azure实例元数据服务(IMDS)证明终结点的证书链问题。 这些问题可能会影响依赖于 IMDS 证明数据的应用程序,以便进行 VM 身份验证、许可验证或安全令牌获取。 注释 有关Windows VM,请参阅Windows上的 IMDS 证书链问题(../windows/windows-vm-imds-certissues)。 证书链体系结构 IMDS 证明使用四级证书链,该链在

适用于:✔️ Linux VM

总结

本文可帮助你排查 Linux VM 上Azure实例元数据服务(IMDS)证明终结点的证书链问题。 这些问题可能会影响依赖于 IMDS 证明数据的应用程序,以便进行 VM 身份验证、许可验证或安全令牌获取。

注释

有关Windows VM,请参阅Windows上的 IMDS 证书链问题。

证书链体系结构

IMDS 证明使用四级证书链,该链在 Windows 和 Linux 中相同:

DigiCert Global Root G2 (Root CA)
  +-- Microsoft TLS RSA Root G2 (cross-signed intermediate)
        +-- Microsoft TLS G2 RSA CA OCSP xx (OCSP responder intermediate)
              +-- CN=metadata.azure.com (leaf certificate)

Important

尽管名为“Microsoft TLS RSA Root G2”,它并不是根证书颁发机构。 它是由 DigiCert Global Root G2 颁发的交叉签名的中间证书。

注释

IMDS 轮换 OCSP 中间证书。 Azure 使用多个编号为 02 至 16 的 OCSP 响应程序中间证书。 VM 可以使用其中任意一个。

与Windows的主要区别

与Windows不同,大多数 Linux 分发版不会通过 AIA(颁发机构信息访问)自动下载缺少的中间证书。 如果信任存储中缺少中间证书,则链生成会立即失败。 此限制使问题在 Linux 上更加明显,但也意味着修复非常简单:安装缺少的证书。

症状

查询 IMDS 已证明终结点的应用程序会失败,并出现证书或 SSL 错误。 常见症状包括:

  • 访问 curl IMDS 认证端点时返回证书验证错误
  • Python 应用程序引发ssl.SSLCertVerificationError
  • Java应用程序报告sun.security.validator.ValidatorException
  • 自定义许可或身份验证以无提示方式失败

如何诊断

步骤 1:验证 IMDS 是否可访问

curl -s -H "Metadata:true" \
  "http://169.254.169.254/metadata/instance?api-version=2021-02-01" | head -c 200

如果此命令返回 JSON 元数据,则 IMDS 连接正常工作。 此问题特定于已证明的终结点和证书。

步骤 2:提取已证明的文档并检查证书链

# Get the attested document
ATTESTED=$(curl -s -H "Metadata:true" \
  "http://169.254.169.254/metadata/attested/document?api-version=2018-10-01")

# Extract the signing certificate from the PKCS#7 signature
echo "$ATTESTED" | python3 -c "
import json, sys, base64
doc = json.load(sys.stdin)
sig = base64.b64decode(doc['signature'])
with open('/tmp/imds_sig.der', 'wb') as f:
    f.write(sig)
print('Signature saved to /tmp/imds_sig.der')
"

# Extract the certificate from the PKCS#7 envelope
openssl pkcs7 -in /tmp/imds_sig.der -inform DER -print_certs -out /tmp/imds_cert.pem 2>/dev/null

# View the certificate details
openssl x509 -in /tmp/imds_cert.pem -noout -subject -issuer -dates

步骤 3:验证证书链

# Check if the chain validates against the system trust store
openssl verify -verbose /tmp/imds_cert.pem 2>&1

如果看到 error 20 at 0 depth lookup: unable to get local issuer certificate,信任存储中缺少中间证书或根证书。

步骤 4:确定 VM 使用的 OCSP 中间层

IMDS 轮换 OCSP 中间证书。 在安装证书之前,请确定 VM 使用哪个证书:

# Extract the OCSP number from the leaf certificate's issuer
OCSP_ISSUER=$(openssl x509 -in /tmp/imds_cert.pem -noout -issuer)
echo "Leaf issuer: $OCSP_ISSUER"
OCSP_NUM=$(echo "$OCSP_ISSUER" | grep -oP 'OCSP \K[0-9]+')
echo "Your VM uses OCSP: $OCSP_NUM"

在以下部分中的安装命令中使用此 OCSP 编号。 这些示例使用 04 ,但 VM 可能使用不同的数字(02、06、08、10、12、14 或 16)。

步骤 5:检查信任存储中有哪些证书

# Check for DigiCert Global Root G2
awk -v cmd='openssl x509 -noout -subject' '/BEGIN/{close(cmd)};{print | cmd}' \
  /etc/ssl/certs/ca-certificates.crt 2>/dev/null | grep -i "DigiCert Global Root G2"

# Check for Microsoft TLS RSA Root G2
awk -v cmd='openssl x509 -noout -subject' '/BEGIN/{close(cmd)};{print | cmd}' \
  /etc/ssl/certs/ca-certificates.crt 2>/dev/null | grep -i "Microsoft TLS"

步骤 6:测试证书下载终结点的连接

# Test AIA endpoints (port 80)
for host in cacerts.digicert.com caissuers.microsoft.com www.microsoft.com; do
    if curl -s --connect-timeout 5 -o /dev/null "http://$host"; then
        echo "[OK] $host"
    else
        echo "[BLOCKED] $host"
    fi
done

解决方案

安装缺少的证书

下载并安装信任存储中缺少的中间证书。 可能需要同时安装交叉签名中间证书和 OCSP 响应程序中间证书。

Important

证书下载 URL 提供 DER 格式的文件。 Linux 信任存储需要 PEM 格式。 安装前,务必使用 openssl x509 -inform DER 进行转换。

注释

IMDS 将轮换 OCSP 中间体(编号为 02 到 16)。 检查叶证书的签发者(步骤 4),以确定您的 VM 使用的是哪个 OCSP 中间证书。 将下方下载 URL 中的 04 替换为您的 VM 的实际 OCSP 编号。 例如,如果 VM 使用 OCSP 10,请更改为 OCSP%2004``OCSP%2010。

Ubuntu/Debian

# Install the cross-signed intermediate (Microsoft TLS RSA Root G2)
sudo curl -s -o /tmp/microsoft-tls-rsa-root-g2.der \
  "http://caissuers.microsoft.com/pkiops/certs/Microsoft%20TLS%20RSA%20Root%20G2%20-%20xsign.crt"
sudo openssl x509 -in /tmp/microsoft-tls-rsa-root-g2.der -inform DER \
  -out /usr/local/share/ca-certificates/microsoft-tls-rsa-root-g2.crt

# Install the OCSP intermediate (replace 04 with your VM's OCSP number)
sudo curl -s -o /tmp/microsoft-tls-g2-rsa-ca-ocsp.der \
  "https://www.microsoft.com/pkiops/certs/Microsoft%20TLS%20G2%20RSA%20CA%20OCSP%2004.crt"
sudo openssl x509 -in /tmp/microsoft-tls-g2-rsa-ca-ocsp.der -inform DER \
  -out /usr/local/share/ca-certificates/microsoft-tls-g2-rsa-ca-ocsp.crt

# Update the certificate store
sudo update-ca-certificates

RHEL / CentOS / Oracle Linux / Azure Linux

# Install the cross-signed intermediate
sudo curl -s -o /tmp/microsoft-tls-rsa-root-g2.der \
  "http://caissuers.microsoft.com/pkiops/certs/Microsoft%20TLS%20RSA%20Root%20G2%20-%20xsign.crt"
sudo openssl x509 -in /tmp/microsoft-tls-rsa-root-g2.der -inform DER \
  -out /etc/pki/ca-trust/source/anchors/microsoft-tls-rsa-root-g2.crt

# Install the OCSP intermediate (replace 04 with your VM's OCSP number)
sudo curl -s -o /tmp/microsoft-tls-g2-rsa-ca-ocsp.der \
  "https://www.microsoft.com/pkiops/certs/Microsoft%20TLS%20G2%20RSA%20CA%20OCSP%2004.crt"
sudo openssl x509 -in /tmp/microsoft-tls-g2-rsa-ca-ocsp.der -inform DER \
  -out /etc/pki/ca-trust/source/anchors/microsoft-tls-g2-rsa-ca-ocsp.crt

# Update the certificate store
sudo update-ca-trust

SUSE /openSUSE

# Install the cross-signed intermediate
sudo curl -s -o /tmp/microsoft-tls-rsa-root-g2.der \
  "http://caissuers.microsoft.com/pkiops/certs/Microsoft%20TLS%20RSA%20Root%20G2%20-%20xsign.crt"
sudo openssl x509 -in /tmp/microsoft-tls-rsa-root-g2.der -inform DER \
  -out /usr/share/pki/trust/anchors/microsoft-tls-rsa-root-g2.crt

# Install the OCSP intermediate (replace 04 with your VM's OCSP number)
sudo curl -s -o /tmp/microsoft-tls-g2-rsa-ca-ocsp.der \
  "https://www.microsoft.com/pkiops/certs/Microsoft%20TLS%20G2%20RSA%20CA%20OCSP%2004.crt"
sudo openssl x509 -in /tmp/microsoft-tls-g2-rsa-ca-ocsp.der -inform DER \
  -out /usr/share/pki/trust/anchors/microsoft-tls-g2-rsa-ca-ocsp.crt

# Update the certificate store
sudo update-ca-certificates

验证修复

安装证书后,验证证书链是否有效:

# Re-fetch and verify
curl -s -H "Metadata:true" \
  "http://169.254.169.254/metadata/attested/document?api-version=2018-10-01" \
  | python3 -c "import json,sys,base64; d=json.load(sys.stdin); open('/tmp/imds_sig.der','wb').write(base64.b64decode(d['signature']))"

openssl pkcs7 -in /tmp/imds_sig.der -inform DER -print_certs -out /tmp/imds_cert.pem 2>/dev/null
openssl verify -verbose /tmp/imds_cert.pem

成功的输出显示:

/tmp/imds_cert.pem: OK

Tip

还可以将 --autofix 标志与 验证工具 配合使用,在一个步骤中自动执行下载、转换、安装、信任存储更新和重新验证。

更多情景

时钟倾斜导致验证失败

症状:openssl verify 即使证书应仍在有效期内,也会因 certificate is not yet valid 或 certificate has expired 而失败。

原因: 虚拟机的系统时钟存在严重偏差。 证书验证会根据本地时钟检查 notBefore 和 notAfter。

如何检测:

# Check current time vs NTP
date -u
chronyc tracking 2>/dev/null || ntpq -p 2>/dev/null

解决方法:

# Force time sync (chrony)
sudo chronyc makestep

# Or force time sync (ntpd)
sudo ntpdate time.windows.com

同步时钟后,重新运行 openssl verify /tmp/imds_cert.pem。

已过期的中间证书

症状: 中间证书已存在于信任存储中,但 openssl verify 仍然失败。 证书的 notAfter 日期已过。

如何检测:

# Check expiry of the OCSP intermediate
openssl x509 -in /tmp/imds_cert.pem -noout -issuer -dates

解决方法: 下载新的证书,并使用上一“解决方案”部分中特定于发行版的命令重新安装它。 验证工具的 --autofix 标志会自动处理此步骤。

代理会拦截 AIA,但不会拦截 IMDS

症状: IMDS 可访问(步骤 1 通过),但证书下载终结点被阻止(步骤 6 失败)。

原因: IMDS 使用会绕过代理设置的链路本地地址(169.254.169.254)。 证书下载 URL 通过已配置的代理。 如果代理阻止 AIA 终结点,证书下载会失败。

如何检测:

# Check proxy settings
echo "http_proxy=$http_proxy"
echo "https_proxy=$https_proxy"
env | grep -i proxy

分辨率: 将 AIA 和 CRL 终结点添加到 no_proxy 环境变量:

export no_proxy="$no_proxy,caissuers.microsoft.com,www.microsoft.com,cacerts.digicert.com,crl3.digicert.com,crl4.digicert.com,ocsp.digicert.com,oneocsp.microsoft.com"

若要使此更改永久化,请将 export 行添加到 /etc/environment 或 /etc/profile.d/proxy.sh.

预安装的证书即将过期

症状: IMDS 已正常运行数月,然后突然开始失效。 所有 AIA 终结点都被阻止(防火墙策略)。 VM 依赖于预安装的证书。

原因: 如果阻止 AIA,请预安装所有中间证书。 这些证书具有到期日期。 过期后,链会失败,VM 无法自动加载替换。

如何检测:

# Check expiry of installed Microsoft TLS certs
for cert in /usr/local/share/ca-certificates/microsoft-*.crt \
             /etc/pki/ca-trust/source/anchors/microsoft-*.crt \
             /usr/share/pki/trust/anchors/microsoft-*.crt; do
    [ -f "$cert" ] && echo "$(openssl x509 -in "$cert" -noout -enddate 2>/dev/null) $cert"
done

解决方法:

  1. 从“Azure证书颁发机构详细信息”页下载新证书。

  2. 若要防止 AIA 被阻止时将来出现过期问题,请预安装 所有 OCSP 中间变体(02 到 16)。 这样,VM 就可以在 OCSP 轮换中幸存下来,而无需下载任何内容:

    for NUM in 02 04 06 08 10 12 14 16; do
        curl -s -o "/tmp/ocsp-${NUM}.der" \
            "https://www.microsoft.com/pkiops/certs/Microsoft%20TLS%20G2%20RSA%20CA%20OCSP%20${NUM}.crt"
        openssl x509 -in "/tmp/ocsp-${NUM}.der" -inform DER \
            -out "/usr/local/share/ca-certificates/microsoft-tls-g2-rsa-ca-ocsp-${NUM}.crt"
    done
    sudo update-ca-certificates
    

    注释

    显示的证书安装路径适用于 Ubuntu/Debian。 对于 RHEL,请使用 /etc/pki/ca-trust/source/anchors/ 和 update-ca-trust。 对于 SUSE,请使用 /usr/share/pki/trust/anchors/ 和 update-ca-certificates。

防火墙注意事项

如果 VM 的防火墙阻止出站 HTTP(端口 80),则无法从 AIA 终结点下载证书。 确保可访问以下终结点:

Purpose Endpoints
AIA (证书下载) cacerts.digicert.com、caissuers.microsoft.com、www.microsoft.com
CRL(证书吊销列表) crl3.digicert.com、crl4.digicert.com
OCSP (在线验证) ocsp.digicert.com、oneocsp.microsoft.com

有关详细信息,请参阅 证书下载和吊销列表。

资料来源与适用范围

资料来源
微软官方 Linux 虚拟机排障文档
适用范围
Azure Linux 虚拟机;按正文发行版、内核及代理版本
内容语言
中文;命令、路径和错误标识保留技术原文
本地收录日期
2026-10-26
授权说明
CC BY 4.0

正文与所需资源由本站本地存储。查看来源及更新记录 ↗

请按适用版本和实际日志确认原因;本站没有对每一种系统或设备逐项执行文中的操作。