Proxmox : Migrer les clés CephX aes vers aes256k sur Ceph Squid 19.2.6

Après la mise à jour d’un cluster Ceph vers Squid 19.2.6, de nouvelles alertes peuvent apparaître dans ceph health detail, notamment :

AUTH_INSECURE_CLIENT_KEY_TYPE
AUTH_INSECURE_SERVICE_KEY_TYPE
AUTH_INSECURE_KEYS_ALLOWED
AUTH_INSECURE_KEYS_CREATABLE
AUTH_INSECURE_SERVICE_TICKETS
AUTH_INSECURE_ROTATING_SERVICE_KEY_TYPE

Ces alertes ne signifient pas nécessairement que le cluster est en panne. Elles indiquent que certaines clés CephX utilisent encore l’ancien type aes. Mais dans mon cas, la HA n’était plus opérationnelle et je ne pouvais plus migrer les VM malgrès quelles étaient toujours opérationelles.

Point de vue hyperviseur, le cluster continuait à fonctionner normalement, mais il conservait les anciennes clés CephX en aes. Il a donc fallu migrer progressivement les clés vers aes256k, puis désactiver complètement aes.

L’objectif de cet article est de documenter une migration réalisée sur un cluster Proxmox VE / Ceph de production, avec une méthode progressive destinée à limiter les risques.

Contexte : CVE-2025-30156

L’ancien type de clé CephX aes repose sur AES-128-CBC sans authentification de message HMAC, avec un vecteur d’initialisation fixe. Cette construction permet notamment certaines manipulations du ciphertext sans détection d’altération.

Ce problème est référencé sous CVE-2025-30156. Ceph a corrigé cette vulnérabilité dans les versions récentes, notamment Ceph Squid 19.2.6.

Le nouveau type de clé recommandé est :

aes256k

Il repose sur AES256-CTS-HMAC-SHA384-192, conformément à RFC 8009, et apporte l’authentification nécessaire pour empêcher les manipulations exploitées avec l’ancienne construction.

Point important : la mise à jour de Ceph ne convertit pas automatiquement les anciennes clés existantes. Les anciennes clés sont conservées afin d’éviter une rupture brutale des services. C’est précisément pour cette raison que les alertes AUTH_INSECURE_* apparaissent après la mise à jour.

Environnement utilisé

La migration décrite ici a été réalisée sur un cluster de trois nœuds :

  • pve01
  • pve02
  • pve03

Avec :

  • Proxmox VE 9.2.4
  • Ceph Squid 19.2.6
  • 3 MON
  • 3 MGR
  • 30 OSD
  • 2 pools
  • 129 PG
  • Environ 4,4 TiB de données

CephX était déjà activé :

auth_client_required = cephx
auth_cluster_required = cephx
auth_service_required = cephx

Ces paramètres n’ont pas été modifiés. L’objectif était uniquement de migrer le type de chiffrement des credentials CephX.

1. Vérifier l’état initial du cluster

Avant toute modification, il faut impérativement vérifier que le cluster est sain :

ceph -s
ceph health detail

Dans mon cas, Ceph signalait plusieurs problèmes liés aux anciennes clés :

[WRN] AUTH_INSECURE_CLIENT_KEY_TYPE
[ERR] AUTH_INSECURE_SERVICE_KEY_TYPE
[ERR] AUTH_INSECURE_SERVICE_TICKETS

Les MON autorisaient encore l’ancien chiffrement aes.

2. Vérifier la configuration CephX actuelle

La configuration des chiffrements peut être affichée avec :

ceph --format=json mon dump | jq -r '
  "allowed=" + ([.auth_allowed_ciphers[].name] | join(",")),
  "preferred=" + .auth_preferred_cipher.name,
  "service=" + .auth_service_cipher.name
'

Au début de la migration, nous avions :

allowed=aes,aes256k
preferred=aes
service=aes

Il est essentiel que aes256k soit déjà autorisé avant de commencer à migrer les différentes clés.

3. Définir aes256k comme chiffrement préféré

ceph mon set auth_preferred_cipher aes256k

Vérification :

ceph mon dump | grep -E \
'auth_allowed_ciphers|auth_preferred_cipher|auth_service_cipher'

Résultat attendu :

auth_allowed_ciphers aes,aes256k
auth_preferred_cipher aes256k
auth_service_cipher aes

Les futures créations de clés utilisent désormais aes256k comme type préféré.

4. Migrer les MGR

Les trois MGR doivent être migrés individuellement.

Exemple pour mgr.pve01 :

systemctl stop ceph-mgr@pve01
ceph auth rotate --key-type=aes256k mgr.pve01 > /tmp/mgr.pve01.keyring

Installer la nouvelle clé :

ceph-authtool \
  --import-keyring /tmp/mgr.pve01.keyring \
  /var/lib/ceph/mgr/ceph-pve01/keyring
chown ceph:ceph /var/lib/ceph/mgr/ceph-pve01/keyring
chmod 600 /var/lib/ceph/mgr/ceph-pve01/keyring

Puis redémarrer le MGR :

systemctl start ceph-mgr@pve01

Vérification :

ceph -s
ceph health detail

Lorsque la migration fonctionne, mgr.pve01 disparaît de AUTH_INSECURE_SERVICE_KEY_TYPE.

La même procédure est appliquée à mgr.pve02 et mgr.pve03.

5. Migrer les OSD

C’est la partie la plus sensible de la procédure.

Les OSD utilisés dans mon cluster sont des OSD BlueStore créés avec ceph-volume. Il faut donc mettre à jour :

  • la clé CephX dans la base d’authentification ;
  • le keyring local de l’OSD ;
  • la clé osd_key stockée dans le label BlueStore.

6. Un seul OSD à la fois

Mon cluster utilise une réplication :

size = 3
min_size = 2

Nous avons donc migré un seul OSD à la fois.

Pour osd.0 :

systemctl stop ceph-osd@0
ceph osd down 0

Vérifier immédiatement l’état du cluster :

ceph -s
ceph health detail

Pendant l’arrêt, les PG utilisant cet OSD peuvent temporairement apparaître en undersized ou degraded.

Il faut impérativement attendre le retour de l’OSD et des PG avant de passer au suivant.

7. Faire tourner la clé de l’OSD

ceph auth rotate --key-type=aes256k osd.0 > /tmp/osd.0.keyring

Installer la nouvelle clé :

ceph-authtool \
  --import-keyring /tmp/osd.0.keyring \
  /var/lib/ceph/osd/ceph-0/keyring
chown ceph:ceph /var/lib/ceph/osd/ceph-0/keyring
chmod 600 /var/lib/ceph/osd/ceph-0/keyring

8. Identifier le périphérique BlueStore

Pour identifier le périphérique utilisé par un OSD :

ceph-volume lvm list 0

Dans mon cas, osd.0 utilisait :

/dev/ceph-1e46639a-575f-4c39-a048-7b64439816f6/osd-block-66b0399e-8fb7-44e3-ab83-7762defa7eed

Pour les OSD suivants, une méthode plus rapide consiste à utiliser :

readlink -f /var/lib/ceph/osd/ceph-N/block

9. Mettre à jour la clé BlueStore

L’OSD étant arrêté, mettre à jour son osd_key :

ceph-bluestore-tool \
  --dev /dev/ceph-1e46639a-575f-4c39-a048-7b64439816f6/osd-block-66b0399e-8fb7-44e3-ab83-7762defa7eed \
  set-label-key \
  --key osd_key \
  -v /tmp/osd.0.keyring

Cette étape est importante pour les OSD BlueStore créés avec ceph-volume.

10. Redémarrer l’OSD

systemctl start ceph-osd@0

Vérifier :

ceph -s

On veut retrouver :

30 osds: 30 up, 30 in
129 active+clean

Une fois le cluster revenu à un état propre, passer à l’OSD suivant.

Cette procédure a été répétée pour les 30 OSD du cluster, un par un.

11. Un incident de synchronisation horaire

Pendant la migration, un problème de synchronisation temporelle a été détecté sur pve01.

Ceph signalait :

clock skew detected on mon.pve02
clock skew detected on mon.pve03

Il s’agissait en réalité d’un décalage de l’horloge de pve01.

La synchronisation a été vérifiée avec :

timedatectl
chronyc tracking
chronyc sources -v

Après correction, chrony indiquait notamment :

System time     : 0.000075084 seconds fast of NTP time
Last offset     : +0.000105958 seconds
Leap status     : Normal

Le cluster est ensuite revenu à :

3 MON quorum
30/30 OSD up/in
129 PG active+clean

Ne poursuivez jamais une migration Ceph si le cluster présente un problème de synchronisation horaire.

12. Migrer client.admin

La clé client.admin est particulièrement sensible puisqu’elle permet l’administration du cluster.

Avant sa rotation, il est prudent de conserver une clé de secours.

ceph auth get-or-create client.admin-backup \
  mon 'allow *' \
  > /root/client.admin-backup.keyring

chmod 600 /root/client.admin-backup.keyring

Générer ensuite la nouvelle clé :

ceph auth rotate --key-type=aes256k client.admin \
  > /root/client.admin.keyring

Importer la nouvelle clé dans le keyring Proxmox :

ceph-authtool \
  --import-keyring /root/client.admin.keyring \
  /etc/pve/priv/ceph.client.admin.keyring

Tester explicitement le nouveau keyring :

ceph -n client.admin \
  -k /etc/pve/priv/ceph.client.admin.keyring \
  auth ls >/dev/null && echo "ADMIN OK"

Résultat :

ADMIN OK

Ne passez jamais directement à la désactivation de aes sans avoir validé l’accès administratif avec la nouvelle clé.

13. Migrer client.crash

Le keyring utilisé était :

/etc/pve/ceph/ceph.client.crash.keyring

Rotation :

ceph auth rotate --key-type=aes256k client.crash \
  > /tmp/client.crash.keyring

Installation :

ceph-authtool \
  --import-keyring /tmp/client.crash.keyring \
  /etc/pve/ceph/ceph.client.crash.keyring

Il est normal que chmod sur certains fichiers sous /etc/pve échoue : ce répertoire est géré par pmxcfs dans Proxmox.

14. Vérifier les clients bootstrap

Les entités suivantes existaient dans la base d’authentification :

  • client.bootstrap-mds
  • client.bootstrap-mgr
  • client.bootstrap-osd
  • client.bootstrap-rbd
  • client.bootstrap-rbd-mirror
  • client.bootstrap-rgw

Avant de les modifier, les trois nœuds ont été inspectés afin de rechercher leurs keyrings :

find /etc/pve /etc/ceph /var/lib/ceph \
  -type f \
  \( -name "ceph.keyring" -o -name "*.keyring" \) \
  -print 2>/dev/null | sort

Le seul keyring bootstrap trouvé était :

/var/lib/ceph/bootstrap-osd/ceph.keyring

Les cinq autres entités étaient des comptes bootstrap standards présents dans la base d’authentification, mais aucun keyring correspondant n’était présent sur les trois nœuds.

15. Migrer client.bootstrap-osd

La rotation a été effectuée une seule fois, puis le même keyring a été distribué aux trois nœuds.

ceph auth rotate --key-type=aes256k client.bootstrap-osd \
  > /tmp/client.bootstrap-osd.keyring

Installation locale :

ceph-authtool \
  --import-keyring /tmp/client.bootstrap-osd.keyring \
  /var/lib/ceph/bootstrap-osd/ceph.keyring

Le même fichier a ensuite été distribué à pve01 et pve02.

Attention : il ne faut pas faire trois rotations successives pour la même entité. Il faut générer une nouvelle clé une seule fois, puis distribuer ce même keyring partout où il est utilisé.

16. Migrer les autres clients bootstrap

Les cinq comptes restants étaient :

  • client.bootstrap-mds
  • client.bootstrap-mgr
  • client.bootstrap-rbd
  • client.bootstrap-rbd-mirror
  • client.bootstrap-rgw

Le cluster n’utilisait par ailleurs :

  • aucun CephFS ;
  • aucun orchestrateur Ceph ;
  • aucun RBD mirror.

Les cinq entités ont donc été converties dans l’auth DB :

for c in \
  client.bootstrap-mds \
  client.bootstrap-mgr \
  client.bootstrap-rbd \
  client.bootstrap-rbd-mirror \
  client.bootstrap-rgw
do
    ceph auth rotate --key-type=aes256k "$c" >/dev/null || exit 1
done

Après cette étape, plus aucune clé client n’utilisait aes.

17. Vérifier l’absence des anciennes clés statiques

ceph --format=json health detail \
  | jq '.checks | has("AUTH_INSECURE_CLIENT_KEY_TYPE")'

Résultat attendu :

false

Pour les services :

ceph --format=json health detail \
  | jq '.checks | has("AUTH_INSECURE_SERVICE_KEY_TYPE")'

Résultat attendu :

false

18. Passer les tickets de service en aes256k

Une fois tous les services migrés, nous avons changé le chiffrement des tickets :

ceph mon set auth_service_cipher aes256k

Vérification :

ceph mon dump | grep -E \
'auth_allowed_ciphers|auth_preferred_cipher|auth_service_cipher'

La configuration est devenue :

auth_service_cipher aes256k
auth_allowed_ciphers aes,aes256k
auth_preferred_cipher aes256k

19. Interdire la création de nouvelles clés aes

Une fois tous les clients et services existants migrés, nous avons désactivé la création de nouveaux credentials utilisant l’ancien type :

ceph config set mon 'mon auth allow insecure key' false

Le warning :

AUTH_INSECURE_KEYS_CREATABLE

a immédiatement disparu.

20. Retirer définitivement aes des chiffrements autorisés

La dernière étape de verrouillage consiste à supprimer complètement aes des chiffrements autorisés :

ceph mon set auth_allowed_ciphers aes256k

La vérification finale donne :

ceph --format=json mon dump | jq -r '
  "allowed=" + ([.auth_allowed_ciphers[].name] | join(",")),
  "preferred=" + .auth_preferred_cipher.name,
  "service=" + .auth_service_cipher.name
'

Résultat obtenu :

allowed=aes256k
preferred=aes256k
service=aes256k

À partir de ce moment, le cluster n’accepte plus de clés CephX en aes.

21. Le dernier warning : AUTH_INSECURE_ROTATING_SERVICE_KEY_TYPE

Après toutes les opérations, le cluster affichait encore :

AUTH_INSECURE_ROTATING_SERVICE_KEY_TYPE

Avec :

rotating service keys for mon using insecure key type: aes
rotating service keys for mds using insecure key type: aes
rotating service keys for osd using insecure key type: aes
rotating service keys for mgr using insecure key type: aes

Ces clés ne correspondent plus aux clés statiques utilisées actuellement par les services. Il s’agit d’anciennes clés tournantes conservées pendant leur durée de vie.

La durée des tickets est contrôlée par :

ceph config get mon auth_service_ticket_ttl

Dans mon cluster :

3600.000000

soit 1 heure.

Ces anciennes clés peuvent donc disparaître naturellement au fil de leur expiration.

Il n’est pas nécessaire de lancer immédiatement :

ceph auth wipe-rotating-service-keys

Cette commande force la suppression des anciennes clés tournantes et peut invalider les tickets existants. Pour une migration normale, il est préférable de laisser les anciennes clés expirer naturellement.

22. État final du cluster

Après migration, le cluster présentait :

  • 3 MON en quorum
  • 30/30 OSD up/in
  • 129 PG active+clean
  • CephX toujours activé
  • aes256k comme seul chiffrement autorisé

La configuration des MON était :

auth_allowed_ciphers  = aes256k
auth_preferred_cipher = aes256k
auth_service_cipher   = aes256k

Et la vérification :

ceph --format=json health detail \
  | jq '.checks | keys[]' | grep AUTH

ne retournait plus que :

AUTH_INSECURE_ROTATING_SERVICE_KEY_TYPE

Warning : ne pas migrer plusieurs OSD simultanément

Ne migrez pas plusieurs OSD simultanément sans avoir vérifié la redondance de vos pools.

Dans mon cluster, avec size=3 et min_size=2, nous avons utilisé une stratégie extrêmement simple :

  • arrêt d’un seul OSD ;
  • rotation de sa clé ;
  • mise à jour du label BlueStore ;
  • redémarrage ;
  • attente du retour up/in ;
  • attente du retour des PG à active+clean ;
  • passage à l’OSD suivant.

Warning : synchronisation NTP

La synchronisation horaire doit être correcte sur tous les MON.

Vérifications :

timedatectl
chronyc tracking
chronyc sources -v

Une dérive de quelques centaines de millisecondes peut provoquer :

clock skew detected

et compliquer fortement le diagnostic d’un problème Ceph.

Warning : ne jamais publier les clés CephX

Les commandes ceph auth rotate génèrent des secrets CephX.

Évitez de publier leur sortie dans un article, une capture d’écran ou un terminal partagé.

Exemple :

ceph auth rotate --key-type=aes256k osd.0 > /tmp/osd.0.keyring

Après validation, les fichiers temporaires peuvent être supprimés :

rm -f /tmp/osd.0.keyring

Une clé affichée ou copiée par erreur doit être considérée comme exposée et remplacée par une nouvelle rotation.

Warning : client.admin

La rotation de client.admin est une opération particulièrement sensible.

  • Conserver une clé de secours avant la rotation.
  • Installer le nouveau keyring.
  • Tester explicitement l’accès avec la nouvelle clé.
  • Ne désactiver aes qu’après validation.

Procédure condensée

La logique générale est la suivante :

  1. Mise à jour vers une version Ceph corrigée.
  2. Vérification de la santé du cluster.
  3. Vérification de NTP / Chrony.
  4. Vérification de la présence de aes256k.
  5. Définition de aes256k comme chiffrement préféré.
  6. Migration des MGR.
  7. Migration des OSD un par un.
  8. Migration des clients.
  9. Passage des tickets de service en aes256k.
  10. Interdiction de créer de nouvelles clés aes.
  11. Suppression de aes de auth_allowed_ciphers.
  12. Expiration naturelle des anciennes rotating service keys.
  13. Vérification finale de la santé du cluster.

Vérifications finales

Les commandes suivantes permettent de contrôler le résultat :

ceph -s
ceph health detail
ceph --format=json mon dump | jq -r '
  "allowed=" + ([.auth_allowed_ciphers[].name] | join(",")),
  "preferred=" + .auth_preferred_cipher.name,
  "service=" + .auth_service_cipher.name
'

L’objectif final est :

health: HEALTH_OK

avec :

allowed=aes256k
preferred=aes256k
service=aes256k

Conclusion

La migration de aes vers aes256k n’est pas une simple modification de configuration.

Sur un cluster Ceph existant, les credentials doivent être migrés progressivement, notamment ceux des MGR, OSD et clients CephX. Le nouveau chiffrement doit ensuite être activé pour les tickets, la création de nouvelles clés aes doit être interdite et, enfin, aes doit être retiré des chiffrements autorisés.

Cette migration nous a également rappelé plusieurs points importants :

  • un seul OSD à la fois dans ma configuration ;
  • horloges synchronisées sur les MON ;
  • ne jamais exposer les clés secrètes ;
  • tester client.admin avant de verrouiller l’authentification ;
  • ne pas supprimer brutalement les anciennes rotating service keys.

À l’issue de la procédure, le cluster fonctionne avec CephX et aes256k uniquement, sans clé statique utilisant l’ancien type aes.

La documentation officielle Ceph reste la référence avant toute adaptation de cette procédure à un autre cluster ou à une architecture différente.

Ressources

Cette procédure s’appuie principalement sur la documentation officielle Ceph. Les ressources suivantes ont été utilisées pour comprendre la vulnérabilité, la migration des clés CephX, la gestion des clés clients et la mise à jour des labels BlueStore.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. Découvrez comment les données de vos commentaires sont traitées.