From 05bd66d6c136e0131c1906204a70ccc445880b0a Mon Sep 17 00:00:00 2001 From: Patrick Donnelly Date: Fri, 9 May 2025 14:56:10 -0400 Subject: [PATCH] mon/MonClient: wipe secrets and invalidate tickets on auth epoch change * This causes service daemons to drop all known service tickets and request new ones from the auth server. * This causes the clients (and service daemons) to request new tickets from the auth server which will include tickets signed with the new service keys. Signed-off-by: Patrick Donnelly (cherry picked from commit bca0d66c5e7ac98006b3658b53a9e83faca7c70f) --- src/mon/MonClient.cc | 22 ++++++++++++++++++++++ src/mon/MonClient.h | 1 + src/mon/MonMap.cc | 7 +++++++ 3 files changed, 30 insertions(+) diff --git a/src/mon/MonClient.cc b/src/mon/MonClient.cc index 041a1192bb3..0ee230f9b7c 100644 --- a/src/mon/MonClient.cc +++ b/src/mon/MonClient.cc @@ -409,6 +409,7 @@ void MonClient::handle_monmap(MMonMap *m) auto con_addrs = m->get_source_addrs(); string old_name = monmap.get_name(con_addrs); const auto old_epoch = monmap.get_epoch(); + const auto old_auth_epoch = monmap.auth_epoch; auto p = m->monmapbl.cbegin(); decode(monmap, p); @@ -446,6 +447,11 @@ void MonClient::handle_monmap(MMonMap *m) cct->set_mon_addrs(monmap); + if (old_auth_epoch < monmap.auth_epoch) { + ldout(cct, 1) << "auth epoch has changed: invalidating tickets and rotating secrets" << dendl; + _wipe_secrets_and_tickets(); + } + sub.got("monmap", monmap.get_epoch()); map_cond.notify_all(); want_monmap = false; @@ -522,6 +528,10 @@ int MonClient::init() "rotate-key", this, "rotate live authentication key"); + cct->get_admin_socket()->register_command( + "wipe-rotating-secrets", + this, + "wipe rotating secrets"); return 0; } @@ -613,6 +623,14 @@ int MonClient::authenticate(double timeout) return authenticate_err; } +void MonClient::_wipe_secrets_and_tickets() +{ + ldout(cct, 5) << " wiping rotating secrets and invalidating tickets" << dendl; + rotating_secrets->wipe(); + auth->invalidate_all_tickets(); + _check_auth_tickets(); +} + int MonClient::call( std::string_view command, const cmdmap_t& cmdmap, @@ -636,6 +654,10 @@ int MonClient::call( errss << "cephx not enabled; no key to rotate"; return -EINVAL; } + } else if (command == "wipe-rotating-secrets") { + ldout(cct, 1) << __func__ << ": " << command << dendl; + std::lock_guard l{monc_lock}; + _wipe_secrets_and_tickets(); } return 0; } diff --git a/src/mon/MonClient.h b/src/mon/MonClient.h index 2beee15edae..ece08ccea11 100644 --- a/src/mon/MonClient.h +++ b/src/mon/MonClient.h @@ -809,6 +809,7 @@ public: md_config_t::config_callback get_config_callback(); private: + void _wipe_secrets_and_tickets(); std::map version_requests; ceph_tid_t version_req_id; diff --git a/src/mon/MonMap.cc b/src/mon/MonMap.cc index 7bbfaf53d83..e5cd4e54cde 100644 --- a/src/mon/MonMap.cc +++ b/src/mon/MonMap.cc @@ -4,6 +4,7 @@ #include "MonMap.h" #include +#include #include #include #include @@ -886,6 +887,9 @@ seastar::future<> MonMap::build_monmap(const crimson::common::ConfigProxy& conf, seastar::future<> MonMap::build_initial(const crimson::common::ConfigProxy& conf, bool for_mkfs) { + /* an invalid epoch so the real monmap doesn't trigger rotation */ + auth_epoch = std::numeric_limits::max(); + // mon_host_override? if (maybe_init_with_mon_host(conf.get_val("mon_host_override"), for_mkfs)) { @@ -967,6 +971,9 @@ int MonMap::build_initial(CephContext *cct, bool for_mkfs, ostream& errout) lgeneric_dout(cct, 1) << __func__ << " for_mkfs: " << for_mkfs << dendl; const auto& conf = cct->_conf; + /* an invalid epoch so the real monmap doesn't trigger rotation */ + auth_epoch = std::numeric_limits::max(); + // mon_host_override? auto mon_host_override = conf.get_val("mon_host_override"); if (!mon_host_override.empty()) { -- 2.39.5