oauth2-proxy fonctionne devant Icinga Web 2 : 302 vers Keycloak, qui federe LDAP. Quatre defauts leves, dont trois du meme motif — un nom construit par convention d'un cote, declare de l'autre. 1. Le secret de cookie etait en base64 STANDARD. oauth2-proxy decode en url-safe : le decodage echoue, il retombe sur la chaine brute et se plaint de sa LONGUEUR, jamais de l'encodage. Garde ajoutee qui refuse + et /. 2. L'issuer etait fabrique (`keycloak.<domaine>`), un nom que rien ne publie. Le plan expose `auth.<domaine>` — c'est ce nom que le DNS resout et que nginx sert. Derive desormais du champ `expose`. 3. Keycloak s'annoncait sous ce meme nom invente : « issuer did not match ». Meme correctif a la source. 4. Le pare-feu est-ouest bloquait l'edge : nginx ne declarait son 443 qu'avec `pair: externe`, que le devis est-ouest saute (il releve de la frontiere). Le flux existait d'un seul cote et la matrice etait satisfaite. nginx declare maintenant aussi son 443 depuis la flotte. obs-01 et mon-01 deployees. 7 cibles Prometheus up, scrutees en TLS a travers cinq zones du VRF. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
108 lines
4.2 KiB
YAML
108 lines
4.2 KiB
YAML
---
|
|
# L'ISSUER SE DERIVE DE L'EXPOSITION DECLAREE, il ne s'invente pas. Le defaut fabriquait
|
|
# `https://keycloak.<domaine>` par convention de nommage — un nom que rien ne publie : le
|
|
# plan expose Keycloak sous `auth.<domaine>`, et c'est ce nom-la que PowerDNS resout et
|
|
# que nginx sert. Resultat le 2026-08-07 : `lookup keycloak.chezlepro.internal : no such
|
|
# host`, et oauth2-proxy redemarrait en boucle.
|
|
#
|
|
# Le champ `expose` est deja la source pour PowerDNS, nginx et /etc/hosts. C'est la
|
|
# quatrieme fois qu'on le lit : une convention de nommage se contredit, une declaration
|
|
# se corrige.
|
|
- name: Charger les registres applications et domaines (expositions)
|
|
ansible.builtin.include_vars:
|
|
file: "{{ item }}"
|
|
loop:
|
|
- "{{ setops_plan_dir }}/applications.yml"
|
|
- "{{ setops_plan_dir }}/domaines.yml"
|
|
when: serveur_oauth2_proxy_issuer_derive | bool
|
|
|
|
- name: Dériver l'issuer depuis l'exposition de Keycloak
|
|
ansible.builtin.set_fact:
|
|
serveur_oauth2_proxy_issuer: >-
|
|
https://{{ (applications | default({})).get(serveur_oauth2_proxy_app_idp, {}).get('expose', []) | first }}/realms/{{ serveur_oauth2_proxy_realm }}
|
|
when:
|
|
- serveur_oauth2_proxy_issuer_derive | bool
|
|
- ((applications | default({})).get(serveur_oauth2_proxy_app_idp, {}).get('expose', []) | length) > 0
|
|
|
|
- name: Exiger la configuration OIDC (client, secret, redirect, upstream, cookie)
|
|
ansible.builtin.assert:
|
|
that:
|
|
- serveur_oauth2_proxy_client_id | length > 0
|
|
- serveur_oauth2_proxy_client_secret | length > 0
|
|
- serveur_oauth2_proxy_redirect_url | length > 0
|
|
- serveur_oauth2_proxy_upstream | length > 0
|
|
- serveur_oauth2_proxy_cookie_secret | length > 0
|
|
fail_msg: "client_id, client_secret (voûte), redirect_url, upstream et cookie_secret (voûte) requis."
|
|
|
|
# Garde d'ENCODAGE, distincte de la garde de présence : un secret présent mais en base64
|
|
# standard fait redémarrer oauth2-proxy en boucle, avec un message qui parle de longueur
|
|
# et jamais d'encodage. Mieux vaut refuser ici, où la cause est nommable.
|
|
- name: Refuser un cookie_secret qui n'est pas du base64 url-safe
|
|
ansible.builtin.assert:
|
|
that:
|
|
- "'+' not in serveur_oauth2_proxy_cookie_secret"
|
|
- "'/' not in serveur_oauth2_proxy_cookie_secret"
|
|
fail_msg: >-
|
|
`vault_oauth2_cookie` contient `+` ou `/` : c'est du base64 STANDARD. oauth2-proxy
|
|
décode en base64 URL-SAFE et retombera sur la chaîne brute, dont la longueur sera
|
|
refusée. Régénérer : openssl rand -base64 32 | tr '+/' '-_'
|
|
|
|
- name: Créer l'utilisateur système oauth2-proxy
|
|
ansible.builtin.user:
|
|
name: "{{ serveur_oauth2_proxy_utilisateur }}"
|
|
system: true
|
|
shell: /usr/sbin/nologin
|
|
create_home: false
|
|
|
|
- name: Télécharger oauth2-proxy
|
|
ansible.builtin.get_url:
|
|
url: "{{ serveur_oauth2_proxy_url }}"
|
|
dest: "/tmp/oauth2-proxy-{{ serveur_oauth2_proxy_version }}.tar.gz"
|
|
mode: "0644"
|
|
|
|
- name: Extraire le binaire oauth2-proxy
|
|
ansible.builtin.unarchive:
|
|
src: "/tmp/oauth2-proxy-{{ serveur_oauth2_proxy_version }}.tar.gz"
|
|
dest: /usr/local/bin
|
|
remote_src: true
|
|
extra_opts: ["--strip-components=1", "--wildcards", "*/oauth2-proxy"]
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
creates: "{{ serveur_oauth2_proxy_binaire }}"
|
|
notify: Redémarrer oauth2-proxy
|
|
|
|
- name: Créer le répertoire de configuration
|
|
ansible.builtin.file:
|
|
path: "{{ serveur_oauth2_proxy_config | dirname }}"
|
|
state: directory
|
|
owner: root
|
|
group: "{{ serveur_oauth2_proxy_utilisateur }}"
|
|
mode: "0750"
|
|
|
|
- name: Déployer la configuration oauth2-proxy
|
|
ansible.builtin.template:
|
|
src: oauth2-proxy.cfg.j2
|
|
dest: "{{ serveur_oauth2_proxy_config }}"
|
|
owner: root
|
|
group: "{{ serveur_oauth2_proxy_utilisateur }}"
|
|
mode: "0640"
|
|
no_log: true
|
|
notify: Redémarrer oauth2-proxy
|
|
|
|
- name: Déployer l'unité systemd oauth2-proxy
|
|
ansible.builtin.template:
|
|
src: oauth2-proxy.service.j2
|
|
dest: /etc/systemd/system/oauth2-proxy.service
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
notify: Redémarrer oauth2-proxy
|
|
|
|
- name: Activer et démarrer oauth2-proxy
|
|
when: not ansible_check_mode
|
|
ansible.builtin.systemd:
|
|
name: "{{ serveur_oauth2_proxy_service }}"
|
|
enabled: true
|
|
state: started
|
|
daemon_reload: true
|