Aller au contenu
Administration Linux medium

AlmaLinux 10 : ce qui change pour un serveur

52 min de lecture

AlmaLinux 10 « Lavender Lion » offre dix ans de correctifs de sécurité, gratuits, sur tout le périmètre de la distribution, sans souscription ni offre payante. En contrepartie, elle exige un processeur x86-64-v3, ce qui tue littéralement une VM dont l'hyperviseur expose un CPU générique, elle supprime la modularité (donc casse les playbooks qui font dnf module enable), et elle démarre avec SELinux en Enforcing. Ce guide s'appuie sur un lab en machine virtuelle : une AlmaLinux 10.2 neuve, une AlmaLinux 9.8 témoin, images cloud officielles vérifiées au SHA256. Chaque affirmation est soit une sortie de commande réelle, soit une consigne officielle présentée comme telle. Sur plusieurs points, le lab contredit ce que raconte la documentation ou les tutoriels, et il le dit.

  • Comprendre ce que les dix ans de sécurité gratuits couvrent, et la nuance qui coûte cher : l'absence d'EUS.
  • Mesurer qui patche quoi : la frontière entre AppStream et EPEL, et pourquoi elle décide de votre architecture.
  • Connaître les comportements par défaut sur lesquels vos scripts reposent : /tmp, sysctl.conf, journaux de connexion.
  • Reproduire et corriger les trois pièges SELinux réels, dont un que tous les tutoriels racontent de travers.
  • Anticiper le piège x86-64-v3, celui qui transforme un hyperviseur mal configuré en kernel panic.
  • Préparer une migration AlmaLinux 9 vers 10 avec ELevate, et savoir quand y renoncer.

Avant de bâtir quoi que ce soit, il faut savoir combien de temps la version tiendra et ce qu'elle vous engage à faire. C'est ici que se joue l'argument principal d'AlmaLinux, et il mérite d'être énoncé avec sa nuance.

Dix ans de sécurité, gratuits, sans rien à acheter

Section intitulée « Dix ans de sécurité, gratuits, sans rien à acheter »

AlmaLinux 10 bénéficie d'un support actif jusqu'au 31 mai 2030 et de correctifs de sécurité jusqu'au 31 mai 2035, soit dix ans. La machine le déclare elle-même, dans son fichier d'identité système :

Fenêtre de terminal
grep SUPPORT_END /etc/os-release
SUPPORT_END=2035-06-01

Le point capital n'est pas la durée, c'est le modèle économique : tout est gratuit, et la fondation ne vend rien. Il n'y a aucune souscription à activer, aucun compte à créer, aucun agent d'abonnement à installer. Cette absence est en elle-même l'information, et elle se vérifie en une ligne : command -v pro subscription-manager insights-client ne trouve rien du tout sur l'image cloud.

Ce tableau se lit comme une liste de choses à retester avant de bâtir dessus. Les valeurs de la colonne AlmaLinux 10 sont celles relevées dans la VM du lab, pas des chiffres d'annonce. La colonne AlmaLinux 9 vient du témoin, une 9.8 lancée à côté.

ComposantAlmaLinux 9 (témoin)AlmaLinux 10 (mesuré)
Version9.8 (Olive Jaguar)10.2 (Lavender Lion)
Noyau Linux5.14.0-6876.12.0-211 (el10_2)
systemd252257
glibc2.342.39
OpenSSH9.9p1
sudo1.9.17p2 (C, GNU)
coreutils9.5 (GNU)
Gestionnaire de paquetsdnf 4.xdnf 4.20
nginx1.26.3 (AppStream)
PostgreSQL16 (AppStream)
Podman5.8.2 (AppStream)

Deux lectures utiles. Le noyau 6.12 et systemd 257 placent AlmaLinux 10 sur un socle récent et parfaitement standard : rien d'exotique, aucun composant maison. La vraie rupture d'AlmaLinux 10 n'est pas dans les numéros de version, elle est dans le niveau d'instruction du processeur exigé et dans la disparition de la modularité, deux points traités plus bas.

AlmaLinux 10 n'est pas en dnf5, contrairement à ce qu'on lit partout

Section intitulée « AlmaLinux 10 n'est pas en dnf5, contrairement à ce qu'on lit partout »

Voici la première contradiction relevée par le lab, et elle a des conséquences pratiques. Une idée très répandue veut que la génération EL10 soit passée à dnf5, la réécriture du gestionnaire de paquets. C'est faux sur AlmaLinux 10.2. La distribution livre dnf 4.20, le binaire /usr/bin/dnf pointe vers dnf-3, et dnf5 n'est même pas disponible au catalogue :

Fenêtre de terminal
readlink -f $(command -v dnf)
dnf list --available dnf5 dnf5-plugins
/usr/bin/dnf-3
Error: No matching Packages to list

La conséquence est subtile mais elle change le diagnostic : la sous-commande dnf module existe donc encore. Ce qui a disparu, ce sont les modules eux-mêmes, pas la commande. Ce n'est pas la même chose, et le message d'erreur que vous obtiendrez n'est pas celui que vous attendez. Le mécanisme complet des dépôts et des transactions RPM est détaillé dans le guide gérer les paquets avec DNF.

Voici la section qui décide d'une architecture, et elle repose entièrement sur des mesures. La question est simple : les paquets que vous installez vraiment sur un serveur sont-ils couverts par l'engagement de sécurité d'AlmaLinux ? La réponse est « en partie », et il faut savoir où passe la frontière.

Les dépôts activés par défaut, et le changement entre 9 et 10

Section intitulée « Les dépôts activés par défaut, et le changement entre 9 et 10 »

Sur l'image cloud neuve, dnf repolist donne quatre dépôts actifs. Retenez surtout le troisième, CRB (CodeReady Builder, le dépôt qui fournit les bibliothèques de développement dont beaucoup de paquets tiers dépendent) :

appstream AlmaLinux 10 - AppStream
baseos AlmaLinux 10 - BaseOS
crb AlmaLinux 10 - CRB
extras AlmaLinux 10 - Extras

CRB est activé par défaut sur AlmaLinux 10. Le lab a vérifié les deux versions côte à côte : sur le témoin AlmaLinux 9, le même dépôt est disabled. C'est un vrai changement de comportement entre les deux versions, et il vous épargne le dnf config-manager --enable crb que traînent tous les vieux tutoriels EL9. D'autres dépôts existent mais restent désactivés (highavailability, nfv, rt, sap), ce qui est le comportement attendu.

Le lab a interrogé huit paquets que l'on installe réellement sur un serveur : serveur web, base de données, cache, conteneurs, outils d'exploitation. Le résultat trace une frontière nette entre ce qu'AlmaLinux patche et ce qu'elle ne patche pas.

PaquetVersionDépôt qui le sertCouvert par AlmaLinux ?
nginx1.26.3appstreamoui
postgresql16appstreamoui
podman5.8.2appstreamoui
valkey8.0.7appstreamoui
redisn'existe plusaucunsans objet
dockern'existe pashors distributionnon
fail2ban1.1.0epelnon
certbot4.2.0epelnon

Trois faits méritent qu'on s'y arrête. D'abord, redis n'existe plus du tout : dnf repoquery "redis*" et dnf repoquery --whatprovides redis renvoient le vide, pas une ancienne version. Le remplaçant est valkey, le fork communautaire né du changement de licence de Redis. Un rôle Ansible qui installe redis casse sur AlmaLinux 10, et il casse avec un message de paquet introuvable, pas avec un avertissement de renommage. Ensuite, Docker est purement hors distribution : il faut passer par le dépôt officiel de Docker, ou utiliser Podman, qui est là, dans AppStream, et couvert. Enfin, fail2ban et certbot ne sont pas dans AlmaLinux du tout : ils viennent d'EPEL.

En résumé : sur AlmaLinux 10, le serveur web, la base de données, le cache et les conteneurs sont couverts par la distribution ; ce sont fail2ban et certbot, deux outils d'exploitation très courants, qui sortent du périmètre. Les guides Debian 13 Trixie et Ubuntu Server 26.04 appliquent le même protocole de mesure à leurs propres dépôts.

Le champ Vendor du paquet RPM tranche la question de la couverture mieux que n'importe quel discours. Mettez les deux paquets côte à côte, une fois installés :

Fenêtre de terminal
rpm -qi nginx | grep -E "^(Name|Vendor|Packager)"
rpm -qi fail2ban | grep -E "^(Name|Vendor|Packager)"
Name : nginx Name : fail2ban
Vendor : AlmaLinux Vendor : Fedora Project
Packager : AlmaLinux … Packager : Fedora Project

fail2ban est empaqueté et signé par le projet Fedora, pas par AlmaLinux. Il est donc hors de l'engagement de sécurité de la distribution que vous avez choisie. EPEL (Extra Packages for Enterprise Linux) est maintenu par un groupe d'intérêt de la communauté Fedora, et il n'offre aucun SLA. La formulation officielle du projet ne laisse aucune ambiguïté : « If it breaks, you get to keep both pieces », que l'on peut traduire par « si ça casse, vous gardez les morceaux ». Le paquet est là, il s'installe en une commande, et personne ne s'est engagé à le corriger.

L'effet de bord savoureux : installer fail2ban pose un pare-feu

Section intitulée « L'effet de bord savoureux : installer fail2ban pose un pare-feu »

Le lab a mesuré une conséquence que personne n'annonce, et qui laisse un composant inattendu sur votre machine. La VM n'avait ni firewalld ni nftables (voir plus bas, c'est une trouvaille en soi). Après un simple dnf -y install fail2ban, le paquet EPEL tire ses dépendances depuis BaseOS :

Fenêtre de terminal
dnf repoquery --installed --queryformat "%{name} from_repo=%{from_repo}\n" firewalld nftables python3-firewall
firewalld from_repo=baseos
nftables from_repo=baseos
python3-firewall from_repo=baseos

Vous vous retrouvez donc avec un firewalld installé sur une machine qui n'en avait pas, tiré par un paquet venu d'un dépôt communautaire. Le point rassurant, vérifié dans la foulée : il est installé mais pas activé. systemctl is-active firewalld répond inactive, et is-enabled répond disabled. Rien ne filtre, mais le composant est là, et beaucoup d'administrateurs ignorent sa présence jusqu'au jour où quelqu'un le démarre par réflexe.

AlmaLinux publie ses correctifs sous forme d'ALSA (AlmaLinux Security Advisory), et la liste est consultable sans souscription, directement depuis la machine. Chaque avis est nominatif : il cite le paquet, la sévérité et la version corrigée.

Fenêtre de terminal
dnf updateinfo list
dnf updateinfo summary
ALSA-2026:33124 Moderate/Sec. coreutils-9.5-8.el10_2.x86_64
ALSA-2026:26532 Important/Sec. dracut-107-7.el10_2.x86_64
ALSA-2026:22715 Important/Sec. expat-2.7.3-1.el10_2.1.x86_64
ALSA-2026:25191 Critical/Sec. kernel-6.12.0-211.22.1.el10_2.x86_64

Gardez en tête la limite de cet outil, elle découle de tout ce qui précède : cette liste ne couvre que les dépôts AlmaLinux. EPEL n'émet pas d'ALSA. Un dnf updateinfo qui ne remonte rien pour fail2ban ne signifie donc pas que fail2ban est sain : cela signifie que personne ne publie d'avis pour lui. La routine de mise à jour au quotidien est décrite dans mises à jour de sécurité.

Trois comportements par défaut sur lesquels vos scripts reposent

Section intitulée « Trois comportements par défaut sur lesquels vos scripts reposent »

Voici trois mesures qui, prises ensemble, dessinent le caractère d'AlmaLinux 10 : une distribution conservatrice, qui préserve des comportements historiques du monde Unix. C'est un argument d'exploitation, pas un jugement de valeur : vos scripts, vos crons et vos outils d'audit reposent souvent sur ces comportements sans que vous en ayez conscience.

Sur AlmaLinux 10, /tmp est un répertoire xfs sur le disque, sans point de montage dédié : ce qui s'y trouve survit au redémarrage. L'unité systemd tmp.mount, qui monterait à la place un tmpfs (un système de fichiers en mémoire vive, vidé à chaque redémarrage), est livrée mais désactivée.

Fenêtre de terminal
findmnt /tmp
stat -fc "%T" /tmp
systemctl is-enabled tmp.mount
[exit=1]
xfs
disabled

findmnt ne trouve aucun point de montage (code de retour 1), le type de système de fichiers est xfs, et tmp.mount est disabled. Le lab a poussé la vérification jusqu'au bout, avec un redémarrage réel (l'identifiant de démarrage change, sinon le lab s'arrête) et un fichier témoin déposé juste avant :

APRES REBOOT :
2026-07-13T07:14:55+00:00
[/tmp exit=0]
2026-07-13T07:14:55+00:00
[/var/tmp exit=0]

Le témoin est toujours là, dans /tmp comme dans /var/tmp. Un job qui dépose un gros fichier temporaire sans craindre de saturer la RAM, ou un script qui laisse un état dans /tmp entre deux exécutions, peut donc compter sur cette persistance. Gardez toutefois un réflexe de portabilité : d'autres distributions montent /tmp en mémoire et le vident à chaque démarrage, Debian 13 par exemple, donc un script destiné à plusieurs systèmes ne doit jamais supposer la persistance. La bascule reste possible dans l'autre sens : systemctl enable --now tmp.mount monte le tmpfs, et le lab a vérifié qu'elle tient au redémarrage. AlmaLinux fournit l'unité, elle choisit simplement de ne pas l'activer.

La méthode historique de réglage des paramètres du noyau fonctionne : ce que vous écrivez dans /etc/sysctl.conf est appliqué au démarrage. Le lab a écrit net.ipv4.ip_forward=1 dans ce fichier, puis a réellement redémarré la VM :

APRES REBOOT, /etc/sysctl.conf contient :
net.ipv4.ip_forward=1
valeur reelle du noyau :
1

La valeur est appliquée. Le mécanisme se lit dans le système de fichiers : /etc/sysctl.d/99-sysctl.conf est un lien symbolique vers ../sysctl.conf, donc le fichier historique est bien pris dans le balayage de systemd-sysctl. Le placement moderne, dans /etc/sysctl.d/99-local.conf, fonctionne évidemment aussi.

C'est ce placement moderne qu'il faut préférer dans un rôle Ansible ou un script destiné à plusieurs distributions : toutes ne lisent plus le fichier historique au démarrage, et écrire dans /etc/sysctl.d/ est la seule convention qui fonctionne partout. Sur une machine AlmaLinux seule, les deux emplacements sont équivalents et vérifiés.

last, lastb et lastlog sont présentes, et btmp est alimenté

Section intitulée « last, lastb et lastlog sont présentes, et btmp est alimenté »

Les trois commandes historiques de consultation des connexions sont livrées, et les fichiers qu'elles lisent sont réellement alimentés. C'est un point que vos outils d'audit utilisent peut-être sans que vous le sachiez.

Fenêtre de terminal
command -v last lastb lastlog
/usr/bin/last
/usr/bin/lastb
/usr/bin/lastlog

Les trois commandes sont là, et surtout elles voient quelque chose. Le lab a provoqué deux échecs d'authentification SSH réels (mauvais mot de passe, depuis la VM elle-même), puis a regardé le fichier qui enregistre les échecs :

$ stat -c "%n taille=%s modifie=%y" /var/log/btmp
/var/log/btmp taille=768 modifie=2026-07-13 07:13:19 +0000
$ lastb
root ssh:notty 127.0.0.1 Mon Jul 13 07:13 - 07:13 (00:00)
root ssh:notty 127.0.0.1 Mon Jul 13 07:13 - 07:13 (00:00)
btmp begins Mon Jul 13 07:13:16 2026

btmp est alimenté (il passe de 0 à 768 octets), et lastb voit les deux échecs. Pour qui surveille les tentatives de force brute en lisant btmp, AlmaLinux ne demande rien de nouveau : vos scripts d'audit et votre supervision fonctionnent tels quels. Le complément habituel reste fail2ban, qui lit les journaux plutôt que btmp, et qui vient d'EPEL comme on l'a vu.

Un espace utilisateur GNU, en C, sans réécriture

Section intitulée « Un espace utilisateur GNU, en C, sans réécriture »

L'espace utilisateur d'AlmaLinux 10 est celui que vos automatisations connaissent depuis des années, et le lab l'a vérifié binaire par binaire. La distribution livre sudo 1.9.17p2 écrit en C, le binaire setuid historique de Todd Miller, et GNU coreutils 9.5 sur l'ensemble des binaires testés :

ls ls (GNU coreutils) 9.5
cp cp (GNU coreutils) 9.5
cat cat (GNU coreutils) 9.5
sort sort (GNU coreutils) 9.5
true true (GNU coreutils) 9.5
false false (GNU coreutils) 9.5

Aucune asymétrie, aucun binaire réécrit. Mieux : sudo-rs, uutils-coreutils et rust-coreutils ne sont même pas disponibles au catalogue (dnf list --available répond No matching Packages to list). La conséquence pratique est directe : le prompt de sudo, le format de sortie de ls et le comportement des coreutils sont exactement ceux qu'attendent vos scripts Expect, vos crons et vos parsings en CI. Sur ce terrain, il n'y a rien à retester.

Côté clés de dépôt, même stabilité : rpm --import fonctionne, sans aucun avertissement de dépréciation, et reste le mécanisme officiel. La raison est structurelle : les clés vivent dans /etc/pki/rpm-gpg/ et chaque dépôt déclare explicitement la sienne dans son fichier .repo, avec gpgcheck=1 :

/etc/yum.repos.d/almalinux-baseos.repo:gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-AlmaLinux-10

La clé est rattachée à un dépôt précis : une clé importée pour un dépôt tiers ne signe pas pour les autres. Le modèle RPM n'a jamais eu le défaut du trousseau unique, celui qui a condamné apt-key dans le monde APT, où toute clé importée signait pour tous les dépôts.

Sur une infrastructure cloisonnée ou soumise à une revue de conformité, tout flux sortant non déclaré est un point d'audit. La question mérite une mesure, pas une opinion. Le lab a lancé tcpdump dans la VM, en excluant sa propre session SSH de pilotage, sur deux fenêtres de 30 secondes.

Fenêtre de capturePaquets capturés (hors SSH)
Contrôle, machine au repos0
Pendant 3 connexions SSH avec session complète4

Les quatre paquets de la seconde fenêtre, sortie brute intégrale :

07:12:33.133171 eth0 Out IP 10.0.2.15.56577 > 51.91.83.168.123: NTPv4, Client, length 48
07:12:33.148211 eth0 In IP 51.91.83.168.123 > 10.0.2.15.56577: NTPv4, Server, length 48
07:12:34.653770 eth0 Out IP 10.0.2.15.60396 > 172.234.184.36.123: NTPv4, Client, length 48
07:12:34.667517 eth0 In IP 172.234.184.36.123 > 10.0.2.15.60396: NTPv4, Server, length 48

Du NTP, et rien d'autre. Zéro requête DNS, zéro poignée de main TLS, zéro paquet vers un domaine nommé. À la connexion, AlmaLinux n'appelle personne.

Trois précisions complètent le tableau, et deux d'entre elles expliquent le résultat. Il n'y a pas de MOTD dynamique : /etc/motd fait 0 octet, /etc/motd.d/ est vide, et /etc/update-motd.d/ n'existe pas. Il n'y a donc rien à exécuter à la connexion, donc rien à appeler. Ensuite, insights-client n'est pas installé, pas plus que subscription-manager : c'est une différence nette avec RHEL, où le client Insights est présent, et AlmaLinux ne reprend pas cette pièce. Enfin, par honnêteté : dnf-makecache.timer est actif, donc la machine contacte les miroirs AlmaLinux périodiquement. Ce n'est pas de la télémétrie (aucune donnée sur votre machine n'est transmise), mais c'est bien du trafic sortant, et autant le savoir avant de le découvrir dans un journal de pare-feu.

SELinux et le pare-feu : la vérité mesurée, pas la légende

Section intitulée « SELinux et le pare-feu : la vérité mesurée, pas la légende »

C'est le vrai dépaysement pour qui découvre la famille Enterprise Linux, et c'est aussi le domaine où circulent le plus d'approximations. Le lab en corrige deux, dont une qui est répétée dans la quasi-totalité des tutoriels.

Commençons par la légende. On lit partout que firewalld serait actif dès le premier démarrage sur la famille Enterprise Linux. C'est faux sur l'image cloud, et le lab est catégorique :

Fenêtre de terminal
rpm -q firewalld nftables iptables-nft iptables-services
command -v firewall-cmd nft iptables
package firewalld is not installed
package nftables is not installed
package iptables-nft is not installed
package iptables-services is not installed
[exit=1]

Il n'y a aucun pare-feu, pas même installé : ni firewalld, ni nftables, ni iptables, et pas le moindre binaire dans le PATH. Le témoin AlmaLinux 9 donne exactement le même résultat : ce n'est pas une nouveauté de la version 10, c'est le profil de l'image cloud.

La réserve doit être posée franchement, car elle limite la portée du constat : ce résultat vaut pour l'image cloud (GenericCloud), celle que l'on déploie chez un hébergeur. Une installation par l'ISO d'AlmaLinux, elle, installe et active firewalld ; le lab ne l'a pas testée, et ne peut donc rien en dire de première main. Retenez la conséquence opérationnelle, qui ne change pas : sur une machine cloud, le filtrage est à votre charge, et c'est la première chose à poser sur un serveur exposé. La marche à suivre est dans les guides firewalld et nftables.

Le contrôle d'accès obligatoire (MAC, un mécanisme qui restreint ce qu'un processus peut faire, indépendamment des permissions de fichiers classiques) est en revanche bien présent, et actif dès le premier démarrage.

Fenêtre de terminal
getenforce
sestatus | grep -E "Loaded policy|Current mode"
Enforcing
Loaded policy name: targeted
Current mode: enforcing

La politique chargée est targeted : seuls les services réseau connus sont confinés, le reste du système tourne sans restriction supplémentaire. Si vous venez d'une distribution sous AppArmor, le modèle mental change : AppArmor raisonne par chemin de fichier, SELinux par étiquette posée sur chaque fichier et chaque processus. C'est plus fin et plus strict, et c'est précisément pour cela que SELinux bloque des choses qui marchaient ailleurs. Les trois sections qui suivent reproduisent les blocages réels, avec leur correctif. Le fond du sujet est traité dans le guide SELinux.

Le piège du port non standard n'est pas celui qu'on raconte

Section intitulée « Le piège du port non standard n'est pas celui qu'on raconte »

Voici la correction la plus utile de ce guide. L'exemple pédagogique le plus répandu au monde consiste à faire écouter Apache sur le port 8443 pour « démontrer » que SELinux bloque les ports non standard. Cet exemple est faux, parce que 8443 est déjà autorisé dans la politique :

Fenêtre de terminal
semanage port -l | grep -w "^http_port_t"
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000

Et de fait, httpd démarre sans broncher sur 8443 : le lab obtient un systemctl restart httpd en code 0 et un journal qui annonce Server configured, listening on: port 8443. Un lecteur qui suit le tutoriel classique voit donc son service fonctionner, et en conclut, à tort, que SELinux ne pose pas de problème.

Pour reproduire le vrai refus, il faut choisir un port réellement absent de http_port_t. Le lab a pris le 8099, qui est étiqueté, mais dans un autre domaine (preupgrade_port_t). Cette fois, le démarrage échoue :

[systemctl restart httpd sur 8099 -> exit=1]
httpd[15735]: (13)Permission denied: AH00072: make_sock: could not bind to address [::]:8099
httpd[15735]: (13)Permission denied: AH00072: make_sock: could not bind to address 0.0.0.0:8099
httpd[15735]: no listening sockets available, shutting down

Deuxième correction, et elle fait perdre des heures : le message AH00072 est bien celui annoncé, mais il n'est pas dans /var/log/httpd/error_log. Le grep du lab y revient vide. L'erreur vit dans le journal systemd. Un administrateur qui fait un tail -f sur le fichier de log d'Apache, comme le réflexe le commande, ne voit strictement rien. Il faut passer par journalctl -u httpd. Le correctif, lui, ne désactive rien du tout :

Fenêtre de terminal
sudo semanage port -a -t http_port_t -p tcp 8099
sudo systemctl restart httpd

Après cette seule commande, le service démarre en code 0 et répond. Vous avez étendu la politique, pas contourné SELinux.

Deuxième piège, et celui-là est bien réel. Un site servi depuis /srv/www : le fichier existe, Apache tourne, la configuration est correcte, et pourtant 403 systématique. La cause se lit dans le contexte SELinux du fichier, que la plupart des administrateurs ne pensent pas à regarder :

Fenêtre de terminal
ls -Z /srv/www/index.html
curl -o /dev/null -w "HTTP=%{http_code}\n" http://127.0.0.1:8099/
unconfined_u:object_r:var_t:s0 /srv/www/index.html
HTTP=403

L'étiquette est var_t, ce n'est pas httpd_sys_content_t : le domaine httpd_t n'a pas le droit de lire ce type de fichier. Le correctif tient en deux commandes, et les deux sont indispensables :

Fenêtre de terminal
sudo semanage fcontext -a -t httpd_sys_content_t "/srv/www(/.*)?"
sudo restorecon -Rv /srv/www
Relabeled /srv/www from unconfined_u:object_r:var_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0
Relabeled /srv/www/index.html from unconfined_u:object_r:var_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0

Le lab obtient alors un HTTP 200. Retenez le piège dans le piège, mesuré et vérifié : semanage fcontext seul ne suffit pas. Cette commande écrit la règle mais ne réétiquette rien du tout. Sans restorecon, le 403 persiste, et on croit que la commande n'a pas fonctionné. C'est l'erreur classique, et elle mène droit au chmod 777, qui ne règle rien puisque le problème n'est pas dans les permissions Unix.

Troisième piège, incontournable dès qu'on lance des conteneurs. Un volume monté depuis l'hôte est refusé en lecture par SELinux, tant qu'il n'est pas étiqueté pour les conteneurs :

$ podman run --rm -v /srv/data:/data:ro alpine cat /data/fichier.txt
cat: can't open '/data/fichier.txt': Permission denied
[podman SANS :z -> exit=1]
$ podman run --rm -v /srv/data:/data:z alpine cat /data/fichier.txt
donnee-du-lab
[podman AVEC :z -> exit=0]

Le suffixe :z demande à Podman de réétiqueter le répertoire de l'hôte en container_file_t. Le lab a vérifié que le contexte de /srv/data a bien changé après coup, ce qui est exactement le point de vigilance.

Quand un service est bloqué et que la production attend, la tentation est de taper setenforce 0 et de passer à autre chose. C'est désarmer SELinux sur toute la machine, y compris sur les services qui n'ont rien demandé. Il existe une solution ciblée, et elle est réversible : passer un seul domaine en permissif.

Fenêtre de terminal
sudo semanage permissive -a httpd_t
getenforce
Enforcing

Lisez bien la sortie : le système reste en Enforcing, seul le domaine httpd_t est permissif. Vous débloquez Apache sans ouvrir le reste, et vous revenez en arrière avec semanage permissive -d httpd_t. Avant même d'en arriver là, la bonne démarche est de lire les refus, car SELinux vous dit précisément ce qu'il a bloqué :

Fenêtre de terminal
sudo ausearch -m avc -ts recent
sudo ausearch -m avc -ts recent | audit2why

ausearch liste les refus récents, et audit2why les traduit en langage compréhensible, en expliquant quelle règle ou quel booléen manque. C'est en général là que se trouve la réponse, en trente secondes.

La modularité est supprimée en 10, et le playbook casse

Section intitulée « La modularité est supprimée en 10, et le playbook casse »

Voici la rupture majeure d'AlmaLinux 10 pour qui gère un parc EL9 avec de l'automatisation. La modularité est le mécanisme qui permettait, sur EL8 et EL9, de choisir une version alternative d'un logiciel (dnf module enable nginx:1.24). Elle a disparu en EL10, et la démonstration est sans appel.

Sur le témoin AlmaLinux 9, la commande fonctionne parfaitement :

[a9 : dnf module enable nginx:1.24 -> exit=0]

Sur AlmaLinux 10, la même commande échoue :

[a10 : dnf module enable nginx:1.24 -> exit=1]
WARNING: modularity is deprecated, and functionality will be removed in a future release of DNF5.
Error: Problems in request:
missing groups or modules: nginx:1.24

Un rôle Ansible qui fait dnf module enable réussit sur AlmaLinux 9 (code 0) et échoue sur AlmaLinux 10 (code 1). La tâche passe donc en failed et le playbook s'arrête. Le même résultat est obtenu avec postgresql:16.

Le piège de diagnostic mérite d'être nommé, parce qu'il envoie chercher au mauvais endroit. Le message n'est pas « commande inconnue », ni « la modularité a été supprimée ». C'est missing groups or modules: nginx:1.24, qui ressemble à s'y méprendre à une faute de frappe dans le nom du flux. L'administrateur part alors chercher le bon nom de module, qui n'existe plus. Il faut avoir lu l'avertissement de dépréciation, deux lignes plus haut, pour comprendre ce qui se passe. Et rappelez-vous du point établi en début de guide : la commande dnf module existe encore (on est en dnf 4.20, pas en dnf5), elle ne fait simplement plus rien d'utile.

Le remplacement est un retour à des paquets parallèles, plus simple à raisonner : chaque version majeure est un paquet distinct, avec son nom propre.

Fenêtre de terminal
# Le choix de version se fait maintenant par le nom du paquet
sudo dnf install postgresql18-server
sudo dnf install php8.4
sudo dnf install nodejs24

Auditez vos rôles Ansible avant de migrer un parc : grep -rn "dnf module\|yum module" roles/ vous donne la liste des tâches à réécrire. C'est une correction mécanique, mais elle doit être faite avant le premier serveur, pas après.

Le piège x86-64 : l'hyperviseur, pas le vieux serveur

Section intitulée « Le piège x86-64 : l'hyperviseur, pas le vieux serveur »

C'est la trouvaille la plus spectaculaire du lab, et probablement le point qui vous fera perdre le plus de temps si vous ne le connaissez pas. AlmaLinux 10 exige x86-64-v3, un niveau d'instruction du processeur (correspondant grosso modo à un Intel Haswell, sorti en 2013), comme le reste de la génération EL10 ; elle fournit en plus une variante v2, ce qui la distingue de RHEL 10 et de Rocky 10. Mais le vrai piège n'est pas le vieux serveur que vous n'avez plus, il est dans votre hyperviseur.

Le lab a booté exactement la même image AlmaLinux 10, sur le même hôte physique, en changeant uniquement le modèle de CPU exposé par QEMU :

CPU émuléRésultat
kvm64 (le défaut de Proxmox)Fatal glibc error: CPU does not support x86-64-v2 puis kernel panic
Nehalem (antérieur à Haswell)Fatal glibc error: CPU does not support x86-64-v3 puis kernel panic
Haswell (premier modèle v3)boote jusqu'au a10 login:

Vous n'avez pas besoin d'un vieux serveur pour rencontrer ce problème : il suffit d'un type de CPU générique dans la configuration de la VM, et kvm64 est le défaut historique de Proxmox. Une image parfaitement saine, sur un hôte parfaitement moderne, ne démarre pas.

Ce que la console série révèle change complètement le diagnostic, et personne ne l'écrit. Voici les trois raisons pour lesquelles on cherche au mauvais endroit.

Premièrement, le noyau démarre parfaitement. Ce n'est pas le noyau qui refuse le processeur, c'est glibc, en espace utilisateur, qui tue init. La panique du noyau qui suit est une conséquence, pas la cause :

[ 0.940167] Run /init as init process
Fatal glibc error: CPU does not support x86-64-v2
[ 0.940904] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00007f00

Deuxièmement, le message se noie. La ligne qui explique tout passe au milieu d'un kernel panic, dans un flot de registres et de traces d'appels. Sur une console Proxmox, on voit la panique, et on part enquêter du côté du noyau, de l'image disque ou du bootloader. Le message qui donne la réponse tient sur une seule ligne, et il faut savoir qu'il est là.

Troisièmement, et c'est le plus retors : le niveau cité varie selon le CPU. Avec kvm64, l'erreur parle de v2 (le processeur émulé est en dessous de v2). Avec Nehalem, elle parle de v3. Autrement dit, chercher littéralement « x86-64-v3 » dans les logs peut ne rien donner, alors que vous êtes exactement en face du problème.

Détecter son niveau, et la conséquence sur un cluster

Section intitulée « Détecter son niveau, et la conséquence sur un cluster »

La commande qui répond à la question « de quel niveau dispose ma machine » est peu connue, et elle ne demande rien à installer. Le marqueur (supported, searched) désigne le plus haut niveau réellement supporté :

Fenêtre de terminal
/usr/bin/ld.so --help | grep -A6 "Subdirectories of glibc-hwcaps"
Subdirectories of glibc-hwcaps directories, in priority order:
x86-64-v4
x86-64-v3 (supported, searched)
x86-64-v2 (supported, searched)

Sur le CPU du lab, v3 est le plus haut niveau supporté : v4 est listé, mais non marqué, donc indisponible.

La conséquence opérationnelle sur un cluster est celle qu'il faut retenir, et elle est structurante. La parade évidente consiste à exposer le CPU réel de l'hôte (-cpu host en QEMU, « host » comme type de processeur sur Proxmox). Mais cette option interdit la migration à chaud entre des nœuds aux processeurs différents, puisque la VM se met à dépendre d'un jeu d'instructions précis. Donc : si vous voulez garder la migration à chaud dans un cluster hétérogène, tous les nœuds doivent être au moins x86-64-v3. C'est un prérequis d'infrastructure, à valider avant de choisir AlmaLinux 10, pas après.

AlmaLinux est le seul des RHEL-like à proposer une variante x86-64-v2, ce qui lui permet de tourner sur du matériel que RHEL 10 et Rocky 10 rejettent. Le lab a vérifié que les dépôts existent vraiment : interrogés depuis la VM, BaseOS, AppStream, CRB et extras en version v2 répondent tous HTTP 200.

Il faut dire tout aussi clairement ce que cette variante n'est pas, et le lab s'arrête là où sa preuve s'arrête. La variante v2 n'a pas été installée : le lab prouve que les dépôts sont en ligne, pas qu'un système v2 complet s'installe et se met à jour dans la durée. Les limites connues sont réelles : les éditeurs tiers ne construisent pas pour elle, et les modules ZFS précompilés font planter les machines v2 ; ELevate refuse de migrer vers la variante v2. Traitez-la pour ce qu'elle est : un filet de survie pour du matériel amorti, utile pour prolonger un parc, pas une plateforme de production sur laquelle bâtir un projet neuf.

dnf history undo : annuler une transaction, pour de vrai

Section intitulée « dnf history undo : annuler une transaction, pour de vrai »

Voici une capacité de dnf vérifiée plutôt que supposée. dnf est transactionnel de bout en bout : chaque opération reçoit un identifiant, et elle peut être annulée, dépendances comprises.

Fenêtre de terminal
sudo dnf -y install tree htop
dnf history list
sudo dnf -y history undo 6
rpm -q tree htop
7 | -y history undo 6 | 2026-07-13 07:13 | Removed | 4
6 | -y install tree htop | 2026-07-13 07:13 | Install | 4
package tree is not installed
package htop is not installed

Les paquets sont réellement désinstallés, ainsi que les quatre dépendances tirées au passage, et l'annulation est elle-même enregistrée comme une transaction (l'identifiant 7). La commande dnf history info donne le détail de n'importe quelle transaction passée, ce qui en fait un excellent outil de post-mortem après un incident. Le monde APT, lui, n'offre pas d'équivalent natif de cette annulation. Si vous exploitez des serveurs où une mise à jour ratée doit pouvoir être défaite en une commande, c'est un point à mettre au crédit d'AlmaLinux.

ELevate est l'outil de migration entre versions majeures, bâti sur leapp (le moteur de migration de Red Hat) et porté par CloudLinux pour fonctionner entre distributions EL. Le lab a joué la phase d'analyse, et c'est la seule phase dont il peut parler.

La commande leapp preupgrade analyse le système sans rien modifier, et produit un rapport. Dans le lab, elle va au bout et sort en code 1 : la migration est inhibée.

Upgrade has been inhibited due to the following problems:
Inhibitors: 2
A report has been generated at /var/log/leapp/leapp-report.txt
--- leapp preupgrade exit=1

Le rapport contient sept entrées, dont deux inhibiteurs qui bloquent la migration tant qu'ils ne sont pas traités :

RisqueConstat
high (inhibiteur)Newest installed kernel not in use
high (inhibiteur)Legacy network configuration found (/etc/sysconfig/network-scripts/ifcfg-eth0)
highGRUB2 core will be automatically updated during the upgrade
mediumBerkeley DB (libdb) has been detected on your system
lowSELinux will be set to permissive mode
lowSome enabled RPM repositories are unknown to Leapp (elevate)
infoSELinux relabeling will be scheduled

L'inhibiteur ifcfg est le plus intéressant, parce qu'il concerne toutes les machines EL9 : l'image cloud AlmaLinux 9 livre encore un fichier /etc/sysconfig/network-scripts/ifcfg-eth0, un format hérité que RHEL 10 ignore. Non traité, il donne une machine sans réseau après migration, ce qui est le pire scénario possible sur un serveur distant. Le remède est donné par leapp lui-même :

Fenêtre de terminal
sudo nmcli connection migrate /etc/sysconfig/network-scripts/ifcfg-eth0

Le second inhibiteur mérite une mise en garde d'honnêteté : « Newest installed kernel not in use » est en partie un artefact de la séquence du lab, qui enchaîne dnf upgrade (lequel installe un noyau plus récent) et leapp preupgrade sans redémarrage intermédiaire. Un lab plus propre aurait redémarré avant. Cela dit, c'est exactement la séquence qu'un administrateur pressé va jouer, et il rencontrera donc le même blocage. La parade est triviale : redémarrer sur le noyau le plus récent avant de lancer leapp.

Ce que le lab n'a pas fait, et ce que dit le terrain

Section intitulée « Ce que le lab n'a pas fait, et ce que dit le terrain »

Soyons net sur la limite : le lab n'a pas joué leapp upgrade, seulement leapp preupgrade. Le déroulé complet (transaction RPM, régénération de l'initramfs, GRUB, redémarrage) n'est pas validé ici. Aucune conclusion de ce guide ne repose sur une migration menée à son terme.

Ce que rapportent les retours de terrain, en revanche, dessine un profil de risque clair. Sur une VM standard, sans exotisme, la migration passe. Mais un échec complet est documenté en production, sur une machine combinant un panneau de contrôle d'hébergement et un noyau tiers (KernelCare) : le système est resté hybride EL9/EL10, aucune entrée initramfs n'était présente dans GRUB, et seule la restauration d'un instantané a permis de récupérer la machine. Le combo mortel est là : panneau de contrôle plus noyau tiers. Si votre serveur porte l'un ou l'autre, ne migrez pas en place.

Il faut d'ailleurs dire que dans la culture EL, la migration en place reste minoritaire. Le réflexe dominant est « reconstruis plutôt que migrer » : on provisionne une machine neuve en 10, on y rejoue son infrastructure as code, on bascule le trafic, on garde l'ancienne quelques jours. C'est plus long à écrire la première fois, et infiniment plus sûr que de jouer une migration en place sur un serveur de production.

Compatibilité, licences et gouvernance : ce qu'il faut savoir avant de choisir

Section intitulée « Compatibilité, licences et gouvernance : ce qu'il faut savoir avant de choisir »

Ce contexte n'est pas de la politique, il conditionne un choix d'entreprise. Il mérite d'être présenté factuellement, sans prendre parti, pour que vous puissiez décider vous-même.

Depuis juillet 2023, AlmaLinux ne vise plus la compatibilité « 1:1, bug-for-bug » avec RHEL, mais la compatibilité ABI (Application Binary Interface : un binaire compilé pour RHEL fonctionne sur AlmaLinux). C'est un changement réel, et il a fait beaucoup de bruit à l'époque.

N'écrivez pas « AlmaLinux n'est plus compatible RHEL » : c'est faux. Trois ans après, le constat le plus honnête est que c'est devenu un non-événement. Il n'existe aucun cas documenté de logiciel cassé par cet écart. Le signal le plus parlant est d'ailleurs l'absence de signal : le sujet est mort sur les forums, ce qui, pour une controverse de cette ampleur, en dit long.

La contrepartie de cette liberté est réelle et documentée, et elle joue plutôt en faveur d'AlmaLinux. Ne dépendant plus du calendrier de Red Hat, la distribution corrige parfois des failles avant lui. Un rapport de sécurité indépendant publié en mai 2026, portant sur une vulnérabilité noyau à exploit public, relevait qu'AlmaLinux disposait de noyaux corrigés le jour même, quand Ubuntu, RHEL, SUSE, Debian, Oracle et Rocky étaient encore marqués « en cours ». AlmaLinux a par ailleurs réintroduit plus de 150 périphériques retirés en amont par Red Hat, ce qui prolonge la vie de matériel encore parfaitement fonctionnel.

Le vrai coût du choix est contractuel, pas technique

Section intitulée « Le vrai coût du choix est contractuel, pas technique »

Voici le point que les comparatifs techniques manquent systématiquement, et c'est pourtant la vraie raison pour laquelle des entreprises paient RHEL. La certification logicielle (ISV) d'AlmaLinux n'existe pas encore : elle est annoncée comme « coming soon ».

Traduisez ce que cela signifie en pratique. Un logiciel certifié pour RHEL (un ERP, une base de données propriétaire, un progiciel métier) fonctionnera sur AlmaLinux, puisque l'ABI est compatible. Mais l'éditeur ne le supportera pas. Si vous ouvrez un ticket, la première question sera votre distribution, et la réponse sera de reproduire le problème sur RHEL. Le coût du choix n'est donc pas technique, il est contractuel. Pour un serveur web, un cluster de conteneurs ou une infrastructure maison, cela ne change rien. Pour une machine qui porte un progiciel critique sous contrat de support, cela change tout.

AlmaLinux est portée par une fondation 501(c)(6) (une structure sans but lucratif de droit américain), dont le conseil d'administration est élu, avec un garde-fou inscrit dans les statuts : aucun employeur ne peut détenir plus d'un siège votant. C'est une protection réelle contre la capture du projet par une entreprise unique.

Le contrepoint doit être posé avec la même netteté : CloudLinux a créé la fondation, la finance à hauteur d'environ un million de dollars par an, et vend le support commercial via TuxCare. La dépendance financière est donc réelle, même si le contrôle est contré statutairement. Ce sont deux faits, et ils coexistent. Chacun en tirera la conclusion qui correspond à son niveau de tolérance au risque.

Quant à Rocky Linux, l'autre grand RHEL-like, il revendique le bug-for-bug et suit RHEL sur le matériel : v3 obligatoire, pas de variante v2. C'est une position différente, ni meilleure ni pire ; elle sera préférable si votre exigence est la conformité stricte à RHEL, et pénalisante si votre parc contient des machines pré-Haswell. Enfin, un point de vocabulaire qui traîne partout : n'écrivez jamais « Red Hat viole la GPL ». Ni la Software Freedom Conservancy ni la Free Software Foundation ne l'affirment ; elles parlent d'une pratique contraire à l'esprit de la licence, et seul un tribunal pourrait trancher. Le sujet mérite une neutralité stricte.

Ce tableau regroupe les symptômes les plus fréquents sur une AlmaLinux 10 neuve ou migrée. Cherchez-y avant de partir en investigation : dans la grande majorité des cas, le coupable est l'un des changements documentés plus haut, pas un bug de votre application.

SymptômeCause probableSolution
Kernel panic au boot d'une VM, image saineCPU exposé inférieur à x86-64-v3 (kvm64 par défaut sur Proxmox)Passer le type de CPU à Haswell ou plus récent ; chercher Fatal glibc error dans la console série
Attempted to kill init! sans autre indiceC'est glibc qui tue init, pas le noyauMême cause que ci-dessus ; le niveau cité varie (v2 ou v3) selon le CPU
missing groups or modules: nginx:1.24La modularité est supprimée en EL10Utiliser les paquets parallèles (postgresql18-server, php8.4, nodejs24)
Playbook Ansible en échec sur dnf moduleSort en code 1 sur Alma 10, en 0 sur Alma 9Réécrire la tâche ; auditer avec grep -rn "dnf module" roles/
No matching Packages sur redisredis n'existe plus dans EL10Installer valkey, le remplaçant dans AppStream
No matching Packages sur fail2ban ou certbotIls sont dans EPEL, pas dans AlmaLinuxdnf install epel-release, en sachant qu'EPEL n'a aucun SLA
httpd ne démarre pas sur un port customSELinux refuse le bind (AH00072)semanage port -a -t http_port_t -p tcp <port> ; lire journalctl -u httpd, pas error_log
403 sur un DocumentRoot hors /var/wwwContexte SELinux var_t au lieu de httpd_sys_content_tsemanage fcontext -a … puis restorecon -Rv (le premier seul ne suffit pas)
Permission denied dans un volume PodmanVolume non étiqueté pour les conteneursAjouter :z au montage, jamais sur /home, /etc, /usr ou /var
Service bloqué, cause inconnueRefus SELinux non luausearch -m avc -ts recent | audit2why ; en urgence, semanage permissive -a <domaine>
firewalld apparaît sans qu'on l'ait installéTiré en dépendance de fail2ban (EPEL) depuis BaseOSNormal ; il est installé mais inactif. Le démarrer sciemment, ou le retirer
leapp preupgrade sort en code 1Inhibiteurs dans le rapportLire /var/log/leapp/leapp-report.txt ; traiter ifcfg avec nmcli connection migrate
Pas de réseau après une migration ELevateConfiguration réseau héritée (ifcfg-*) ignorée par EL10Migrer les profils avant avec nmcli connection migrate
  • AlmaLinux 10 « Lavender Lion » offre dix ans de correctifs de sécurité gratuits (actif jusqu'au 31 mai 2030, sécurité jusqu'au 31 mai 2035), sans souscription ni offre payante. La nuance obligatoire : pas d'EUS gratuit, il faut suivre les versions mineures.
  • La frontière de couverture est AppStream contre EPEL. Le serveur web, la base, le cache et les conteneurs sont couverts ; fail2ban et certbot viennent d'EPEL (Vendor: Fedora Project), hors engagement de sécurité. Docker est hors distribution, et redis n'existe plus : c'est valkey.
  • Trois comportements fiables pour vos scripts : /tmp reste sur le disque et survit au redémarrage, /etc/sysctl.conf est lu au boot, et last/lastb/lastlog sont présentes avec un btmp alimenté.
  • Du GNU, en C, sans surprise : sudo 1.9.17p2 et GNU coreutils 9.5, et aucune réécriture Rust au catalogue. rpm --import n'est pas déprécié : chaque dépôt déclare sa propre clé, il n'y a pas de trousseau unique.
  • AlmaLinux n'appelle personne : 0 paquet au repos, 4 paquets NTP pendant trois connexions SSH, pas de MOTD dynamique, pas d'insights-client.
  • SELinux est en Enforcing, mais aucun pare-feu n'est installé sur l'image cloud : la légende du « firewalld actif par défaut » est fausse en cloud (l'ISO, non testée ici, se comporte autrement).
  • Le piège SELinux n'est pas celui qu'on raconte : 8443 est déjà autorisé, donc l'exemple classique ne démontre rien. Et l'erreur AH00072 vit dans le journal systemd, pas dans error_log. Sur un DocumentRoot custom, semanage fcontext seul ne suffit pas : il faut restorecon.
  • La modularité est supprimée : dnf module enable sort en code 1 sur Alma 10 (0 sur Alma 9), donc le playbook casse. Le choix de version passe par des paquets parallèles. Fait qui contredit la doc : Alma 10 n'est pas en dnf5, elle livre dnf 4.20.
  • Le piège x86-64 est dans l'hyperviseur, pas dans le vieux serveur : kvm64 (défaut de Proxmox) donne un kernel panic. C'est glibc qui tue init, le message se noie dans la panique, et le niveau cité varie (v2 ou v3). Dans un cluster, tous les nœuds doivent être au moins v3 pour garder la migration à chaud.
  • Le vrai coût du choix est contractuel : la certification ISV d'AlmaLinux n'existe pas encore. Un logiciel certifié RHEL fonctionnera, mais l'éditeur ne le supportera pas.

Ce guide croise un lab en machine virtuelle et les publications officielles. Les liens ci-dessous permettent de vérifier chaque affirmation à la source, et de suivre les points encore mouvants, en particulier la certification ISV et la maturité d'ELevate vers EL10.

Le cycle de vie et le modèle de support, cœur de l'argument de cette page :

Ce qui n'est pas couvert par AlmaLinux, à lire avant de bâtir une architecture :

  • Le projet EPEL : la documentation qui pose l'absence d'engagement, dans les termes du projet lui-même (« if it breaks, you get to keep both pieces »). C'est la source de la frontière AppStream/EPEL décrite ici.
  • ELevate, la migration entre versions majeures : la procédure officielle, les prérequis, et la liste des cas non pris en charge. À lire intégralement avant toute migration en place.

Le paysage RHEL-like, pour situer AlmaLinux dans sa famille :

  • Rocky Linux : l'autre RHEL-like, qui revendique le bug-for-bug et suit RHEL sur le matériel (donc v3 obligatoire, pas de variante v2).

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn