From 75915fcd1d9a8925a80c488a6566ad58dca1f74a Mon Sep 17 00:00:00 2001 From: Patrick Donnelly Date: Mon, 23 Jun 2025 23:27:31 -0400 Subject: [PATCH] mon: provide emergency mechanism to rescue allowed_ciphers If the administrator accidentally revokes auth to client.admin, they cannot fix it because the setting is stored in the monmap. Provide a config to restore access in such an emergency. Signed-off-by: Patrick Donnelly (cherry picked from commit 5f125fba84bc863d5b7a6e6b1cdb28969a1d40d7) --- src/common/options/mon.yaml.in | 9 +++++++++ src/mon/AuthMonitor.cc | 4 ++++ src/mon/Monitor.cc | 29 +++++++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/common/options/mon.yaml.in b/src/common/options/mon.yaml.in index e72c9ce01bd..9d6e2a1db3b 100644 --- a/src/common/options/mon.yaml.in +++ b/src/common/options/mon.yaml.in @@ -817,6 +817,15 @@ options: - mon flags: - runtime +- name: mon_auth_emergency_allowed_ciphers + type: str + level: advanced + desc: set allowed ciphers to override mon map configuration + services: + - mon + flags: + - startup + - no_mon_update - name: mon_auth_validate_all_caps type: bool level: advanced diff --git a/src/mon/AuthMonitor.cc b/src/mon/AuthMonitor.cc index 8a8c484f7f6..f9a8030a66d 100644 --- a/src/mon/AuthMonitor.cc +++ b/src/mon/AuthMonitor.cc @@ -509,6 +509,10 @@ bool AuthMonitor::check_health() next.add("AUTH_INSECURE_KEYS_CREATABLE", HEALTH_WARN, "Monitors are configured to allow creation of insecure key types", 1); } + if (auto c = cct->_conf.get_val("mon_auth_emergency_allowed_ciphers"); !c.empty()) { + next.add("AUTH_EMERGENCY_CIPHERS_SET", HEALTH_WARN, "Monitors are configured to use emergency allowed ciphers", 1); + } + { auto service_key_type = mon.monmap->auth_service_cipher; if (!secure_key_types.contains(service_key_type)) { diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index 91465307165..fd8a36544ca 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -953,6 +953,23 @@ int Monitor::init() dout(2) << "init" << dendl; std::lock_guard l(lock); + auto emergency_ciphers = cct->_conf.get_val("mon_auth_emergency_allowed_ciphers"); + if (!emergency_ciphers.empty()) { + std::vector v; + std::vector ciphers; + get_str_vec(emergency_ciphers, ", ", v); + for (auto& cipher : v) { + int c = CryptoManager::get_key_type(cipher); + if (c < 0) { + lderr(cct) << "init: invalid cipher: " << cipher << dendl; + continue; + } + ciphers.push_back(c); + } + std::lock_guard lock{cipher_mutex}; + my_allowed_ciphers = std::move(ciphers); + } + finisher.start(); // start ticker @@ -6801,8 +6818,16 @@ void Monitor::notify_new_monmap(bool can_change_external_state, bool remove_rank std::lock_guard lock{cipher_mutex}; my_service_cipher = monmap->auth_service_cipher; dout(20) << __func__ << ": my_service_cipher now " << my_service_cipher << dendl; - my_allowed_ciphers = monmap->auth_allowed_ciphers; - dout(20) << __func__ << ": auth_allowed_ciphers now " << my_allowed_ciphers << dendl; + auto emergency_ciphers = cct->_conf.get_val("mon_auth_emergency_allowed_ciphers"); + if (emergency_ciphers.empty()) { + my_allowed_ciphers = monmap->auth_allowed_ciphers; + dout(20) << __func__ << ": auth_allowed_ciphers now " << my_allowed_ciphers << dendl; + } else { + dout(20) << __func__ + << ": mon_auth_emergency_allowed_ciphers (" << my_allowed_ciphers + << ") overrides MonMap::auth_allowed_ciphers (" << monmap->auth_allowed_ciphers << ")" + << dendl; + } } } -- 2.39.5