From e6db4be354b5c1378048a326e9f7a097611ae10c Mon Sep 17 00:00:00 2001 From: Kobi Ginon Date: Mon, 27 Apr 2026 22:08:54 +0300 Subject: [PATCH] mgr/cephadm: replace md5_hash with FIPS-safe config_hash Replace md5_hash() usages in cephadm dependency hashing with an algorithm-agnostic config_hash() helper. config_hash() is backed by SHA-256, making dependency hash generation unconditionally FIPS-safe while preserving change-detection behavior. Fixes: https://tracker.ceph.com/issues/76185 Signed-off-by: Kobi Ginon --- src/pybind/mgr/cephadm/services/cephadmservice.py | 2 +- src/pybind/mgr/cephadm/services/ingress.py | 2 +- src/pybind/mgr/cephadm/services/monitoring.py | 8 ++++---- src/pybind/mgr/cephadm/services/nfs.py | 6 +++--- src/pybind/mgr/cephadm/utils.py | 11 +++++++---- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/pybind/mgr/cephadm/services/cephadmservice.py b/src/pybind/mgr/cephadm/services/cephadmservice.py index 5a25837931d2..fc2c43943fa0 100644 --- a/src/pybind/mgr/cephadm/services/cephadmservice.py +++ b/src/pybind/mgr/cephadm/services/cephadmservice.py @@ -1343,7 +1343,7 @@ class RgwService(CephService): if ssl_cert: if isinstance(ssl_cert, list): ssl_cert = '\n'.join(ssl_cert) - deps.append(f'ssl-cert:{str(utils.md5_hash(ssl_cert))}') + deps.append(f'ssl-cert:{utils.config_hash(ssl_cert)}') return sorted(deps) diff --git a/src/pybind/mgr/cephadm/services/ingress.py b/src/pybind/mgr/cephadm/services/ingress.py index 59288256aa5f..1f044232ccdf 100644 --- a/src/pybind/mgr/cephadm/services/ingress.py +++ b/src/pybind/mgr/cephadm/services/ingress.py @@ -121,7 +121,7 @@ class IngressService(CephService): ssl_cert_key = getattr(ingress_spec, attr, None) if ssl_cert_key: assert isinstance(ssl_cert_key, str) - deps.append(f'ssl-cert-key:{str(utils.md5_hash(ssl_cert_key))}') + deps.append(f'ssl-cert-key:{utils.config_hash(ssl_cert_key)}') backend_spec = mgr.spec_store[ingress_spec.backend_service].spec if backend_spec.service_type == 'nfs': hosts = get_placement_hosts(spec, mgr.cache.get_schedulable_hosts(), mgr.cache.get_draining_hosts()) diff --git a/src/pybind/mgr/cephadm/services/monitoring.py b/src/pybind/mgr/cephadm/services/monitoring.py index afbf9cd0ca0a..438315a4118c 100644 --- a/src/pybind/mgr/cephadm/services/monitoring.py +++ b/src/pybind/mgr/cephadm/services/monitoring.py @@ -113,7 +113,7 @@ class GrafanaService(CephadmService): # in case security is enabled we have to reconfig when prom user/pass changes prometheus_user, prometheus_password = mgr._get_prometheus_credentials() if security_enabled and prometheus_user and prometheus_password: - deps.append(f'cred:{utils.md5_hash(prometheus_user + prometheus_password)}') + deps.append(f'cred:{utils.config_hash(prometheus_user + prometheus_password)}') # adding a dependency for mgmt-gateway because the usage of url_prefix relies on its presence. # another dependency is added for oauth-proxy as Grafana login is delegated to this service when enabled. @@ -307,7 +307,7 @@ class AlertmanagerService(CephadmService): if security_enabled: alertmanager_user, alertmanager_password = mgr._get_alertmanager_credentials() if alertmanager_user and alertmanager_password: - alertmgr_cred_hash = f'cred:{utils.md5_hash(alertmanager_user + alertmanager_password)}' + alertmgr_cred_hash = f'cred:{utils.config_hash(alertmanager_user + alertmanager_password)}' deps.append(alertmgr_cred_hash) if not mgmt_gw_enabled: @@ -667,9 +667,9 @@ class PrometheusService(CephadmService): alertmanager_user, alertmanager_password = mgr._get_alertmanager_credentials() prometheus_user, prometheus_password = mgr._get_prometheus_credentials() if prometheus_user and prometheus_password: - deps.append(f'prom-cred:{utils.md5_hash(prometheus_user + prometheus_password)}') + deps.append(f'prom-cred:{utils.config_hash(prometheus_user + prometheus_password)}') if alertmanager_user and alertmanager_password: - deps.append(f'alert-cred:{utils.md5_hash(alertmanager_user + alertmanager_password)}') + deps.append(f'alert-cred:{utils.config_hash(alertmanager_user + alertmanager_password)}') # Adding other services as deps (with corresponding justification): # mgmt-gateway : url_prefix depends on the existence of mgmt-gateway diff --git a/src/pybind/mgr/cephadm/services/nfs.py b/src/pybind/mgr/cephadm/services/nfs.py index ffc4fff849b1..36e1b5452b1d 100644 --- a/src/pybind/mgr/cephadm/services/nfs.py +++ b/src/pybind/mgr/cephadm/services/nfs.py @@ -132,9 +132,9 @@ class NFSService(CephService): nfs_spec = cast(NFSServiceSpec, spec) # add dependency of tls fields if (spec.ssl and spec.ssl_cert and spec.ssl_key and spec.ssl_ca_cert): - deps.append(f'ssl_cert: {str(utils.md5_hash(spec.ssl_cert))}') - deps.append(f'ssl_key: {str(utils.md5_hash(spec.ssl_key))}') - deps.append(f'ssl_ca_cert: {str(utils.md5_hash(spec.ssl_ca_cert))}') + deps.append(f'ssl_cert: {utils.config_hash(spec.ssl_cert)}') + deps.append(f'ssl_key: {utils.config_hash(spec.ssl_key)}') + deps.append(f'ssl_ca_cert: {utils.config_hash(spec.ssl_ca_cert)}') deps.append(f'tls_ktls: {nfs_spec.tls_ktls}') deps.append(f'tls_debug: {nfs_spec.tls_debug}') deps.append(f'tls_min_version: {nfs_spec.tls_min_version}') diff --git a/src/pybind/mgr/cephadm/utils.py b/src/pybind/mgr/cephadm/utils.py index b59b94e17ead..8221b950af41 100644 --- a/src/pybind/mgr/cephadm/utils.py +++ b/src/pybind/mgr/cephadm/utils.py @@ -187,10 +187,13 @@ def file_mode_to_str(mode: int) -> str: return r -def md5_hash(input_value: str) -> str: - input_str = str(input_value).encode('utf-8') - hash_object = hashlib.md5(input_str) - return hash_object.hexdigest() +def config_hash(input_value: str) -> str: + """ + Short stable digest for config/dependency change detection. + Uses SHA-256 so this works on FIPS-enabled systems (MD5 may be blocked). + """ + input_str = input_value.encode('utf-8') + return hashlib.sha256(input_str).hexdigest()[:8] def get_node_proxy_status_value(data: Any, key: str, lower: bool = False) -> str: -- 2.47.3