]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mon/MonClient: wipe secrets and invalidate tickets on auth epoch change
authorPatrick Donnelly <pdonnell@ibm.com>
Fri, 9 May 2025 18:56:10 +0000 (14:56 -0400)
committerPatrick Donnelly <pdonnell@ibm.com>
Mon, 13 Oct 2025 23:59:37 +0000 (19:59 -0400)
* 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 <pdonnell@ibm.com>
(cherry picked from commit bca0d66c5e7ac98006b3658b53a9e83faca7c70f)

src/mon/MonClient.cc
src/mon/MonClient.h
src/mon/MonMap.cc

index cc4adda6952f8ca5548732831d402b6b19697b96..84522fb1807d934ec97b3a7aefe578b3ab897023 100644 (file)
@@ -408,6 +408,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);
@@ -445,6 +446,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;
@@ -521,6 +527,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;
 }
@@ -611,6 +621,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,
@@ -634,6 +652,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;
 }
index 803c74eb7f62945a5841aad665846a42e82f8d0f..7bb77fa1903019def939e814994ebc21ba32923d 100644 (file)
@@ -778,6 +778,7 @@ public:
   md_config_t::config_callback get_config_callback();
 
 private:
+  void _wipe_secrets_and_tickets();
 
   std::map<ceph_tid_t, std::unique_ptr<VersionCompletion>> version_requests;
   ceph_tid_t version_req_id;
index f99fff042206de41e5a4c7cba6e042f3e312e697..642aac5140cdbe28ad884701153952fae86a4a3a 100644 (file)
@@ -4,6 +4,7 @@
 #include "MonMap.h"
 
 #include <algorithm>
+#include <limits>
 #include <sstream>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -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<decltype(auth_epoch)>::max();
+
   // mon_host_override?
   if (maybe_init_with_mon_host(conf.get_val<std::string>("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<decltype(auth_epoch)>::max();
+
   // mon_host_override?
   auto mon_host_override = conf.get_val<std::string>("mon_host_override");
   if (!mon_host_override.empty()) {