☰
VMware vCenter证书过期检测与自动替换:从原理到脚本实践
2026/10/20 8:04:16 网站建设 项目流程

简介:VMware虚拟化环境中,证书过期是一类常见且棘手的故障,轻则出现安全警告,重则导致vCenter管理界面无法访问、ESXi主机失去连接。这套脚本正是面向VMware运维人员推出的证书过期处理工具包,围绕vSphere/vCenter的证书生命周期管理,提供了从状态检查到修复清理的完整方案。资源包共4个文件,包含1个Python脚本和3个Shell脚本,压缩后仅7KB,轻量且便于携带。其中checksts.py用于检测Service Trust Reputation(STR)状态,帮助定位过期证书;fixsts.sh负责修复STR过期问题,可执行更新或重新初始化操作;fix_encipherment_cert.sh专门处理加密证书的更换或续期,保障数据传输安全;clean_backup_stores.sh则用于清理旧备份和临时文件,避免新旧证书相互干扰。整套脚本分工明确,先检查后修复,再清理残留,操作路径清晰,适合已具备一定VMware基础的管理员快速排查证书异常。资源已有2045人学习,脚本结构简洁、注释易懂,既能作为应急修复工具,也可为自定义证书管理流程提供参考。

1. VMware 证书过期:不是登录报错那么简单,是 vCenter 服务链整体停摆的开始

VMware vCenter 证书过期这几年几乎成了虚拟化环境里"定时炸弹"的代名词。表面看只是浏览器弹一个安全警告,实际上 vCenter 内部组件之间全部走证书互信:vpxd 信任 STS 的签名证书,Web Client 信任 machine SSL 证书,ESXi 信任 VMCA 根证书。任何一张证书过期,都会出现"管理页面能开、登录却失败,API 调不通,主机重新连接一直报错"的诡异状态。这类问题靠手工点 UI 根本救不回来,正确思路是提前用脚本周期性地检查全部证书剩余有效期,在到期前完成替换,并在出事后提供一条可回滚路径。下面这套从检测、备份到替换的 bash 实现就是为此准备的,适合手里管着多套 vCenter/ESXi 环境、想把证书维护真正纳入自动化流程的运维工程师。

2. 先摸清 vCenter 的证书家族:machine、STS、solution user 各自过期后的症状

2.1 三张证书的职责与过期影响

vCenter 不是单张证书,而是典型的"证书链 + 多组件互信"模型。machine SSL 证书对外提供 HTTPS 服务,vSphere Web Client、API、SDK 客户端连接的 443 端口用的就是它。过期后最明显的问题是浏览器和程序直接拒绝连接,vCenter 服务本身可能还在运行,但外部已经无法访问。STS 签名证书(Security Token Service)负责给 SSO 登录信息签名,SSO 令牌和 SAML assertion 都以它作为信任根;这张证书过期,vpxd 在向 STS 请求 token 时会失败,登录界面一直转圈或直接报 unspecified error。solution user 证书则是 vpxd、vapi、vsphere-ui 这些组件以 solution user 身份在 vmdir 中注册用的身份凭证,它过期不会直接体现在浏览器上,但组件间互调失败后,vpxd 日志里会出现大量 TLS 握手失败和 certificate verify failed。

所以只盯着浏览器地址栏的锁标志,大概率会漏掉 STS 和 solution user 这两张"内伤"证书。实际环境里最常见的情况是:用户打电话说 vCenter 登录不了但网页能开,查下来 SSL 证书在期限内,STS 证书却已经过期一周了。这也解释了为什么光靠人工点 UI 换一张证书行不通——要维护的至少是三个对象的证书,而不是一张。还有一张 VMCA 根证书也要留意,它是 vCenter 内置的证书签发机构,machine、solution user 以及 ESXi 的主机证书默认都由它签发。VMCA 根证书过期后,整个信任链都会断裂,最典型的症状是"证书刚刚续签完,加回来的 ESXi 主机还是报 host certificate verify failed",通常要用证书管理工具把主机证书重新生成一遍,或者直接把主机证书换成自定义 CA 签发的证书,再把该 CA 导入 vCenter 信任库。

2.2 用命令看清所有证书的过期时间

检查证书过期时间,我一般分两条线:本地读文件、远程探测端口。本地读文件适合在 vCenter Appliance 上直接执行,能拿到 STS 和 solution user 证书的信息;远程探测适合检查 ESXi 主机和尚未登录的 vCenter,只要目标开放了 443 端口就行。vCenter Appliance 里,STS 和 solution user 证书存储在 vmafd 组件维护的目录数据库中,用 dir-cli 查看:

/usr/lib/vmware-vmafd/bin/dir-cli certificate list

输出摘录如下,注意看 Not After 那一行:

Certificate: Subject: C=US, O=VMware, OU=VMware Certificate Authority, CN=VMCA Not Before: Sep 28 10:11:02 2024 GMT Not After: Sep 27 10:11:02 2026 GMT

如果证书数量很多,直接把输出重定向到文件再按 Not After 排序,或者用grep -A4 "Not After"只要过期行。dir-cli 的输出是按编码顺序排的,不是按时间排的,想挑快过期的建议写个小管道处理,别肉眼硬翻。远程探测的命令更通用,只要本机能连通目标就能用:

echo | openssl s_client -connect esxi01.local:443 -servername esxi01.local 2>/dev/null \ | openssl x509 -noout -dates

-servername在目标有多张证书时指定要探测的证书,避免因为 SNI 拿到错误的一张。-dates与-enddate的区别是前者同时输出 notBefore 和 notAfter,后者只要过期时间;脚本里解析用-enddate更省事。2>/dev/null 在这里不是可有可无,openssl s_client 握手失败时会把底层 TLS 错误打到 stderr,不重定向会让后续输出解析乱掉。

2.3 判断"是不是证书问题"的四个信号

在写脚本之前,先明确什么情况应该被脚本纳入处理范围。我总结四个高频信号。第一是 vCenter 的 Web Client 打开后反复提示连接不安全,或者直接白屏后跳登录失败,但 :5480 管理端口能正常进。:5480 走的是 VAMI 服务,和 vSphere 443 用的是不同证书体系,所以 :5480 能进、:443 进不去时,基本可以锁定 443 对应的 machine SSL 证书或 STS 证书出问题。

第二是已加入 vCenter 的 ESXi 主机在 vpxd 日志里反复报 TLS 错误。日志路径固定看 /var/log/vmware/vpxd/vpxd.log,检索关键字 SSL、TLS、trust、certificate,如果时间点集中在一张证书的失效时间附近,基本可以坐实。第三是脚本调 vSphere API 时报 certificate verify failed,但浏览器能访问。这是 SAN 缺失或者机器证书链没补全的典型表现,现代 TLS 客户端强制校验 SAN,浏览器则会容忍。第四是 vCenter 服务起来后个别组件是 stopped 状态,手动 start 也拉不起来。vpxd 依赖 STS,STS 证书失效时 service-control 按顺序启动会直接失败,状态一直处于 red。把这四个信号和前面三类证书对上号,再去看 2.2 节输出的过期时间,就能快速定位要先处理哪一张证书。这也是我坚持把检测脚本写成"全部列出来、逐张算剩余天数"的原因:不预判,让数据说话,哪里快过期一目了然。

3. 写脚本前先盘家底:备份、红线与工具链选型,缺一步都白干

3.1 备份连同权限一起保

证书替换脚本里最容易翻车的不是替换动作,而是备份。证书文件一旦被覆盖,想回滚只能靠备份;而备份如果丢了属主和权限位,回滚回来也起不了服务。vCenter Appliance 上有几个目录属于高危区,动之前必须先拉完整副本:/etc/vmware-vpx/ssl 是 vpxd 的机器证书和私钥;/etc/vmware-vsphere-ui/certificates/ssl 是 Web Client 的证书和私钥;/etc/vmware-vmafd 是 vmafd 的配置与证书数据库,记录了全局信任根。

备份命令我固定用cp -a,而不是普通 cp。-a 会把权限、属主、软链接全部原样保留。如果是在多处执行,建议再打包一次放到 vCenter 的 root 家目录之外,比如挂载的备份卷里,避免 vCenter 本身挂掉时备份也一起丢。

BACKUP_DIR="/root/cert-backup/$(date +%Y%m%d-%H%M%S)" mkdir -p "$BACKUP_DIR" cp -a /etc/vmware-vpx/ssl "$BACKUP_DIR/vpx-ssl" cp -a /etc/vmware-vsphere-ui/certificates/ssl "$BACKUP_DIR/vsphere-ui-ssl" cp -a /etc/vmware-vmafd "$BACKUP_DIR/vmafd" tar czf "${BACKUP_DIR}.tar.gz" -C /root "$(basename "$BACKUP_DIR")"

备份完别急着往下走,确认一下 tar 包能正常解开、文件 mode 没变。证书目录的私钥文件一般是 600,证书是 644,目录是 700。如果 tar 解开后私钥变成 644,回滚时 vpxd 会直接拒绝启动,因为 VMware 组件对私钥权限查得很严,多一个 group 读权限都会报 permission denied。

3.2 工具链怎么分工

脚本不需要发明新东西,针对 VMware 证书过期问题,常见的工具分工是三段式。openssl 负责所有"看"的动作:看证书剩余天数、看 SAN、看签名算法,它到处都有,vCenter Appliance 和 ESXi 都自带,不需要额外装包。vCenter 侧的"换"动作交给 /usr/lib/vmware-vmca/bin/certificate-manager,它是 vCenter Appliance 自带的证书管理入口,通过交互菜单支持替换 machine 证书、替换 solution user 证书、重新生成 VMCA 根证书等能力。脚本要调用它,通常借助 expect 模拟终端交互,因为它是菜单式程序,没有提供完整的非交互参数集合。

ESXi 侧的"换"动作走文件替换加重启服务:把新证书覆盖到 /etc/vmware/ssl/rui.crt 和 rui.key,然后重启 hostd 和 vpxa。也可以用 esxcli 的相关子命令做类似操作,但文件直替在跨版本场景里可预期性更好,回滚也简单,把旧文件放回去重启服务即可。选型时还有一个隐性因素:安全通道。批量对 ESXi 执行操作时,scp/ssh 是常见做法,需要提前把跳板机的公钥发布到各 ESXi 主机,否则脚本跑到一半卡在密码输入上,体验很差。

3.3 脚本里必须守住的四条红线

与其让脚本越写越复杂,不如先把四条红线焊死在设计里。第一条是替换顺序。machine 证书和 solution user 证书不建议分开换:只换 machine 而不换 solution user,vmafd 里记录的组件身份和新的机器证书会对不上,vpxd 在启动时会拿旧身份去建立新 TLS 连接,直接失败。最常见做法是用 certificate-manager 统一替换,一次把 machine 和 solution user 都刷新到同一套信任体系下。

第二条是 SAN 必填。vCenter 7 及以后的版本对证书 SAN 的校验比之前严格得多,Web 服务可以容忍 CN 匹配,但 API 客户端的 TLS 库已经全面切换到 SAN 检查。生成 CSR 时至少要把 vCenter 的 FQDN、短主机名、管理 IP 都写进 SAN,仅填 CN 的证书上线后第二天就会有人来找你。第三条是时间基准统一成 UTC。openssl 输出的 notAfter 是 GMT,而系统 date 输出的是本地时区;脚本里不处理时区,剩余天数会差若干小时,边界情况下造成"昨天看还剩 1 天,今天就过期"的误判,所以我习惯在脚本开头export TZ=UTC。第四条是替换动作必须保留人工回退能力。证书替换类脚本一旦跑挂,vCenter 管理面就失联,再想救人只能走终端或控制台,因此 replace 脚本里每个阶段都要输出可读日志,并保留上一步的备份路径和回滚提示,别为了追求一键全自动把最后的回滚出口也堵死。

4. 证书过期自动替换脚本:check 与 replace 分离的完整 bash 实现

4.1 脚本架构:为什么把 check 和 replace 拆开

处理 VMware 证书过期问题,我强烈不建议把检测和替换塞进同一个脚本。检测脚本要每天跑、每周跑,操作都是只读的,风险为零;替换脚本只能低频跑,而且最好在变更窗口内跑。把两者拆开,check 脚本可以交给 cron 无脑天天执行,replace 脚本则留在变更时手动触发,避免检测脚本误带一个替换动作把环境搞挂。整体流程按"读状态 - 做备份 - 替换 - 重启 - 验证"五步组织。验证这步经常被忽略,替换完不看新证书是否生效,等于白做,所以脚本里我会在最后自动跑一次 openssl s_client 探测,确认远端返回的证书已是新签名。

4.2 检测脚本 check_vmware_cert_expiry.sh

#!/bin/bash # # check_vmware_cert_expiry.sh # 检测 vCenter 本地证书与远端 ESXi 证书的剩余有效期 # 用法: ./check_vmware_cert_expiry.sh [预警阈值天数] [ESXi 主机列表文件] # set -u export TZ=UTC ALERT_DAYS=${1:-60} HOST_FILE=${2:-/root/scripts/esxi_hosts.txt} # vCenter Appliance 上需要关注的本地证书路径 VC_CERTS=( /etc/vmware-vpx/ssl/rui.crt /etc/vmware-vsphere-ui/certificates/ssl/rui.crt ) # 把 openssl 输出的到期时间换算为剩余天数 calc_remain_days() { local enddate="$1" local remain remain=$(( ($(date -d "$enddate" +%s) - $(date +%s)) / 86400 )) echo "$remain" } # 逐个检查本地证书 for cert in "${VC_CERTS[@]}"; do if [[ ! -f "$cert" ]]; then echo "[SKIP] $cert 不存在" continue fi enddate=$(openssl x509 -in "$cert" -noout -enddate 2>/dev/null | cut -d= -f2) [[ -z "$enddate" ]] && { echo "[ERROR] $cert 解析失败"; continue; } remain=$(calc_remain_days "$enddate") if (( remain < ALERT_DAYS )); then echo "[ALERT] $cert 剩余 ${remain} 天,请尽快处理" else echo "[OK] $cert 剩余 ${remain} 天" fi done # 检查远端 ESXi 主机的 443 证书 if [[ -f "$HOST_FILE" ]]; then while read -r host; do [[ -z "$host" ]] && continue enddate=$(echo | openssl s_client -connect "${host}:443" -servername "$host" 2>/dev/null \ | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2) if [[ -z "$enddate" ]]; then echo "[ERROR] ${host} 读取证书失败" continue fi remain=$(calc_remain_days "$enddate") if (( remain < ALERT_DAYS )); then echo "[ALERT] ${host} 剩余 ${remain} 天" else echo "[OK] ${host} 剩余 ${remain} 天" fi done < "$HOST_FILE" fi

脚本的运行逻辑是:先对 vCenter 本地的关键证书逐个读到期时间,再按主机列表逐个探测远端 443 端口证书,两路都不写任何状态、不改任何配置,可以放心放进 cron。参数说明:第一个参数是预警阈值天数,默认 60 天。之所以默认 60 而不是 30,是因为 VMware 证书过期前的一个月内,部分组件会开始对即将过期的证书做严格校验,vpxd 日志里会提前出现告警,把阈值抬到 60 天能给你留出申请新证书和走变更流程的时间。第二个参数是 ESXi 主机列表文件,每行一个 FQDN,脚本对空行做了容忍,列表文件单独放也便于多环境复用。

脚本里有个细节值得单独提:cut -d= -f2取的是 openssl 输出行中等于号后面的内容,也就是形如 "May 20 12:34:56 2026 GMT" 的字符串。GNU date 解析它没有任何问题,但前提是环境里装的是 GNU coreutils,vCenter Appliance 是 Photon OS,默认满足;如果你把脚本放到 BusyBox 的机器上跑,date -d 会解析失败。另一个稳妥做法是openssl x509 -checkend n,它可以判断证书在 n 秒后是否仍有效,比如-checkend 5184000就等价于判断剩余是否小于 60 天,兼容性更好,缺点是不输出精确剩余天数。我自己的做法是检测脚本里两者都用:先 date 解析拿天数,解析失败就退回 checkend 做布尔判断。

4.3 vCenter 侧替换脚本 renew_vcenter_cert.sh

替换脚本是证书过期处理的关键路径。以下脚本对应最常见的场景:vCenter 的 machine 证书快过期,用内置 VMCA 重新签发一张并全链路刷新。如果你的环境要求使用商业 CA 签发的证书,选择菜单时选项不同,但脚本框架可以复用。

#!/bin/bash # # renew_vcenter_cert.sh # 半自动替换 vCenter machine 证书并重启服务 # 用法: ./renew_vcenter_cert.sh # set -euo pipefail export TZ=UTC BACKUP_DIR="/root/cert-backup/$(date +%Y%m%d-%H%M%S)" mkdir -p "$BACKUP_DIR" echo ">>> [1/4] 备份当前证书与 vmafd 配置" cp -a /etc/vmware-vpx/ssl "$BACKUP_DIR/vpx-ssl" cp -a /etc/vmware-vsphere-ui/certificates/ssl "$BACKUP_DIR/vsphere-ui-ssl" cp -a /etc/vmware-vmafd "$BACKUP_DIR/vmafd" echo " 备份路径: $BACKUP_DIR" echo ">>> [2/4] 调用 certificate-manager 刷新 machine 证书" expect <<'EOF' set timeout 600 spawn /usr/lib/vmware-vmca/bin/certificate-manager -c expect { -re {[Oo]ption} { send "1\r" } timeout { puts "未匹配到菜单提示,请人工接管终端" exit 1 } } expect { -re {[Cc]ontinue} { send "y\r" } -re {[Yy]/[Nn]} { send "y\r" } timeout { puts "未匹配到确认提示,请人工接管终端" exit 1 } } expect eof EOF echo ">>> [3/4] 重启 vCenter 全部服务" service-control --stop --all >/dev/null 2>&1 || true sleep 10 service-control --start --all echo ">>> [4/4] 验证新证书是否生效" echo | openssl s_client -connect localhost:443 -servername "$(hostname)" 2>/dev/null \ | openssl x509 -noout -dates echo ">>> 替换完成,备份目录在 $BACKUP_DIR"

在这套脚本里,第 2 步用 expect 自动应答 certificate-manager 的交互菜单。send "1\r" 发送的是"用 VMCA 签发的证书替换 machine SSL certificate"这一项,不同 vCenter 版本的菜单序号会有差异,第一次跑之前一定要先手动执行一次 certificate-manager -c,把你那个版本的实际菜单序号填进去。expect 匹配的正则用的是通用文本 [Oo]ption 和 [Cc]ontinue,如果新版本菜单文案变了,脚本会超时退出并提示人工接管,而不是继续乱发指令。

第 3 步重启服务是整个操作里最重头的地方。service-control --stop --all 会把 vCenter Appliance 上所有 VMware 服务停掉,这个动作会让管理面短暂不可用,属于正常现象。后面跟的 sleep 10 是给服务进程留出落盘清理的时间,直接马上 start 可能在磁盘锁未释放时失败。我自己在 vCenter 7 上遇到过 stop 后立刻 start 导致部分组件没起来的情况,加了 10 秒等待后就稳定了。这里的 --stop --all 在 vCenter 6.5 及以后版本通用,如果版本较老,也可以只重启 vpxd 和 vsphere-client 两个服务,但证书刷新涉及的信任关系是全局的,我建议还是全部重启一次最干净。还有一个必须注意的点:这个操作要求通过 SSH 登录 vCenter Appliance,而不是通过 Web Client,因为 Web Client 本身就在重启范围内,操作到一半连接会断。

4.4 ESXi 侧批量替换脚本 renew_esxi_certs.sh

vCenter 的证书处理完,ESXi 主机侧的证书也要同步刷新,否则 vCenter 加回主机时仍然会因为主机证书不被信任而失败。下面这个脚本用文件直替的方式替换一批 ESXi 的证书。

#!/bin/bash # # renew_esxi_certs.sh # 批量替换 ESXi 主机证书并重启 hostd / vpxa # 用法: ./renew_esxi_certs.sh <新证书.crt> <新私钥.key> [主机列表] # set -euo pipefail CERT_FILE=${1:?请指定新证书文件路径} KEY_FILE=${2:?请指定新私钥文件路径} HOST_FILE=${3:-/root/scripts/esxi_hosts.txt} # 替换前先验证证书文件本身有效 openssl x509 -in "$CERT_FILE" -noout -dates || { echo "证书文件无效"; exit 1; } # 私钥与证书是否匹配,通过 modulus 对比即可确认 CERT_MOD=$(openssl x509 -in "$CERT_FILE" -noout -modulus | openssl md5) KEY_MOD=$(openssl rsa -in "$KEY_FILE" -noout -modulus 2>/dev/null | openssl md5) [[ "$CERT_MOD" == "$KEY_MOD" ]] || { echo "证书与私钥不匹配,退出"; exit 1; } while read -r esx; do [[ -z "$esx" || "$esx" == \#* ]] && continue echo ">>> 处理 $esx" scp -q "$CERT_FILE" "root@${esx}:/etc/vmware/ssl/rui.crt" scp -q "$KEY_FILE" "root@${esx}:/etc/vmware/ssl/rui.key" ssh "root@${esx}" ' chown root:root /etc/vmware/ssl/rui.crt /etc/vmware/ssl/rui.key chmod 644 /etc/vmware/ssl/rui.crt chmod 600 /etc/vmware/ssl/rui.key /etc/init.d/vpxa restart >/dev/null 2>&1 /etc/init.d/hostd restart >/dev/null 2>&1 ' echo " $esx 完成" done < "$HOST_FILE" echo ">>> 全部主机处理完成"

脚本开头的证书指纹匹配是一个容易被忽略但极其实用的检查:由于先算出了证书的 modulus 和私钥的 modulus,两者不一致说明这份证书和密钥根本不是一对。很多证书替换翻车都死在拿错了密钥上,覆盖上去之后主机证书校验不过,vCenter 连接直接失败。替换动作本身是覆盖 rui.crt 和 rui.key,再重启 vpxa 和 hostd。vpxa 是 vCenter 与 ESXi 之间的代理服务,它持有从 vCenter 来的连接状态;hostd 是 ESXi 的管理守护进程,负责对外提供 443 服务。只重启一个的话,另一边的证书上下文还是旧的,表现出来就是"证书明明换了,但登录 ESXi 还是旧证书"。两个都要重启,顺序无所谓,但我建议 vpxa 在前、hostd 在后,这样 vCenter 到主机的通道先断掉重连,避免 hostd 重启瞬间 vpxa 还在向旧上下文写数据。

这里默认你在跳板机上配了到各 ESXi 的 SSH 密钥,scp/ssh 才能免密执行。如果环境里强制要求密码登录,脚本就不能这样直接跑,要包一层 sshpass,或者在每台 ESXi 上先临时打开 SSH 后手动执行。ESXi 的 SSH 服务默认是关的,批量替换前要把这个前置条件确认好,别等脚本跑到一半才发现连不上。

5. 证书替换避坑清单:五条踩出来的血泪经验

5.1 只换了 machine 证书没换 solution user 证书,vpxd 直接起不来

现象:替换 machine SSL 证书后重启相关服务,vpxd 一直处于 stopped 状态,日志里报 SSO 相关的 token 校验失败,登录页能开但提交登录信息后一直转圈。原因:vpxd 本身也是 vmdir 里的一个 solution user,它的身份证书仍然是旧 CA 签发的;machine 证书刷新后,vpxd 尝试用旧 solution user 证书与新信任链握手,对端直接拒绝,STS 到 vpxd 的信任链断裂。解决:不要单独替换 machine 证书。要么用 certificate-manager 的选项把 machine 与 solution user 一起刷新,要么替换完成后立即检查 vmafd 中 solution user 证书状态,发现不匹配就补一次"替换 solution user certificates"。顺序上的规则是:先刷新 solution user,再刷新 machine,最后重启全部服务。

5.2 替换后不重启服务,界面显示的还是旧证书

现象:certificate-manager 执行完毕,提示替换成功,但浏览器访问 vCenter 时看到的证书依然是旧的那个,或者新旧交替出现。原因:vpxd、vsphere-ui 这些服务进程在启动时一次性加载证书并保持长连接,运行时不会重新读取磁盘上的证书文件,替换文件只是改了磁盘,进程内存里还是旧证书。解决:替换后必须执行服务重启。vCenter 上直接service-control --stop --all && service-control --start --all,ESXi 上执行/etc/init.d/hostd restart和/etc/init.d/vpxa restart。如果嫌影响面大,至少重启 vpxd 和 vsphere-client 两个服务,ESXi 侧至少重启 hostd。

5.3 自定义证书没带 SAN,浏览器能访问但 API 客户端全部失败

现象:新证书替换后,用 Chrome 打开 vCenter 只是提示不安全,点继续能进;但用 PowerCLI、curl 调 API 时直接报 certificate verify failed,连 vCenter 的 SDK 客户端也连不上。原因:现代 TLS 客户端默认开启 SAN 校验,证书里没有 subjectAltName 扩展时,客户端不再采用 CN 匹配作为回退。浏览器出于兼容性会容忍,程序不会,vCenter 7 以后对自定义证书的 SAN 检查尤其严格,缺失 SAN 直接被视为非法证书。解决:生成 CSR 时显式写好 SAN,至少要包含 vCenter 的 FQDN、短主机名、管理 IP 三项。确认证书内容时用openssl x509 -in 证书.crt -noout -ext subjectAltName检查 SAN 字段确实存在再执行替换。我自己的习惯是把这个检查写进 replace 脚本的最前面,SAN 缺失直接拒绝执行。

5.4 备份丢了 ACL 权限,回滚后 vpxd 报 permission denied

现象:证书替换后发现问题想回滚,把备份的 rui.crt 和 rui.key 拷回去,结果 vpxd 起不来,日志报 permission denied,ls 一看文件权限变成了 664 或 777。原因:备份时用的是普通 cp,没带 -a 或 -p 参数,文件的属主和权限位丢失。vpxd 启动时对私钥文件有严格的权限检查,600 是底线,多一个 group 权限都会拒绝。解决:备份一律用cp -a,或者用 tar 加--preserve-permissions打包。回滚后如果发现权限不对,手工补救:chown root:root /etc/vmware-vpx/ssl/*、chmod 600 /etc/vmware-vpx/ssl/rui.key、chmod 644 /etc/vmware-vpx/ssl/rui.crt。不要再花时间排查服务配置,绝大多数这类 permission denied 都是权限位问题。

5.5 时区没统一,脚本报还剩 180 天,实际已过期

现象:检测脚本输出某个 ESXi 主机证书剩余 180 天,结果第二天 vCenter 日志开始报该主机证书校验失败,手动查才发现证书当天过期。原因:openssl x509 的 notAfter 输出是 GMT,脚本里 date 用的是本地时区,时间减法直接按字符串解析,导致剩余天数多算了时区偏移对应的误差,在跨越日期边界时被放大成误判。解决:脚本开头export TZ=UTC,让 date 的输出时区与证书时间戳保持一致;比较时统一用date -d "$enddate" +%s转成时间戳再算差,不要直接比较日期字符串。另外把预警阈值从 30 天提到 60 天,给时区、审批、证书申请留出足够缓冲。

6. 进阶:把一次性替换脚本升级成定时巡检与自动告警

证书处理最怕的不是替换本身,而是"不知道它快过期了"。replace 脚本再完善,如果没人记得跑,一样白搭。我的做法是把 check 脚本挂进 cron,每天凌晨跑一次,输出进独立日志,再根据剩余天数决定是否触发告警。

# 追加到 /etc/crontab,每天凌晨 2 点执行证书巡检 0 2 * * * root /root/scripts/check_vmware_cert_expiry.sh 60 /root/scripts/esxi_hosts.txt >> /var/log/vmware-cert-check.log 2>&1

日志文件要单独建,不要跟系统日志混在一起。证书检查是连续性任务,今天剩 61 天、明天剩 60 天,日志会逐日积累,混在别的日志里很难追溯。我还会在 check 脚本开头加一行echo "===== $(date -Iseconds) =====",把每次执行的时间戳打进去,翻日志时能一眼确认 cron 任务确实在跑而不是静默失败。如果想让巡检结果直接触达,可以复用 webhook 思路,在 check 脚本末尾加一段条件发送:只要存在剩余天数小于阈值的条目,就调用通用的 Webhook 地址推送告警。这个地址可以是企微、钉钉或者任意一个 HTTP 收件端,脚本本身不关心具体平台,只要对方接受 JSON 即可。

# check 脚本末尾追加 if (( alert_count > 0 )); then curl -fsS -H "Content-Type: application/json" \ -d "{\"title\":\"vmware-cert-alert\",\"days\":$alert_count}" \ "$WEBHOOK_URL" >/dev/null 2>&1 || true fi

这里的|| true是刻意的:告警只是锦上添花,不能因为 Webhook 不可用就把巡检脚本的退出码变成非零,否则 cron 会认为任务失败,后续轮次可能被监控系统误报。真正的责任人仍然是人,webhook 只是把"明天要换证书"这件事挪到你面前。

还有一个经验是"主动轮换优于被动救护"。我现在对 vCenter 和 ESXi 的证书采取固定轮换节奏:在证书剩余 90 天左右就走一次 replace 脚本,而不是等它过期。VMware 证书过期后的恢复操作虽然可行,但过程涉及服务全部重启、SSO 信任重建,在关键时刻搞一次,代价远超提前换一次。定期轮换也让 replace 脚本始终保持热状态,每次变更都是验证脚本的一次机会,真到紧急时刻就不至于手忙脚乱。上次我处理一套环境凌晨的证书到期告警,当时整个人是懵的:日志里 TLS 报错刷屏,vCenter 登录页转圈,ESXi 主机全部显示已断开。后来按这套脚本流程只用了不到四十分钟就恢复了连接,原因是 check 脚本提前一周已经在日志里标出了三张即将过期的证书,只是当时没及时处理。从那次以后,我再不敢把证书维护拖到告警响起,每周一早上看一遍巡检日志成了固定习惯。这套流程不一定适合所有环境,但方向是对的:先检测、再备份、替换留退路,最后用巡检把问题消灭在发生之前。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询