哈喽大家好,欢迎来到虚拟化时代君(XNHCYL),收不到通知请将我点击星标!“ 大家好,我是虚拟化时代君,一位潜心于互联网的技术宅男。这里每天为你分享各种你感兴趣的技术、教程、软件、资源、福利…(每天更新不间断,福利不见不散)
文 章 引 言
新年新气象,大家元旦快乐!开启打螺丝模式,继续技术文章的分享。
今天在给客户升级VMware vCenter时候遇到了奇怪的问题,客户环境是VCSA 7.x 升级到 8.x。记录下解决的过程和思路。
故障现象描述
在将 VCSA 7.x 升级到 8.x 的升级中,显示不信任一个或多个 URL,就像证书已过期一样。
这个错误其实很少见,小编这么多年遇到也是寥寥无几。但是还好有VMware的KB库有相关案例:
-
https://knowledge.broadcom.com/external/article?legacyId=93526
eam-utility.py脚本
脚本内容,脚本是从官方KB中获取,可自行下载!下载完成之后通过SSH上传到vCenter中。
#!/usr/bin/python -B
#########################################################################
# Copyright 2023 VMware, Inc. All rights reserved. VMware Confidential
#########################################################################
# NOTE: on linux/photon machines execute this file directly
# ----- on windows distribution execute with ""%VMWARE_PYTHON_BIN%" -B%" prefix
from argparse import ArgumentParser
from contextlib import closing
from datetime import datetime, timedelta, tzinfo
try:
inFnc = raw_input
except:
inFnc = input
from json import load, dump
from logging import DEBUG, Formatter, Logger, StreamHandler
from os import chmod, environ
from os.path import exists, join
from stat import S_IREAD, S_IWRITE, S_IRUSR, S_IWUSR, S_IRGRP, S_IROTH
from socket import create_connection
from ssl import CERT_NONE, create_default_context, DER_cert_to_PEM_cert, Purpose
from sys import platform, stdout
try:
from urllib.parse import urlparse
except:
from urlparse import urlparse
_IS_WINDOWS = platform.lower().startswith('win')
_VMWARE_CFG_ENV = 'VMWARE_CFG_DIR'
_TRUST_FILE = (
join(environ.get(_VMWARE_CFG_ENV), 'vmware-eam', 'depot-trust.json')
if _IS_WINDOWS else
'/etc/vmware-eam/depot-trust.json'
)
_INSTALL_TEXT = (
'pins an URL\'s leaf certificate in ESX Agent Manager trust store'
)
_UNINSTALL_TEXT = (
'unpins any known certificate for an URL from ESX Agent Manager\'s' +
' trust store'
)
_DISABLE_TEXT = (
'allows, ESX Agent Manager, access to an URL without establishing' +
' trust'
)
_ENABLE_TEXT = (
'removes permission to access an URL without establishing trust' +
' from ESX Agent Manager'
)
_CLEAR_TEXT = 'clears configured ESX Agent Manager trust store'
_DISABLED_MARKER = 'AnyCertificate'
_CANT_MOD_TEXT = 'Unable to read or modify ESX Agent Manager trust at %s'
_LOG_FORMAT = '%(asctime)s %(message)s'
_DATE_FORMAT = '%Y-%m-%d %H:%M:%S %z'
_TRUST_PERMISSIONS = (
S_IREAD | S_IWRITE | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
)
# In seconds
_CERT_GET_TIMEOUT = 10
def main(args):
return args.operationFnc(_createTimeZoneLogger(), args)
def _installCert(log, args):
rc = 0
url = args.url
if _needsTrust(url):
try:
parts = urlparse(url)
except:
log.warning('Couldn\'t parse the provided URL %s', url, exc_info=True)
rc = 1
if rc == 0:
context = create_default_context(purpose=Purpose.SERVER_AUTH)
# NOTE: Disable hostname verification to be able to access
# ----- misnamed certificates.
context.check_hostname = False
# NOTE: Disable certificate verification to be able to access
# ----- any kind of certificate on the server.
context.verify_mode = CERT_NONE
pem_certificate = None
try:
with closing(
create_connection(
(parts.hostname, 443 if parts.port is None else parts.port),
timeout=_CERT_GET_TIMEOUT
)
) as sock:
with closing(
context.wrap_socket(
sock,
server_hostname=parts.hostname,
do_handshake_on_connect=True
)
) as ssock:
certificate_binary = ssock.getpeercert(binary_form=True)
x509Cert = DER_cert_to_PEM_cert(certificate_binary)
except:
self._log.warning(
'Unable to obtain the certificate from {}'.format(url),
exc_info=True
)
rc = 1
if rc == 0 and not args.y:
log.info(
'PEM encoding of certificate behind URL "%s":\n%s',
url,
x509Cert
)
answer = inFnc(
'Do you want associate(pin) this certificate to this URL as trust'
'(enter "y" to confirm): '
)
if not answer.lower() == 'y':
log.info('User did not agree, stopping the operation')
rc = 1
if rc == 0:
try:
trust = _readTrust(log, args)
trust = {} if trust is None else trust
trust[url] = x509Cert
_storeTrust(log, args, trust)
except:
log.warning(_CANT_MOD_TEXT, args.trust_file, exc_info=True)
rc = 1
else:
log.info(
'URL "%s" doesn\'t require trust to access. Ignoring command',
args.url
)
return rc;
def _uninstallCert(log, args):
rc = 0
url = args.url
try:
trust = _readTrust(log, args)
trust = {} if trust is None else trust
if url in trust and not trust[url] == _DISABLED_MARKER:
log.info('Removing certificate pinning for URL %s trust', url)
del trust[url]
_storeTrust(log, args, trust)
else:
log.info(
(
'URL "%s" doesn\'t have a pinned trust certificate.'
' Ignoring command'
),
url
)
except:
log.warning(_CANT_MOD_TEXT, args.trust_file, exc_info=True)
rc = 1
return rc
def _disableTrust(log, args):
rc = 0
url = args.url
if _needsTrust(url):
try:
trust = _readTrust(log, args)
trust = {} if trust is None else trust
if url in trust and trust[url] == _DISABLED_MARKER:
log.info(
'URL "%s" already with disabled trust. Ignoring command',
url
)
else:
log.info('Allowing URL "%s" access without establishing trust', url)
trust[url] = _DISABLED_MARKER
_storeTrust(log, args, trust)
except:
log.warning(_CANT_MOD_TEXT, args.trust_file, exc_info=True)
rc = 1
else:
log.info(
'URL "%s" doesn\'t require trust to access. Ignoring command',
url
)
return rc;
def _enableTrust(log, args):
rc = 0
url = args.url
try:
trust = _readTrust(log, args)
trust = {} if trust is None else trust
if url in trust and trust[url] == _DISABLED_MARKER:
log.info(
'Removing permission to access URL %s without establishing trust',
url
)
del trust[url]
_storeTrust(log, args, trust)
else:
log.info('URL "%s" is not with disabled trust. Ignoring command', url)
except:
log.warning(_CANT_MOD_TEXT, args.trust_file, exc_info=True)
rc = 1
return rc
def _clearTrust(log, args):
rc = 0
if exists(args.trust_file):
log.info('Clearing ESX Agent Manager trust.')
try:
_storeTrust(log, args, {})
except:
log.warning(_CANT_MOD_TEXT, args.trust_file, exc_info=True)
rc = 1
else:
log.info(
'ESX Agent Manager trust not found at %s. Ignoring command',
args.trust_file
)
return rc;
def arguments():
parser = ArgumentParser(
prog='eam-utility',
description='Modifies ESX Agent Manager configuration/state'
)
subParsers = parser.add_subparsers(
title='operations',
dest='operation',
help='operations to modify EAM\'s configuration/state'
)
# NOTE: not in the above method to allow work with python 2
subParsers.required=True
addCertParser = subParsers.add_parser(
'install-cert',
description=_INSTALL_TEXT,
help=_INSTALL_TEXT
)
addCertParser.add_argument(
'url',
help=(
'URL to have its certificate pinned to ESX Agent Manager\'s' +
' trust store'
)
)
_addTrustFileArgument(addCertParser)
addCertParser.add_argument(
'-y',
action='store_true',
help='accept any certificate behind the URL without confirmation'
)
addCertParser.set_defaults(operationFnc=_installCert)
removeCertParser = subParsers.add_parser(
'uninstall-cert',
description=_UNINSTALL_TEXT,
help=_UNINSTALL_TEXT
)
removeCertParser.add_argument(
'url',
help=(
'URL to have its certificate unpinned from ESX Agent Manager\'s' +
' trust store'
)
)
_addTrustFileArgument(removeCertParser)
removeCertParser.set_defaults(operationFnc=_uninstallCert)
disableTrustParser = subParsers.add_parser(
'disable-trust',
description=_DISABLE_TEXT,
help=_DISABLE_TEXT
)
disableTrustParser.add_argument(
'url',
help=(
'URL to be accessible by ESX Agent Manager without establishing trust'
)
)
_addTrustFileArgument(disableTrustParser)
disableTrustParser.set_defaults(operationFnc=_disableTrust)
enableTrustParser = subParsers.add_parser(
'enable-trust',
description=_ENABLE_TEXT,
help=_ENABLE_TEXT
)
enableTrustParser.add_argument(
'url',
help=(
'URL to no-longer be accessible by ESX Agent Manger without' +
' establishing trust'
)
)
_addTrustFileArgument(enableTrustParser)
enableTrustParser.set_defaults(operationFnc=_enableTrust)
clearTrustParser = subParsers.add_parser(
'clear-trust',
description=_CLEAR_TEXT,
help=_CLEAR_TEXT
)
_addTrustFileArgument(clearTrustParser)
clearTrustParser.set_defaults(operationFnc=_clearTrust)
return parser.parse_args()
def _addTrustFileArgument(parser):
parser.add_argument(
'--trust-file',
metavar='file',
default=_TRUST_FILE,
help=(
'Path to file containing ESX Agent Manager\'s trust store' +
' (default: %(default)s)'
)
)
def _needsTrust(url):
return url is not None and url.lower().startswith('https://')
def _readTrust(log, args):
if exists(args.trust_file):
log.info('Loading ESX Agent Manager trust from %s', args.trust_file)
with open(args.trust_file, 'r') as fin:
trust = load(fin)
else:
log.info(
'ESX Agent Manager trust doesn\'t exist at %s, using empty trust',
args.trust_file
)
trust = None
return trust
def _storeTrust(log, args, trust):
log.info('Storing ESX Agent Manager trust to %s', args.trust_file)
with open(args.trust_file, 'w') as fout:
dump(trust, fout, indent=3)
chmod(args.trust_file, _TRUST_PERMISSIONS)
def _createTimeZoneLogger():
logger = Logger('main', DEBUG)
handler = StreamHandler(stdout)
handler.setFormatter(_TimeZonedFormatter(_LOG_FORMAT, _DATE_FORMAT))
logger.addHandler(handler)
return logger
class _TimeZonedFormatter(Formatter):
def formatTime(self, record, datefmt=None):
timeZone = _TimeZone(
int((datetime.now() - datetime.utcnow()).total_seconds())
)
tzTime = datetime.fromtimestamp(record.created, timeZone)
return tzTime.strftime(datefmt if datefmt is not None else _DATE_FORMAT)
class _TimeZone(tzinfo):
def __init__(self, seconds):
# the timezone doesn't work with fractional minutes
fraction = seconds % 60
secondsFixed = (
(seconds - fraction) if fraction < 30
else (seconds + 60 - fraction)
)
self._td = timedelta(seconds=secondsFixed)
def utcoffset(self, dt):
return self._td
def tzname(self, dt):
return 'Custom'
def dst(self, dt):
return timedelta(0)
if __name__ == '__main__':
exit(main(arguments()))
或者,我不想直接将文件下载到我的 VCSA。我也不想禁用 shell 模式来通过 SSH 上传它,所以我最终用 vi 创建了一个名为 eam-utility.py 的文件,并且复制了内容。然后,给予脚本权限便于执行:
chmod +x eam-utility.py
解决过程
1、下面的几种方法都可以作为解决的方法,执行之后需要注意重启VC然后升级。
-
方法1:设置特定 VIB 或 OVF URL 将信任的 SSL 证书。
-
方法2:禁用特定 VIB 或 OVF URL 的 SSL 证书验证。
-
方法3:更改文件服务器的 SSL 证书。
-
方法4:将受信任的根 CA 证书添加到 VECS。
备注:以上方法具体使用参照:https://knowledge.broadcom.com/external/article?legacyId=93526 方法解决
2、我们的环境我使用方法2,因为老的Veeam环境遗留一些老的VIB文件,只需执行以下操作即可:
/eam-utility.py disable-trust https://veeam-vbr.xnhsdj.local:33034/dapi/bundle/7.0 中。0/11.1.94
3、这将向我们展示类似于此输出的内容:
2024-12-31 10:43:29 +0000 /etc/vmware-eam/depot-trust.json 上不存在 ESX Agent Manager 信任,使用空信任
2024-12-31 10:43:29 +0000 允许 URL“https://veeam-vbr.xnhsdj.local:33034/dapi/bundle/7.0.0/11.1.94”访问而不建立信任
2024-12-31 10:43:29 +0000 将 ESX Agent Manager 信任存储到 /etc/vmware-eam/depot-trust.json
4、不要重复此操作,例如,在我的情况下,再重复一个:
./eam-utility.py disable-trust https://vbrv11.jorgedelacruz.es:33034/dapi/bundle 2023-11-27 10:43:52 +0000 Loading ESX Agent Manager trust from /etc/vmware-eam/depot-trust.json 2023-11-27 10:43:52 +0000 Allowing URL "https://vbrv11.jorgedelacruz.es:33034/dapi/bundle" access without establishing trust 2023-11-27 10:43:52 +0000 Storing ESX Agent Manager trust to /etc/vmware-eam/depot-trust.json
./eam-utility.py disable-trust https://vbrv11.xnhsdj.local:33034/dapi/bundle
2024-12-31 10:43:52 +0000 从 /etc/vmware-eam/depot-trust.json 加载 ESX Agent Manager 信任
2024-12-31 10:43:52 +0000 允许 URL“https://vbrv11.xnhsdj.local:33034/dapi/bundle”访问而不建立信任
2024-12-31 10:43:52 +0000 将 ESX Agent Manager 信任存储到 /etc/vmware-eam/depot-trust.json
5、接着我们可以再次转到我们的 VCSA,单击重试,该过程将继续进行。
【以上内容均属虚拟化时代君整理,大家仅供参考!】
往期回顾
点击下方链接阅读精彩文章
涨薪技能、VMware ESXi 上使用 esxcli 进行 DNS 的配置
兄弟们又来云桌面项目了,升级客户Dell R730xd带外IDRAC和BIOS到最新版本故障汇总
业务宕机了吗?VMware vCenter 7.0升级到vCenter8.0卡住39%处理技巧
客户又请一顿火锅,扩容VMware vCenter磁盘13 Archive容量,真的是硬给元子
周末时间又被客户占用,给VMware vCenter Seat磁盘8进行故障排除,客户发了一个红包
VMware运维装逼利器、VMware PowerCLI 自动化管理vSphere环境
免费技术爽文、命令一键备份还原VMware ESXi主机配置文件
VMware vSphere中vApp的功能你真的了解吗?保姆式免费教你vApp的妙处
如何将虚拟机从 VirtualBox 转换为 VMware(Fusion 或 ESXi)
VMware ESXi USB直通技术全解析:如何将物理USB设备直通给虚拟机
超详细通过命令行升级VMware ESXi 7到ESXi 8教程攻略
Dell R730xd安装VMware ESXi 8.0u3d攻略教程
一个小小培训,500大洋外快就到手!VMware vSphere 8内容库你学会了吗?
黑客大佬都在用,VMware ESXi 从Shell启停虚拟机命令
你真的了解VMware三种磁盘配置吗!精简置备 vs 后置备到底选哪个?
博通收购VMware后,新旧VMware兼容性列表查询方案对比
白嫖技巧、VMware vSphere使用mod模式删除无法访问的数据存储
白嫖VMware ESXi 8.0 U3新功能Live Patch、无需重启零中断修复漏洞
VMware安全从我做起,vCenter和Esxi端口加固建议方案
又被客户白嫖一个脚本,VMware vCenter通过Pwershell全自动克隆虚拟机
VMware vCenter(VCSA) 8.0 中的 17 个vmdk有什么用途?给客户介绍用途含泪血赚200!
资源申明:小编更新资源文章只是为了给大家提供一个绿色学习的平台,如果你在本站看到的任何图片文字有涉及到你的利益以及版权都可以联系小编删除。联系微信:XNHSDJ