apache 的 sslcarevocationcheck 指令用于启用客户端证书吊销状态检查(crl/ocsp),是构建高安全等级 pki 体系的关键配置。以下是完整的进阶配置方案:
核心原理
客户端握手 → 发送证书 → apache 验证证书链 → ├─ sslcarevocationcheck chain → 检查 crl/ocsp └─ 吊销状态确认 → 允许/拒绝连接
基础配置(crl 模式)
<virtualhost *:443>
sslengine on
# 根证书与中间证书
sslcertificatefile /etc/ssl/certs/server.crt
sslcertificatekeyfile /etc/ssl/private/server.key
sslcertificatechainfile /etc/ssl/certs/chain.pem
# 受信任的 ca(颁发客户端证书的 ca)
sslcacertificatefile /etc/ssl/certs/ca-issuing.crt
# 强制要求客户端证书
sslverifyclient require
sslverifydepth 2
# === 核心:启用 crl 吊销检查 ===
sslcarevocationcheck chain
# crl 文件路径(pem 格式,可包含多个 crl)
sslcarevocationfile /etc/ssl/crl/issuing-ca.crl
# 或 crl 目录(按哈希命名,推荐用于多 ca)
# sslcarevocationpath /etc/ssl/crl/
</virtualhost>三种检查模式对比
表格
| 模式 | 指令值 | 行为 | 适用场景 |
|---|---|---|---|
| 不检查 | none | 仅验证证书链,不检查吊销 | 内部测试环境(默认) |
| 仅叶子 | leaf | 仅检查客户端证书本身是否吊销 | 低安全场景 |
| 全链检查 | chain | 检查客户端证书 + 中间 ca 吊销 | 生产环境推荐 |
# 配置示例
<virtualhost *:443>
# 严格模式:检查整个证书链的吊销状态
sslcarevocationcheck chain
# 宽松模式:仅检查最终实体证书
# sslcarevocationcheck leaf
# 禁用检查(默认,生产环境不推荐)
# sslcarevocationcheck none
</virtualhost>进阶:ocsp stapling + crl 组合
<virtualhost *:443>
sslengine on
# === 服务端证书 ocsp stapling(优化性能)===
sslusestapling on
sslstaplingcache "shmcb:logs/ssl_stapling(32768)"
sslstaplingresponsemaxage 900
# === 客户端证书吊销检查 ===
sslverifyclient require
sslverifydepth 3
# 同时启用 crl 和 ocsp 检查(apache 2.4+)
sslcarevocationcheck chain
# crl 源
sslcarevocationfile /etc/ssl/crl/merged.crl
# ocsp 响应器配置(客户端证书 ocsp)
sslocspoverrideresponder on
sslocspresponderurl http://ocsp.ca.example.com:8080
sslocspproxyurl http://internal-proxy.example.com:3128
# 缓存 ocsp 响应提升性能
sslocspcachetimeout 600
</virtualhost>自动化 crl 更新架构
# /etc/apache2/conf-available/ssl-revocation.conf # 主配置 sslcarevocationcheck chain # 合并 crl 文件(由定时任务自动更新) sslcarevocationfile /etc/ssl/crl/merged-latest.crl # 备用:crl 目录(支持多 ca 场景) # sslcarevocationpath /etc/ssl/crl/dir/ # 严格模式:crl 过期则拒绝所有连接(默认 warn) # 注意:apache 2.4.30+ 支持,旧版本需 patch sslcarevocationcheck chain,strict
自动更新脚本(配合 cron)
#!/bin/bash
# /usr/local/bin/update-crl.sh
crl_dir="/etc/ssl/crl"
merged_file="$crl_dir/merged-latest.crl"
temp_dir=$(mktemp -d)
# 下载各 ca 的 crl
curl -ssf -o "$temp_dir/ca1.crl" "http://ca1.example.com/ca1.crl"
curl -ssf -o "$temp_dir/ca2.crl" "http://ca2.example.com/ca2.crl"
# 验证并转换格式
for f in $temp_dir/*.crl; do
openssl crl -in "$f" -inform der -out "$f.pem" 2>/dev/null || \
openssl crl -in "$f" -inform pem -out "$f.pem" 2>/dev/null
done
# 合并所有 crl
cat $temp_dir/*.pem > "$merged_file.tmp"
# 原子替换
mv "$merged_file.tmp" "$merged_file"
chmod 644 "$merged_file"
# 优雅重载 apache(不中断连接)
apachectl graceful
# 清理
rm -rf "$temp_dir"
# 记录日志
logger -t crl-update "crl updated at $(date), size: $(stat -c%s "$merged_file") bytes"# /etc/cron.d/crl-update # 每小时更新 crl(根据 ca 的 crl 发布周期调整) 0 * * * * root /usr/local/bin/update-crl.sh >> /var/log/crl-update.log 2>&1
多级 ca 与交叉认证场景
<virtualhost *:443>
sslengine on
# 多个受信 ca(企业根 + 外部合作伙伴 ca)
sslcacertificatepath /etc/ssl/certs/trusted-ca/
# 对应的多 crl 配置
sslcarevocationcheck chain
# 方案1:合并 crl 文件(简单)
# sslcarevocationfile /etc/ssl/crl/all-ca-merged.crl
# 方案2:crl 目录(按 openssl 哈希命名)
# 命名规则:$(openssl x509 -in ca.crt -noout -hash).r0
sslcarevocationpath /etc/ssl/crl/hashed/
</virtualhost>crl 目录哈希命名脚本
#!/bin/bash
# 生成 crl 目录的标准哈希链接
crl_dir="/etc/ssl/crl/hashed"
mkdir -p "$crl_dir"
for crl in /etc/ssl/crl/source/*.crl; do
# 提取签发者名称计算哈希
hash=$(openssl crl -in "$crl" -noout -issuer_hash 2>/dev/null)
if [ -n "$hash" ]; then
# 创建标准命名链接
ln -sf "$crl" "$crl_dir/${hash}.r0"
echo "linked $crl -> $crl_dir/${hash}.r0"
fi
done
# 处理冲突(同一哈希多个 crl)
i=1
for f in "$crl_dir"/*.r0; do
if [ -l "$f" ] && [ -e "$f" ]; then
# 检查是否指向同一文件
true
else
# 处理为 .r1, .r2 等
mv "$f" "${f%.r0}.r$i" 2>/dev/null
fi
doneocsp 实时查询(无 crl 场景)
<virtualhost *:443>
sslengine on
sslverifyclient require
# 仅使用 ocsp(不配置 crl 文件)
sslcarevocationcheck chain
# ocsp 响应器(必须可从服务器访问)
sslocspoverrideresponder on
sslocspresponderurl http://ocsp.internal.example.com
# 超时与重试
sslocspresponsetimeskew 300
sslocspresponsemaxage 86400
# 网络超时
sslocsptimeout 5
# 错误处理:ocsp 不可用时是否允许连接
# 注意:apache 2.4.26+ 支持,需谨慎使用
# sslocspnoverify on # 测试环境跳过 ocsp 签名验证
</virtualhost>高可用与故障转移
<virtualhost *:443>
sslengine on
sslverifyclient require
sslcarevocationcheck chain
# 主 crl 源
sslcarevocationfile /etc/ssl/crl/primary.crl
# 备用机制:当 crl 过期/不可用时
# 通过环境变量控制降级(需 mod_env + 自定义逻辑)
<if "-f '/etc/ssl/crl/emergency.crl'">
# 紧急模式下使用本地缓存 crl
sslcarevocationfile /etc/ssl/crl/emergency.crl
</if>
# 日志记录吊销检查详情
loglevel ssl:warn
errorlog /var/log/apache2/ssl-error.log
customlog /var/log/apache2/ssl-access.log "%t %h %{ssl_client_s_dn}x %{ssl_client_verify}x %{ssl_client_i_dn}x"
</virtualhost>调试与监控
# 详细 ssl 日志(临时启用)
loglevel trace8
# 自定义日志格式包含吊销状态
logformat "%h %l %u %t \"%r\" %>s %b \"%{ssl_client_verify}s\" \"%{ssl_client_s_dn}x\" \"%{ssl_client_i_dn}x\"" ssl_combined
<virtualhost *:443>
customlog /var/log/apache2/ssl-audit.log ssl_combined
# 拒绝时记录详细原因
ssloptions +stdenvvars +exportcertdata
</virtualhost>关键日志分析
# 吊销检查成功
[ssl:info] certificate verification: depth: 1, subject: /cn=intermediate ca,
issuer: /cn=root ca, ok
[ssl:info] certificate verification: depth: 0, subject: /cn=client 123,
issuer: /cn=intermediate ca, ok
# 证书被吊销(crl 匹配)
[ssl:error] certificate verification: error (23): certificate revoked
[ssl:error] re-negotiation handshake failed: certificate revoked?
# crl 过期警告
[ssl:warn] crl has expired, crl checking will be skipped for this ca关键注意事项
| 注意点 | 说明 |
|---|---|
| 性能影响 | crl 文件越大,验证越慢;建议定期清理过期条目 |
| crl 时效性 | 必须确保持续更新,过期 crl 默认跳过检查(非严格模式) |
| 网络隔离 | ocsp 查询需出站网络,内网 ca 需内部 ocsp 响应器 |
| apache 版本 | chain 模式需 2.4+;严格模式需 2.4.30+ |
| 证书链完整性 | 必须配置完整的 sslcertificatechainfile,否则链式检查失败 |
核心建议:生产环境采用 crl 本地缓存 + ocsp 实时校验 的双保险策略,配合自动化更新脚本,在安全与可用性之间取得平衡。
到此这篇关于apache配置sslcarevocationcheck吊销检查的实现的文章就介绍到这了,更多相关apache sslcarevocationcheck吊销检查内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论