identité : Keycloak 26.7.5, oauth2-proxy v7.15.5 ; les rôles savent monter
- serveur_keycloak : une montée remplace la distribution (arrêt, retrait, extraction) au lieu de construire les anciens fichiers sous le nouveau repère - serveur_oauth2_proxy : repère = version du binaire ; empreinte SHA-256 épinglée, archive refusée et retirée du cache si elle diffère - CHANGELOG 67 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
715f9de84d
commit
16675037f5
5 changed files with 169 additions and 13 deletions
40
CHANGELOG.md
40
CHANGELOG.md
|
|
@ -1,5 +1,45 @@
|
|||
# CHANGELOG — Set-OPS
|
||||
|
||||
## 2026-10-03 (67) — Keycloak 26.7.5 et oauth2-proxy v7.15.5 ; deux montées qui n'auraient rien monté
|
||||
|
||||
**Demande de l'exploitant** : mettre à jour Keycloak et oauth2-proxy, premiers du relevé des
|
||||
logiciels en retard (Keycloak 26.7.1 : quatre correctifs de retard, chacun corrigeant plusieurs
|
||||
CVE ; oauth2-proxy v7.15.3 : deux, tous deux de sécurité).
|
||||
|
||||
**Deux défauts trouvés en préparant, avant tout déploiement — les deux rôles ne savaient pas
|
||||
MONTER.** Ils ne faisaient jusque-là que des premières installations.
|
||||
- **oauth2-proxy** décidait sur la seule PRÉSENCE du binaire : changer la version sur une
|
||||
machine installée ne faisait rien. Le rôle demande désormais sa version au binaire.
|
||||
- **Keycloak** avait un repère par version (`.kc-built-<version>`), mais l'extraction portait
|
||||
`creates: bin/kc.sh` : sautée, puis `kc.sh build` sur les ANCIENS fichiers, puis repère de
|
||||
la NOUVELLE version — la machine se serait dite en 26.7.5 en restant en 26.7.1. Et extraire
|
||||
par-dessus ne suffit pas : les bibliothèques portent leur version dans leur nom, les deux
|
||||
générations auraient coexisté. Lors d'une montée, le rôle arrête Keycloak, retire la
|
||||
distribution précédente (`data/` gardée), extrait, puis repose sa configuration et son
|
||||
thème comme à l'installation.
|
||||
|
||||
**oauth2-proxy installait sans rien vérifier.** Empreinte SHA-256 de l'archive écrite dans le
|
||||
rôle (`serveur_oauth2_proxy_sha256`), après relecture : la somme publiée par le projet
|
||||
recalculée sur l'archive. Une archive qui ne la porte pas — dépôt du site ou Internet — est
|
||||
retirée du cache et refusée. Keycloak, lui, vérifiait déjà sa signature PGP : 26.7.5 est signée
|
||||
par la clé épinglée (`861AB50E…`), contrôlé avant déploiement.
|
||||
|
||||
**Appliqué** : dépôt de binaires du site garni des deux versions (les runners n'auront pas à
|
||||
sortir) ; puis les deux locataires. Relu chez chacun : Keycloak 26.7.5 démarré en 6 s après la
|
||||
mise à jour automatique de sa base, aucune bibliothèque 26.7.1 restante, aucune erreur ;
|
||||
oauth2-proxy v7.15.5 sur `mon-01` et `ops-01` ; vigie et console renvoient vers la connexion
|
||||
Keycloak, issuer juste ; sondes `identite`, `passerelle`, `vigie`, `console-ops` au vert.
|
||||
Interruption de l'identité : environ une minute par locataire, pendant le remplacement.
|
||||
|
||||
**À savoir** : le rôle Keycloak n'est pas simulable jusqu'au bout — `courriel-realm.yml`
|
||||
échoue en `--check` faute de jeton d'administration, avec ou sans ce changement. L'extraction
|
||||
est sautée en simulation (l'archive n'y est pas copiée).
|
||||
|
||||
**Vu au passage** : `web-dorsal-01` (Chezlepro) rapporte une sauvegarde VIDE depuis la
|
||||
reconstruction du 2026-10-01 — légitime s'il n'héberge encore aucun site, à confirmer.
|
||||
|
||||
**Validation** : `ansible-lint` (0 violation), `make verifier` conforme (83/83).
|
||||
|
||||
## 2026-10-03 (66) — Les épingles tiennent, cache ou pas
|
||||
|
||||
**Demande de l'exploitant** : faire respecter les épingles de `paquets-tiers.yml`.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
---
|
||||
# Distribution Keycloak (Quarkus). Verifier/ajuster la version sur keycloak.org/downloads.
|
||||
serveur_keycloak_version: "26.7.1"
|
||||
# 26.7.5 (2026-10-03) : quatre versions de correctifs apres 26.7.1, chacune corrigeant
|
||||
# plusieurs CVE. La branche 26.8 existe ; on reste sur la correction de la meme branche.
|
||||
serveur_keycloak_version: "26.7.5"
|
||||
serveur_keycloak_url: "https://github.com/keycloak/keycloak/releases/download/{{ serveur_keycloak_version }}/keycloak-{{ serveur_keycloak_version }}.tar.gz"
|
||||
serveur_keycloak_java_paquet: "default-jre-headless"
|
||||
|
||||
|
|
@ -204,7 +206,7 @@ serveur_keycloak_cache_local: "{{ setops_cache_artefacts | default(lookup('env',
|
|||
# d'authenticite compte le plus.
|
||||
#
|
||||
# Continuite constatee le 2026-08-10 : cette meme cle a signe 26.0.7 (la version alors en
|
||||
# production), 26.3.0, 26.6.2 et 26.7.1.
|
||||
# production), 26.3.0, 26.6.2 et 26.7.1 — puis 26.7.5, verifiee le 2026-10-03.
|
||||
#
|
||||
# ANCRE (2026-08-11) — l'empreinte est PUBLIEE PAR LE PROJET sur https://www.keycloak.org/keys,
|
||||
# sous l'UID « Keycloak Bot <keycloak.bot@gmail.com> ». Ce canal (keycloak.org) est
|
||||
|
|
|
|||
|
|
@ -226,6 +226,58 @@
|
|||
mode: "0644"
|
||||
when: not serveur_keycloak_archive_present.stat.exists
|
||||
|
||||
# UNE NOUVELLE VERSION REMPLACE L'ANCIENNE, ELLE NE S'Y SUPERPOSE PAS (2026-10-03).
|
||||
#
|
||||
# L'extraction portait `creates: bin/kc.sh` : sur une machine deja installee, elle etait
|
||||
# SAUTEE. `kc.sh build` tournait alors sur les anciens fichiers, puis posait le repere de la
|
||||
# NOUVELLE version — la machine se serait dite en 26.7.5 en restant en 26.7.1. Trouve en
|
||||
# preparant cette montee, avant tout deploiement.
|
||||
#
|
||||
# Et extraire par-dessus ne suffit pas : les bibliotheques portent leur version dans leur
|
||||
# nom (`lib/lib/main/*-26.7.1.jar`), les deux generations coexisteraient sur le classpath.
|
||||
# On retire donc la distribution precedente. Ce que le role pose lui-meme dans ce
|
||||
# repertoire — `conf/keycloak.conf`, le theme, le repere — l'est APRES l'extraction ; on ne
|
||||
# garde que `data/` (fichiers de travail) et le repertoire de travail d'Ansible.
|
||||
- name: Une autre version est-elle en place ?
|
||||
ansible.builtin.stat:
|
||||
path: "{{ serveur_keycloak_home }}/bin/kc.sh"
|
||||
register: serveur_keycloak_distribution
|
||||
when: not serveur_keycloak_archive_present.stat.exists
|
||||
|
||||
- name: Mise a jour — arreter Keycloak avant de remplacer sa distribution
|
||||
ansible.builtin.systemd:
|
||||
name: "{{ serveur_keycloak_service }}"
|
||||
state: stopped
|
||||
when:
|
||||
- not serveur_keycloak_archive_present.stat.exists
|
||||
- serveur_keycloak_distribution.stat.exists | default(false)
|
||||
|
||||
- name: Mise a jour — retirer la distribution precedente (data/ gardee)
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- find
|
||||
- "{{ serveur_keycloak_home }}"
|
||||
- -mindepth
|
||||
- "1"
|
||||
- -maxdepth
|
||||
- "1"
|
||||
- "!"
|
||||
- -name
|
||||
- data
|
||||
- "!"
|
||||
- -name
|
||||
- .ansible
|
||||
- -exec
|
||||
- rm
|
||||
- -rf
|
||||
- --
|
||||
- "{}"
|
||||
- +
|
||||
changed_when: true
|
||||
when:
|
||||
- not serveur_keycloak_archive_present.stat.exists
|
||||
- serveur_keycloak_distribution.stat.exists | default(false)
|
||||
|
||||
- name: Extraire Keycloak
|
||||
ansible.builtin.unarchive:
|
||||
src: "/tmp/keycloak-{{ serveur_keycloak_version }}.tar.gz"
|
||||
|
|
@ -234,7 +286,10 @@
|
|||
extra_opts: ["--strip-components=1"]
|
||||
owner: "{{ serveur_keycloak_utilisateur }}"
|
||||
group: "{{ serveur_keycloak_utilisateur }}"
|
||||
creates: "{{ serveur_keycloak_home }}/bin/kc.sh"
|
||||
# En simulation, l'archive n'a pas ete copiee dans /tmp : rien a extraire.
|
||||
when:
|
||||
- not serveur_keycloak_archive_present.stat.exists
|
||||
- not ansible_check_mode
|
||||
|
||||
- name: Deployer keycloak.conf (config non sensible)
|
||||
ansible.builtin.template:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,15 @@
|
|||
# application sans OIDC natif. L'app reçoit l'utilisateur via en-têtes (auth « external »).
|
||||
# Binaire Go statique depuis les releases GitHub (pas d'apt). Requiert client_pki (confiance
|
||||
# step_ca pour joindre Keycloak) + résolution de l'hôte Keycloak.
|
||||
serveur_oauth2_proxy_version: "v7.15.3"
|
||||
# v7.15.5 (2026-10-03) : deux versions de correctifs apres v7.15.3, toutes deux de securite.
|
||||
serveur_oauth2_proxy_version: "v7.15.5"
|
||||
# L'EMPREINTE DE L'ARCHIVE, ECRITE ICI ET NON LUE A COTE DU TELECHARGEMENT (2026-10-03).
|
||||
# Le role installait le binaire de la passerelle SSO sans rien verifier. La somme publiee
|
||||
# par le projet (`*-sha256sum.txt`, meme canal que l'archive) a ete recalculee sur l'archive
|
||||
# le jour meme ; l'ecrire dans le depot fige ce qui a ete relu, et une archive remplacee
|
||||
# plus tard — sur GitHub ou dans le depot de binaires du site — est REFUSEE.
|
||||
# Changer de version = changer cette ligne, apres la meme relecture.
|
||||
serveur_oauth2_proxy_sha256: "f63f94bf72c5f46ab002a0a275aa8b3cf19b4d828aed08a13978cb9a62c3a1fd"
|
||||
serveur_oauth2_proxy_archive: "oauth2-proxy-{{ serveur_oauth2_proxy_version }}.linux-amd64.tar.gz"
|
||||
serveur_oauth2_proxy_url: >-
|
||||
https://github.com/oauth2-proxy/oauth2-proxy/releases/download/{{
|
||||
|
|
|
|||
|
|
@ -63,10 +63,23 @@
|
|||
# dans /tmp : /tmp se vide, et elle repartait du controleur a chaque deploiement (`changed`
|
||||
# sans raison). Le binaire est exactement ce que l'extraction attend (`creates`) : present,
|
||||
# il n'y a rien a apporter. Meme correction que `serveur_keycloak`.
|
||||
#
|
||||
# LA VERSION, PAS LA SEULE PRESENCE (2026-10-03). Le repere etait l'existence du binaire :
|
||||
# changer `serveur_oauth2_proxy_version` sur une machine deja installee ne faisait RIEN —
|
||||
# ni telechargement, ni extraction. On demande donc au binaire sa version.
|
||||
- name: Quelle version d'oauth2-proxy est en place ?
|
||||
ansible.builtin.command:
|
||||
argv: ["{{ serveur_oauth2_proxy_binaire }}", "--version"]
|
||||
register: serveur_oauth2_proxy_version_posee
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
check_mode: false
|
||||
|
||||
- name: L artefact de cette version est-il deja pose ?
|
||||
ansible.builtin.stat:
|
||||
path: "{{ serveur_oauth2_proxy_binaire }}"
|
||||
register: serveur_oauth2_proxy_archive_present
|
||||
ansible.builtin.set_fact:
|
||||
serveur_oauth2_proxy_a_jour: >-
|
||||
{{ (serveur_oauth2_proxy_version_posee.rc | default(1) == 0)
|
||||
and ((serveur_oauth2_proxy_version ~ ' ') in (serveur_oauth2_proxy_version_posee.stdout | default('') ~ ' ')) }}
|
||||
|
||||
# Le controleur telecharge, puis pousse par SSH — la cible ne tire jamais d'Internet.
|
||||
# Motif explique en detail dans `roles/serveur_nextcloud/tasks/installer.yml`.
|
||||
|
|
@ -77,7 +90,7 @@
|
|||
mode: "0700"
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
when: not serveur_oauth2_proxy_archive_present.stat.exists
|
||||
when: not (serveur_oauth2_proxy_a_jour | bool)
|
||||
|
||||
# --- LE DEPOT DU SITE D'ABORD, L'INTERNET ENSUITE (2026-09-12) ----------------
|
||||
#
|
||||
|
|
@ -102,7 +115,7 @@
|
|||
failed_when: false
|
||||
when:
|
||||
- setops_depot_binaires | default('') | length > 0
|
||||
- not serveur_oauth2_proxy_archive_present.stat.exists
|
||||
- not (serveur_oauth2_proxy_a_jour | bool)
|
||||
|
||||
- name: L artefact est-il déjà dans le cache du contrôleur ?
|
||||
ansible.builtin.stat:
|
||||
|
|
@ -110,7 +123,7 @@
|
|||
register: serveur_oauth2_proxy_cache_present
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
when: not serveur_oauth2_proxy_archive_present.stat.exists
|
||||
when: not (serveur_oauth2_proxy_a_jour | bool)
|
||||
|
||||
- name: Télécharger oauth2-proxy dans le cache du contrôleur (une seule fois)
|
||||
ansible.builtin.get_url:
|
||||
|
|
@ -120,15 +133,50 @@
|
|||
delegate_to: localhost
|
||||
become: false
|
||||
when:
|
||||
- not serveur_oauth2_proxy_archive_present.stat.exists
|
||||
- not (serveur_oauth2_proxy_a_jour | bool)
|
||||
- not (serveur_oauth2_proxy_cache_present.stat.exists | default(false))
|
||||
|
||||
# QUELLE QUE SOIT LA PROVENANCE — depot du site ou Internet — l'archive du cache doit avoir
|
||||
# l'empreinte relue (defaults/main.yml). Une archive qui ne l'a pas est retiree du cache,
|
||||
# pour ne pas la reproposer au passage suivant.
|
||||
- name: Mesurer l'archive oauth2-proxy du cache
|
||||
ansible.builtin.stat:
|
||||
path: "{{ serveur_oauth2_proxy_cache_local }}/oauth2-proxy-{{ serveur_oauth2_proxy_version }}.tar.gz"
|
||||
checksum_algorithm: sha256
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
register: serveur_oauth2_proxy_archive_mesuree
|
||||
when: not (serveur_oauth2_proxy_a_jour | bool)
|
||||
|
||||
- name: Retirer du cache une archive dont l'empreinte ne correspond pas
|
||||
ansible.builtin.file:
|
||||
path: "{{ serveur_oauth2_proxy_cache_local }}/oauth2-proxy-{{ serveur_oauth2_proxy_version }}.tar.gz"
|
||||
state: absent
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
when:
|
||||
- not (serveur_oauth2_proxy_a_jour | bool)
|
||||
- serveur_oauth2_proxy_archive_mesuree.stat.exists | default(false)
|
||||
- serveur_oauth2_proxy_archive_mesuree.stat.checksum | default('') != serveur_oauth2_proxy_sha256
|
||||
|
||||
- name: Refuser une archive oauth2-proxy dont l'empreinte ne correspond pas
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- serveur_oauth2_proxy_archive_mesuree.stat.checksum | default('') == serveur_oauth2_proxy_sha256
|
||||
fail_msg: >-
|
||||
L'archive oauth2-proxy {{ serveur_oauth2_proxy_version }} n'a pas l'empreinte relue
|
||||
({{ serveur_oauth2_proxy_sha256[:12] }}…) : obtenue
|
||||
{{ (serveur_oauth2_proxy_archive_mesuree.stat.checksum | default('absente'))[:12] }}.
|
||||
Elle a ete retiree du cache. Ne pas contourner : relire la publication avant de
|
||||
changer l'empreinte.
|
||||
when: not (serveur_oauth2_proxy_a_jour | bool)
|
||||
|
||||
- name: Déposer oauth2-proxy sur l hôte depuis le cache
|
||||
ansible.builtin.copy:
|
||||
src: "{{ serveur_oauth2_proxy_cache_local }}/oauth2-proxy-{{ serveur_oauth2_proxy_version }}.tar.gz"
|
||||
dest: "/tmp/oauth2-proxy-{{ serveur_oauth2_proxy_version }}.tar.gz"
|
||||
mode: "0644"
|
||||
when: not serveur_oauth2_proxy_archive_present.stat.exists
|
||||
when: not (serveur_oauth2_proxy_a_jour | bool)
|
||||
|
||||
- name: Extraire le binaire oauth2-proxy
|
||||
ansible.builtin.unarchive:
|
||||
|
|
@ -139,7 +187,10 @@
|
|||
owner: root
|
||||
group: root
|
||||
mode: "0755"
|
||||
creates: "{{ serveur_oauth2_proxy_binaire }}"
|
||||
# En simulation, l'archive n'a pas ete copiee dans /tmp : rien a extraire.
|
||||
when:
|
||||
- not (serveur_oauth2_proxy_a_jour | bool)
|
||||
- not ansible_check_mode
|
||||
notify: Redémarrer oauth2-proxy
|
||||
|
||||
- name: Créer le répertoire de configuration
|
||||
|
|
|
|||
Loading…
Reference in a new issue