Client ⇒ DNS ⇒ HAProxy (LXC) ⇒ oauth2-proxy ⇒ Applications internes
HAProxy dispose d'un certificat signé par ADCS.
Les serveurs sont accessibles :
Qu’est‑ce qu’un SAN ?
Le SAN (Subject Alternative Name) est une extension d’un certificat SSL/TLS qui permet d’indiquer plusieurs noms DNS (ou adresses IP) comme étant valides pour un même certificat. C'est devenu obligatoire dans les certificats et certains navigateur comme Chrome/Firefox ne lisent plus le CN seul.
Pour qu'un certificat soit valide pour un nom DNS, ce nom DNS doit apparaître dans subjectAltName.
Rôle du le SAN :
Un certificat peut contenir :
| Application | FQDN | Certificat nécessaire |
|---|---|---|
| Guacamole | guac.lab.local | guac.lab.local.pem |
| Grafana | grafana.lab.local | grafana.lab.local.pem |
| Portainer | portainer.lab.local | portainer.lab.local.pem |
HAProxy sélectionne automatiquement le certificat grâce au SNA :
Cela permet :
apt update && apt upgrade -y
apt install haproxy -y
haproxy -v
systemctl enable haproxy systemctl start haproxy
systemctl status haproxy
cd /root openssl genrsa -out guac.lab.local.key 2048
Crée un fichier san.cnf pour ajouter un SAN (recommandé) avec ce contenu :
[ req ] default_bits = 2048 prompt = no default_md = sha256 req_extensions = req_ext distinguished_name = dn [ dn ] CN = guac.lab.local [ req_ext ] subjectAltName = @alt_names [ alt_names ] DNS.1 = guac.lab.local
openssl req -new -key guac.lab.local.key \ -out guac.lab.local.csr \ -config san.cnf
Important : le modèle de certificat doit autoriser :
openssl x509 -in certificat.cer -out certificat.crt
openssl pkcs7 -print_certs -in certificate.p7b -out chain.pem
cat server.key certificat.crt chain.pem > fullchain.pem
chmod 600 /etc/haproxy/certs/fullchain.pem
certutil -ca.cert rootCA.cer
openssl x509 -in rootCA.cer -out rootCA.crt
haproxy -c -f /etc/haproxy/haproxy.cfg systemctl reload haproxy
HAProxy détectera automatiquement le bon certificat grâce au SNI.
🎁 Bonus : Template conseillé dans ADCS pour reverse‑proxy Dans l’outil “Certification Authority”, crée un template basé sur Web Server, configure :
Subject → “Supply in the request” (obligatoire pour SAN) Extensions → “Server Authentication” Validity : 2 ans Private key → “Key usage: Digital Signature + Key Encipherment” Key length : 2048 ou 4096 bits
ÉtapeAction1Générer clé + CSR dans le LXC2Envoyer la CSR à la CA Microsoft3Télécharger certificat + CA4Assembler .pem pour HAProxy5Reload HAProxy 👉 Tous les PC Windows du domaine font automatiquement confiance aux certificats émis par la CA Microsoft : zéro alerte SSL.
sudo chown tomcat:tomcat /etc/tomcat9/ssl/sioguacamole.0870019y.lan.p12 sudo chmod 600 /etc/tomcat9/ssl/sioguacamole.0870019y.lan.p12
OLUTION : désinstaller libtcnative-1 pour forcer Tomcat à repasser en JSSE
Lien : https://github.com/oauth2-proxy/oauth2-proxy
mkdir -p /opt/oauth2-proxy
cd /opt/oauth2-proxy wget https://github.com/oauth2-proxy/oauth2-proxy/releases/download/v7.13.0/oauth2-proxy-v7.13.0.linux-amd64.tar.gz tar -xvf oauth2-proxy-v7.13.0.linux-amd64.tar.gz mv oauth2-proxy-v7.13.0.linux-amd64/oauth2-proxy /usr/local/bin/ chmod +x /usr/local/bin/oauth2-proxy
useradd --system --no-create-home --shell /usr/sbin/nologin oauth2-proxy
mkdir -p /etc/oauth2-proxy chown oauth2-proxy:oauth2-proxy /etc/oauth2-proxy
Ce dossier permet de stocker le fichier oauth2-proxy.cfg.
Un cookie secret 32 octets base64 URL‑safe est obligatoire.
python3 - <<'EOF' import os,base64; print(base64.urlsafe_b64encode(os.urandom(32)).decode()) EOF
Noter la valeur générée qui sera nécessaire pour le service systemd :
nano /etc/systemd/system/oauth2-proxy-guacamole.service
Contenu :
[Unit] Description=oauth2-proxy (Guacamole) After=network-online.target [Service] User=oauth2-proxy Group=oauth2-proxy ExecStart=/usr/local/bin/oauth2-proxy \ --provider=ms_entra_id \ --client-id=<APP_ID_GUAC> \ --client-secret=<APP_SECRET_GUAC> \ --redirect-url=https://guac.lab.local/oauth2/callback \ --email-domain=* \ --cookie-secret=<TON_COOKIE_SECRET> \ --cookie-secure=true \ --cookie-samesite=None \ --cookie-name=_guac_oauth \ --set-xauthrequest \ --pass-access-token \ --http-address=127.0.0.1:4181 \ --upstream=http://10.xxx.yyy.zzz:8080/guacamole Restart=always RestartSec=3 [Install] WantedBy=multi-user.target
# systemctl daemon-reload # systemctl enable --now oauth2-proxy-guacamole Created symlink '/etc/systemd/system/multi-user.target.wants/oauth2-proxy-guacamole.service' -> '/etc/systemd/system/oauth2-proxy-guacamole.service'.
💡 Toutes les options du binaire (cookies, upstream, OIDC provider, scopes) suivent exactement les paramètres décrits dans la documentation oauth2‑proxy. 💡 Le provider msentraid est officiellement supporté.
systemctl status oauth2-proxy-guacamole journalctl -u oauth2-proxy-guacamole -f
Ce fichier contient 4 grandes sections :
Il faut ajouter :
Il faut configurer dans HAProxy (LXC), un backend pointant vers l’instance oauth2‑proxy en rajoutant les lignes suivantes:
# ================================ # FRONTEND HTTPS (entrant) # ================================ frontend fe_https bind *:443 ssl crt /etc/haproxy/certs/ # Détection du domaine utilisé acl host_guac hdr(host) -i sioguacamole.0870019y.lan # Routage vers le backend correspondant use_backend bk_oauth2_guac if host_guac default_backend bk_default # ================================= # BACKEND GUACAMOLE via oauth2-proxy # ================================= backend bk_oauth2_guac http-request set-header X-Forwarded-Proto https http-request set-header X-Forwarded-Host %[req.hdr(host)] server oauth2_guac 127.0.0.1:4181 check # Backend par défaut (si domaine inconnu) backend bk_default errorfile 503 /etc/haproxy/errors/503.http
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
# See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GC>
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
# ================================
# FRONTEND HTTPS (entrant)
# ================================
frontend fe_https
bind *:443 ssl crt /etc/haproxy/certs/
# D tection du domaine utilis
acl host_guac hdr(host) -i sioguacamole.0870019y.lan
# Routage vers le backend correspondant
use_backend bk_oauth2_guac if host_guac
default_backend bk_default
# =================================
# BACKEND GUACAMOLE via oauth2-proxy
# =================================
backend bk_oauth2_guac
http-request set-header X-Forwarded-Proto https
http-request set-header X-Forwarded-Host %[req.hdr(host)]
server oauth2_guac 127.0.0.1:4181 check
# Backend par d faut (si domaine inconnu)
backend bk_default
errorfile 503 /etc/haproxy/errors/503.http
oauth2‑proxy va ensuite :
haproxy -c -f /etc/haproxy/haproxy.cfg
* vérifier si tout est OK :
systemctl restart haproxy
Tu dois voir :
Pour vérifier en ligne de commande :
curl -I https://guac.lab.local
Il devrait y avoir une réponse du proxy.
🟩 Résultat Tu as maintenant : B. Variante au proxy : placer oauth2‑proxy entre HAProxy et Guacamole, et déléguer l’auth au proxy (OIDC/SAML) avec Entra ID, puis passer des en‑têtes vers Guacamole. C’est utile si tu veux factoriser l’auth pour plusieurs apps derrière le même HAProxy. (Côté Entra, l’intégration la plus robuste est en OIDC avec l’IDP Microsoft Entra ID). [oauth2-pro….github.io], [oauth2-pro….github.io]
Tip HA : si tu veux de la haute dispo du frontal, tu pourras ultérieurement doubler ce LXC et ajouter Keepalived/VRRP. [forum.proxmox.com]
Choix de OIDC ici plutôt que SAML car l’intégration oauth2‑proxy avec Entra ID est officielle, documentée et maintenue côté OIDC (group overage, multi‑tenant, etc.).
HAProxy (LXC) en frontal → oauth2‑proxy (OIDC Microsoft Entra ID) → Applications internes (Guacamole, Grafana, …) Cette approche centralise l’authentification côté proxy, factorise les règles (groupes, accès), et décharge les applis. Elle s’appuie sur le provider Microsoft Entra ID officiel d’oauth2‑proxy (OIDC), bien documenté et maintenu.
Lien : https://github.com/ahuacate/pfsense-haproxy
Objectifs
SSO commun via Microsoft Entra ID (OIDC) pour plusieurs applis. 1 conteneur LXC Proxmox hébergeant HAProxy (terminaison TLS) et **une ou plusieurs instances d’oauth2‑proxy. Routage SNI : un FQDN par appli (ex. guac.lab.local, grafana.lab.local). Isolement & lisibilité : 1 instance oauth2‑proxy par appli (recommandé pour débuter), chacune avec son App Registration Entra.