凌晨两点,手机响了。值班同事语气有点慌:“vCenter打不开了,浏览器刷出来一个503 Service Unavailable。”我第一反应是vpxd服务挂了,让他先把服务拉起来看看。结果他试了三四次,vpxd的状态始终是启动失败,日志里反反复复刷着unexpected status 503 service unavailable: cc switch local proxy failed while...这种行。我又让他翻/var/log/vmware/vpxd/vpxd.log,翻到几十行报错之后,基本能断定不是服务卡死,而是证书过期了——这台VCSA 6.7跑了整整两年多,部署之后就没碰过证书,正好卡在那个时间点上。
这篇文章就是把我处理这个问题的完整过程写出来。从最开始的故障判断、原因分析,到实际动手做STS证书更新、修复SSL信任关系,再到最后的重启验证和一堆坑,适合所有正在维护vCenter 6.7的人参考。哪怕你之前没碰过证书相关操作,照着这个思路走,也能少走一大半弯路。
1. 503报错是怎么发生的:从现象到根因
1.1 你看到的503和背后的日志
vCenter 6.7 的 503 报错几乎可以算这个版本最经典的“老年病”了。表现非常统一:打开https://vcsa地址/ui,浏览器直接给你一个503 Service Unavailable,什么登录框都没有。ssh 到 VCSA 里执行service-control --status,能看到一堆服务处于 not running 状态,或者反复重启。
但如果只是普通的服务崩溃,通常重启一次就能恢复,而且日志也不会指向“local proxy failed”这种关键词。真正让我确定是证书问题的是下面这几条日志:
tail -n 200 /var/log/vmware/vpxd/vpxd.log | grep -i "503\|certificate\|ssl"日志里频繁出现类似unexpected status 503 service unavailable: cc switch local proxy failed while的行。注意这里的“local proxy”不是网络代理,而是vCenter内部各种服务之间的本地转发通道。vpxd要调用STS服务来验证token,调用时发现证书不合法,直接拒绝连接,于是向上抛出了这个不咸不淡的“503”。
很多人在这一步会走弯路,以为要把vpxd卸载重装、或者把整个VCSA重置一遍。没必要。vpxd只是受害者,不是凶手。凶手是它要依赖的STS认证链路,具体来说就是那张已经过期的证书。继续往下查日志,可以看到connection refused或者certificate verify failed这类关键字。
1.2 STS证书过期是“主谋”的原因
先解释一下vCenter 6.7里的证书体系。VCSA内部并不是只有一张证书,而是按功能拆成了几个证书库(store),常见的有:
- MACHINE_SSL_CERT:机器SSL证书,负责vCenter对外Web访问的HTTPS加密。
- SOLUTION_USER_CERTS:解决方案用户证书,里面最核心的就是STS证书。
- TRUSTED_ROOT:受信任的根证书库。
- VPXD_EXTENSION_CERT、VSPHERE_WEBCLIENT_CERT等。
STS服务的全称是Security Token Service,安全令牌服务。它相当于vCenter体系的“发证机关”。用户登录vSphere Client时,流程是:客户端先向STS要一个安全令牌,拿到令牌之后再拿着它去访问vpxd、vSAN health service、vSphere Web Client这些组件。如果STS证书过期了,所有组件都会拒绝接受它签发的令牌,哪怕签发出来也没人认。
而最头疼的是,STS这张证书不是“到期前一天才出问题”,而是有一个提前量。证书过期之后,vpxd和vsphere-client这些内部服务在启动时会校验对方的证书,一旦发现不在有效期范围内,直接拒绝通信。所以你在界面上看不到任何友好提示,就只剩一个大白板503。
1.3 证书为什么会过期:自签名证书的有效期陷阱
vCenter 6.7部署时默认生成的是自签名证书,而不是企业CA签发的证书。自签名证书的有效期是有限的,不同组件不一样,有的两年,有的五年。很多做运维的朋友有个误区,以为“反正用的是自签名,过期了也无所谓,重新生成一张就行”。话是没错,但难点在于:你重新生成一张证书之后,vCenter里其他组件、ESXi主机、外部PSC、vSphere Web Client这些角色的信任关系并不会自动跟着更新。这就引出了本文标题里的另一半——SSL信任修复。
证书过期真正可怕的地方在于它的“连锁反应”。证书过期前,你可能完全无感,因为vCenter不像操作系统那样天天弹窗提醒。等你发现打不开的时候,往往已经不只是STS这一张证书过期,连带着机器证书、vpxd证书、vsphere web client证书全都处于不可信任状态。这种情况下,如果只盯着某一环修,修完依然是个坏的。
2. 动手修复前先做这些:快照、备份、状态确认
2.1 必做事项:快照和证书目录备份
处理证书问题最忌讳的就是“直接开干”。证书这个东西是整个安全体系的骨架,一旦操作到一半失败,可能连SSH登录都会出问题。所以我个人的原则是:能打快照就先打快照,不能打快照至少把证书相关目录完整备份一遍。
在VCSA上打了快照之后,再执行下面的备份命令:
mkdir -p /root/vc-cert-backup cp -rp /etc/vmware-vmafd /root/vc-cert-backup/ cp -rp /etc/vmware-vmca /root/vc-cert-backup/ cp -rp /etc/vmware-vpx /root/vc-cert-backup/ cp -rp /var/lib/vmware/vmafd /root/vc-cert-backup/这些目录分别对应证书管理服务、证书颁发服务、vpxd服务和vmafd运行时的数据目录。有这套备份在手,就算后面把证书库清空了,也有退路可以回滚。
另外提醒一句,别只备份不做校验。备份完之后执行ls -l /root/vc-cert-backup看一眼目录大小是否正常。遇到过有人备份命令执行时报错,但没看输出,直接往下操作,最后回滚的时候发现备份目录是空的,只能干瞪眼。
2.2 一条命令看清证书到底过期没有
在开始修复之前,先确认真的是证书过期,而不是别的诡异问题。VCSA的vmafd服务里自带查询证书的命令,直接用:
/usr/lib/vmware-vmafd/bin/vmafd-cli get-server-cert --server-name localhost | openssl x509 -noout -dates执行后你会看到类似这样的输出:
notBefore=May 24 13:00:57 2022 GMT notAfter=May 24 13:00:57 2024 GMT如果notAfter已经晚于当前时间,那说明机器证书还活着。但注意,这一条只查了vmafd里注册的机器证书,STS证书不在这里。要看STS证书,需要进vecs证书库查:
/usr/lib/vmware-vmafd/bin/vecs-cli store list这个命令会列出VCSA里所有的证书库。然后针对每个关心的库执行:
/usr/lib/vmware-vmafd/bin/vecs-cli entry list --store SOLUTION_USER_CERTS --text | egrep -i "alias|not after"以及:
/usr/lib/vmware-vmafd/bin/vecs-cli entry list --store MACHINE_SSL_CERT --text | egrep -i "alias|not after"我见过很多人的STS证书过期时间比机器证书还早一两个月。原因可能是vCenter在某个版本升级时更新过机器证书,但STS证书没跟着转。所以排查时务必把MACHINE_SSL_CERT、SOLUTION_USER_CERTS、VMCA_ROOT这几个库都过一遍。
如果不想进VCSA,也可以在外部用openssl直接看对外服务端口证书的过期时间。比如看443端口:
echo | openssl s_client -connect <vcsa的IP>:443 2>/dev/null | openssl x509 -noout -dates这就是网上经常有人问“linux查看ssl证书过期时间”怎么操作的标准答案。注意,这个命令看到的是反向代理对外暴露的证书,不一定是vmafd内部持有的那张,但至少能让你快速判断“从外部看,证书是否已过期”。
2.3 判断修复范围:只是STS还是整库都挂了
确认证书过期之后,还要判断修复范围。这里有个简单的分法:
- 如果只有
SOLUTION_USER_CERTS里的STS证书过期,而机器证书还是新的,理论上可以只更新STS证书。 - 如果
MACHINE_SSL_CERT、SOLUTION_USER_CERTS、TRUSTED_ROOT里全部是过期的,那就别纠结单点了,直接走“全量重建”的路线。 - 如果不确定具体坏在哪,按“全量重建”处理,反而更省事。
为什么这么说?因为STS证书和机器证书之间存在绑定关系。内部服务发现机器证书变了,但STS证书还指向旧的指纹,一样会拒绝通信。只修一半,等于白修。所以大多数生产环境,我建议直接重签整条证书链,然后一次性把所有组件的信任关系同步好。这也是下文要讲的主要思路。
3. 核心修复过程:更新STS证书并重建SSL信任
3.1 方案A:通过VAMI图形化重签证书
如果VCSA的管理端口5480还能访问,那恭喜你,最省事的路径摆在眼前。
浏览器打开https://<vcsa的IP>:5480,用admin账号登录。左侧菜单找到“证书”,进入Certificate Management界面。6.7的这里会区分几个页面,包括“机器证书”“解决方案用户证书”“证书颁发机构”“信任的根证书”。
我的做法是:优先在“解决方案用户证书”里找到STS对应的条目,直接选择“更换证书”->“生成新的自签名证书”。如果这一步能成功,等于把STS证书刷新成了新的,理论上503应该立刻缓解。
但实际情况往往不会这么顺利。STS证书已经过期的时候,VAMI这个页面虽然能打开,但执行“更换证书”时很可能报错,或者一直转圈没反应。我遇到过一次,页面直接提示The operation is not allowed in the current state,翻译成人话就是:你让我换证书,但当前系统连认证都过不去,我没法干。
这种情况下不要硬等,直接放弃VAMI,改用命令行方案。另外,就算VAMI能换STS证书,也建议顺手把机器证书一起换掉,避免过段时间机器证书过期再次引发类似问题。
3.2 方案B:命令行重建证书库
命令行修复是真正能兜底的方案。流程比较长,但每一步都是必要动作。建议先退出所有登录vCenter的客户端,然后通过SSH登录VCSA。
第一步,停止所有服务,避免在运行中换证书导致更多一致性错误:
service-control --stop --all这个过程会持续几分钟,别中断。停止完成后,必须再确认一遍服务确实已经停了:
service-control --status看到大面积为not running,再继续下一步。
第二步,清理旧的证书库。这里我不建议用vecs-cli store delete去删整个store,风险太大。更稳妥的是只删除对应entry。先查看每个store里的alias名称:
/usr/lib/vmware-vmafd/bin/vecs-cli entry list --store MACHINE_SSL_CERT --text | egrep -i "alias" /usr/lib/vmware-vmafd/bin/vecs-cli entry list --store SOLUTION_USER_CERTS --text | egrep -i "alias"拿到alias之后,使用entry delete删除过期证书。有些环境里,STORE内部存在系统级保护,直接删除会报错,这时可以绕过vecs-cli,直接备份并重命名底层数据目录。操作前再次确认备份完成:
mv /var/lib/vmware/vmafd/vecs /var/lib/vmware/vmafd/vecs.bak.$(date +%Y%m%d)然后重新创建空目录:
mkdir -p /var/lib/vmware/vmafd/vecs注意,这个动作等同于把整个证书库归零,后面的步骤必须一次性做完,否则服务起不来。
第三步,重新生成VMCA根证书和机器证书。VCSA的证书颁发服务是VMCA,生成根证书用:
/usr/lib/vmware-vmca/bin/certool --selfca --config /etc/vmware-vmca/vmca.cnf然后生成新的机器证书私钥和证书请求:
/usr/lib/vmware-vmca/bin/certool --genkey --privkey /root/vcsa-new.key --pubkey /root/vcsa-new.pub /usr/lib/vmware-vmca/bin/certool --gencert --privkey /root/vcsa-new.key --cert /root/vcsa-new.crt --config /etc/vmware-vmca/vmca.cnf如果vmca.cnf里的字段和你的环境不匹配,生成出来的证书CN名可能不对,之后Web访问会出现域名/IP不匹配的警告。不过对于已过期的自签名证书来说,能恢复系统可用的优先级远高于消除浏览器警告。
第四步,把新生成的证书重新导入到vecs证书库:
/usr/lib/vmware-vmafd/bin/vecs-cli entry create --store MACHINE_SSL_CERT --alias MACHINE_CERT --cert /root/vcsa-new.crt --key /root/vcsa-new.key再把根证书导入TRUSTED_ROOT:
/usr/lib/vmware-vmafd/bin/vecs-cli entry create --store TRUSTED_ROOT --alias VMCA_ROOT --cert /root/vmca_root.crt这里需要说明:不同版本的6.7里,alias名称可能存在细微差异,如果导入时报“alias已存在”,先用entry delete把旧的删除,再重新导入。
第五步,同步STS证书。STS证书的更新不完全是“生成新证书”,而是要把新机器证书的密钥信息同步给STS服务。vmafd提供了dir-cli命令:
/usr/lib/vmware-vmafd/bin/dir-cli service --action update --service sts --cert /root/vcsa-new.crt --key /root/vcsa-new.key这条命令的意思是把STS service的证书绑定关系更新为新的证书和私钥。执行成功之后,可以再从solution user certs库里查看STS证书的过期时间,确认已经变成新证书。
千万不要跳过这一步。很多人在命令行里重新生成了机器证书、也导入了store,但忘了同步STS服务,结果重启之后依然503,还在那纳闷为什么。
3.3 修复SSL信任:让ESXi和其他组件重新承认新证书
证书换完不代表万事大吉,因为vCenter和ESXi主机之间的信任还是旧关系。证书更新后,最典型的现象是vSphere Client能打开,但所有ESXi主机显示“证书已更改”或“主机连接已禁用”,甚至SSH到主机调用vpxa服务时直接报证书校验失败。
处理这个问题的核心思路,是让vCenter和ESXi双方都持有对方的新根证书。
先处理vCenter这一侧。在VAMI的“证书”->“信任的根证书”页面,把每台ESXi当前使用的根证书导入到vCenter的TRUSTED_ROOT证书库里。ESXi的证书路径通常在/etc/vmware/ssl/下,文件名是rui.crt。可以用scp把每台主机的rui.crt拷贝下来,然后通过VAMI逐个导入。
再处理ESXi这一侧。在每台ESXi主机上,将vCenter新的根证书/root/vmca_root.crt导入:
esxcli system settings trustedRoot import -c /tmp/vmca_root.crt导入完成之后,重启ESXi与vCenter之间的agent服务,让证书重新加载:
/etc/init.d/vpxa restart这一步在某些场景下会被省略,但只要你环境里有vSAN或分布式交换机,建议不要省。vSAN集群的成员在vCenter证书变更后,健康检查会长时间报证书错误,只有双向信任重建干净才能消除。
4. 服务重启与修复验证
4.1 正确的服务重启顺序
证书库重建完成、信任关系也处理完之后,最后一步就是重启vCenter服务。千万别只启动vpxd一个服务,要按依赖关系从底层往上拉。
先启动全部服务:
service-control --start --all启动过程比较久,15到30分钟都很正常。期间可以通过下面的命令实时观察状态:
service-control --status或者盯关键日志:
tail -f /var/log/vmware/vpxd/vpxd.log大多数情况下,整套服务会在一个相对固定的顺序里依次起来。如果某个服务长时间卡在starting状态,不要反复重启,先看它依赖的上游服务是不是已经起来。比如vpxd依赖vmafd和vmonapi,vmafd没起来的话,vpxd永远起不来。
4.2 怎么确认这次修复真的成功了
服务全部启动之后,做下面几项验证:
第一,浏览器访问https://<vcsa的IP>/ui,看是否出现正常登录页面。如果依然503,先不要慌,用隐身窗口再试一次。因为旧登录页可能已经在本地缓存了无效的STS响应,普通刷新可能还会命中缓存。
第二,用openssl确认对外证书已经更新:
echo | openssl s_client -connect <vcsa的IP>:443 2>/dev/null | openssl x509 -noout -dates第三,登录vSphere Client之后,进入“主机和集群”,逐个检查ESXi主机是否连接正常。正常情况下,之前因为证书过期而报错的主机,现在应该能正常显示状态,不再提示证书错误。
第四,检查STS服务本身是否正常。可以看看STS服务对应的8443端口的证书:
echo | openssl s_client -connect <vcsa的IP>:8443 2>/dev/null | openssl x509 -noout -dates如果这些验证都能通过,基本可以断定修复完成。
5. 常见问题排查与避坑记录
5.1 常见问题速查表
| 现象 | 可能原因 | 处理办法 |
|---|---|---|
| VAMI 5480能进,但ui 443报503 | STS证书过期 | 先尝试VAMI更换解决方案用户证书,失败则命令行清库重建 |
| 命令执行后证书还是老的 | vecs入库未生效 | 检查alias是否冲突,删除旧alias后重新导入 |
| 重启服务后vpxd反复启动失败 | 机器证书和STS证书不匹配 | 用dir-cli重新同步sts服务的证书绑定 |
| ESXi主机显示“证书已更改” | vCenter和ESXi信任关系断裂 | 双向导入根证书,重启vpxa |
| 网页提示证书不匹配警告 | 新证书CN和访问域名不一致 | 不影响可用性,如需消除需要按企业CA签发流程重新制作 |
| 内部服务时间不同步导致校验失败 | NTP异常 | 先修复NTP时间同步,再重新生成证书 |
5.2 几个踩坑经验
第一个坑:千万别只修STS证书。我第一次遇到这个故障时,觉得“问题定位在STS,那就只更新STS证书”,结果机器证书仍然是旧的,内部服务校验时匹配的还是老指纹,vpxd照样起不来。最后还是回到全量重建证书库这条路。
第二个坑:VAMI证书管理界面的“更换证书”按钮不一定可靠。线上环境里,STS过期时VAMI页面上操作经常超时。所以我的经验是:如果VAMI点一下就能成功,那最好;一旦出现“转圈”超过两分钟,直接放弃图形界面,别再反复点了。反复点反而可能让证书库状态更混乱。
第三个坑:更新完证书之后,浏览器还一直报503。这不是系统没修好,而是本地会话缓存了旧的STS令牌。用隐身窗口登录,或者清一次浏览器缓存,基本能恢复。
第四个坑:不要忘记检查NTP时间。证书校验要求系统时间在有效期内,如果VCSA的时间本身就漂了,哪怕证书是新生成的,也一样校验不过。修复证书前顺手执行ntpq -p看一眼时间同步状态,能省掉很多莫名其妙的问题。
就我个人实际体感来说,vCenter 6.7的证书问题不是偶发,而是这个版本生命周期内必然会遇到的坎。证书过期不像硬件故障那样有预兆,但也不是无迹可寻:提前用openssl做个证书到期时间巡检脚本,每个月跑一次,然后在证书到期前三个月重新签发,是成本最低的维护方式。如果你这次只是紧急恢复,不妨把巡检脚本这件事排上日程,下次就不用半夜爬起来对着503挠头了。