]> 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>
Wed, 1 Oct 2025 18:47:00 +0000 (14:47 -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>
src/mon/MonClient.cc
src/mon/MonClient.h
src/mon/MonMap.cc

index cfbbfd7ab736ee5b8f2d1923067780905e8eb284..3c1b7c333e643995520c384c8c99a001e1c1cc47 100644 (file)
@@ -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;
 }
index 2beee15edae9efca25ea5c394e805928025e73ca..ece08ccea1173bebe03d6258d063d14204ed9b2d 100644 (file)
@@ -809,6 +809,7 @@ public:
   md_config_t::config_callback get_config_callback();
 
 private:
+  void _wipe_secrets_and_tickets();
 
   std::map<ceph_tid_t, VersionCompletion> version_requests;
   ceph_tid_t version_req_id;
index 30b33bd2d7d940b33f816210e40ee64a98ce9a3a..fda08f59d5452be7365b269560b1570e49ff6d13 100644 (file)
@@ -4,6 +4,7 @@
 #include "MonMap.h"
 
 #include <algorithm>
+#include <limits>
 #include <sstream>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -890,6 +891,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)) {
@@ -971,6 +975,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()) {