什么是 OCSP Must-Staple

OCSP Must-Staple(RFC 6066 第 8 节定义)是一种证书扩展,用于告知客户端证书颁发机构(CA)要求在 TLS 握手时必须提供 OCSP 响应。通过此扩展,客户端可以拒绝与无法提供有效 OCSP 响应(或 OCSP stapling)的服务器建立连接。

作用机制

当证书包含 Must-Staple 扩展时:

  1. 服务器端:必须在 TLS 握手时通过 OCSP stapling 发送预缓存的 OCSP 响应
  2. 客户端验证:支持 Must-Staple 的客户端会检查 stapled OCSP 响应是否存在且有效
  3. 连接拒绝:如果服务器未提供有效的 OCSP 响应,客户端将拒绝建立连接

安全价值

Must-Staple 主要防止以下攻击场景:

  • 防止吊销绕过:攻击者无法通过阻止客户端直接查询 OCSP 服务器来绕过证书吊销检查
  • 减少客户端到 CA 的网络请求:通过 stapling 减少延迟和隐私泄露
  • 强制证书状态检查:确保每次连接都进行证书有效性验证

验证证书是否包含 Must-Staple

使用 Let’s Encrypt 证书(推荐)

Let’s Encrypt 签发的证书默认包含 Must-Staple 扩展。可以使用以下方式验证:

1
2
# 查看证书扩展信息
openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -text | grep -i "ocsp"

如果证书包含 Must-Staple,会看到类似输出:

1
2
3
OCSP Must-Staple: 
    TLS Feature: 
        status_request

或者使用 OID 直接检查:

1
openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -text | grep -A2 "1.3.6.1.5.5.7.1.24"

使用 OpenSSL 查看完整扩展

1
openssl x509 -in your_certificate.pem -noout -text

在输出中查找 TLS Feature 扩展:

1
2
X509v3 TLS Feature: 
    TLS Feature: status_request

服务器配置

Nginx 配置

Nginx 从 1.3.7 版本开始支持 OCSP stapling。配置示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;

    # 启用 OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;

    # 解析 OCSP 响应器(使用可信 DNS)
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
}

配置说明:

  • ssl_stapling on:启用 OCSP stapling
  • ssl_stapling_verify on:验证 stapling 响应
  • resolver:指定 DNS 服务器用于解析 OCSP 响应器地址
  • valid=300s:缓存 DNS 解析结果 300 秒

Apache 配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<VirtualHost *:443>
    ServerName example.com
    SSLEngine on
    SSLCertificateFile /path/to/fullchain.pem
    SSLCertificateKeyFile /path/to/privkey.pem

    # 启用 OCSP stapling
    SSLUseStapling on
    SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
    SSLStaplingStandardCacheTimeout 3600
    SSLStaplingErrorCacheTimeout 600
</VirtualHost>

测试配置

配置完成后,重启服务并测试:

1
2
3
4
5
# 重启 Nginx
nginx -t && nginx -s reload

# 或重启 Apache
apachectl graceful

验证 Must-Staple 配置

使用 OpenSSL s_client 测试

1
2
# 测试 OCSP stapling 是否正常工作
echo | openssl s_client -connect example.com:443 -servername example.com -status 2>&1 | grep -A5 "OCSP Response"

正常输出示例:

1
2
3
4
5
OCSP Response Status: successful (0x0)
OCSP Response Data:
    OCSP Response IDs:
        OCSP Response ID: (null)
    Cert Status: good

使用 testssl.sh 检测

1
2
# 检测服务器 Must-Staple 支持情况
testssl --standard example.com | grep -i "must-staple"

使用 curl 验证

1
2
3
# curl 7.68.0+ 支持 Must-Staple
# 如果服务器未正确配置 OCSP stapling,会显示警告
curl -vI https://example.com/ 2>&1 | grep -i "staple"

注意事项

兼容性考虑

  • 旧版客户端:不支持 Must-Staple 的客户端会忽略此扩展,正常建立连接
  • 服务器必须支持 stapling:如果证书包含 Must-Staple 但服务器未配置 OCSP stapling,支持该特性的客户端会拒绝连接
  • OCSP 响应器可用性:确保服务器能成功获取并缓存 OCSP 响应

维护建议

  1. 监控 OCSP 响应:定期检查 stapling 是否正常工作
  2. 证书续期:Let’s Encrypt 证书续期后自动保留 Must-Staple
  3. 故障排查:如果客户端突然无法连接,首先检查 OCSP stapling 状态

常见问题

Q: Must-Staple 会导致连接失败吗?

A: 仅当服务器无法提供有效的 OCSP 响应时才会失败。正确配置 OCSP stapling 后不会影响正常连接。

Q: 如何判断证书是否包含 Must-Staple?

A: 使用 openssl x509 -in cert.pem -noout -text | grep "TLS Feature" 检查是否存在 status_request。

Q: 可以为已有证书添加 Must-Staple 吗?

A: 不能。Must-Staple 是证书签发时嵌入的扩展,只能在重新签发证书时添加。


完整配置示例

以下是一个完整的 Nginx 配置示例,包含现代 TLS 最佳实践:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
server {
    listen 443 ssl http2;
    server_name example.com;

    # 证书路径(Let's Encrypt)
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # OCSP Stapling 配置
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s ipv6=off;
    resolver_timeout 5s;

    # TLS 配置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    # HSTS(可与 Must-Staple 配合使用)
    add_header Strict-Transport-Security "max-age=63072000" always;

    # 其他安全头
    add_header X-Frame-Options DENY always;
    add_header X-Content-Type-Options nosniff always;
}

参考来源