deploy: authentik LXC203 + traefik auth.peis.fr routing
This commit is contained in:
+13
-3
@@ -1,4 +1,14 @@
|
|||||||
# INSTRUCTIONS POUR VIBE
|
# INSTRUCTIONS POUR AGENTS
|
||||||
|
|
||||||
|
## 📋 Sommaire des agents
|
||||||
|
|
||||||
|
- **[AGENT_devops.md](AGENT_devops.md)** : Opérations quotidiennes (Status Monitor, commandes SSH, corrections courantes)
|
||||||
|
- **[AGENT_MAJ_traefik_GIT_inventaire.md](AGENT_MAJ_traefik_GIT_inventaire.md)** : Synchronisation Traefik/GIT (procédure détaillée)
|
||||||
|
- **[AGENT-creation-lxc-proxmox.md](AGENT-creation-lxc-proxmox.md)** : Création de containers LXC sur Proxmox
|
||||||
|
- **[AGENT-TRAEFIK-https-homelab-infomaniak.md](AGENT-TRAEFIK-https-homelab-infomaniak.md)** : Configuration HTTPS/Traefik avec Let's Encrypt
|
||||||
|
- **[AGENT_Transfert_de_certificat_viaCT200.md](AGENT_Transfert_de_certificat_viaCT200.md)** : Transfert de certificats via CT200 comme bastion
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## RÈGLES ABSOLUES
|
## RÈGLES ABSOLUES
|
||||||
|
|
||||||
@@ -6,7 +16,7 @@
|
|||||||
cd ~/homelab-config
|
cd ~/homelab-config
|
||||||
git pull
|
git pull
|
||||||
|
|
||||||
2. TOUJOURS travailler depuis ~/homelab-config (WSL) Tu as WSL d'installé avec ubuntu. utilise le pour cloner git...
|
2. TOUJOURS travailler depuis ~/homelab-config (WSL) - Tu as WSL d'installé avec ubuntu. utilise le pour cloner git...
|
||||||
|
|
||||||
3. JAMAIS toucher aux fichiers locaux sur C:/Users/theo/.vibe/Proxmox/inventair/
|
3. JAMAIS toucher aux fichiers locaux sur C:/Users/theo/.vibe/Proxmox/inventair/
|
||||||
|
|
||||||
@@ -36,4 +46,4 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
Créé par : Theo
|
Créé par : Theo
|
||||||
Pour : Mistral Vibe
|
Pour : Mistral Vibe et autres agents
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
PG_USER=authentik
|
||||||
|
PG_DB=authentik
|
||||||
|
PG_PASS=XCYbxE3+7LmL6pv++F31IVNiHSPNHyAC
|
||||||
|
AUTHENTIK_SECRET_KEY=EcJRrU3zmqKzt37gZgViQw4+SydEdPtg29rXCEScQVVFbI1nNROOdh+rQuWCqtic
|
||||||
|
AUTHENTIK_ERROR_REPORTING__ENABLED=false
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
ROOT_PASS=
|
||||||
|
PG_PASS=
|
||||||
|
AUTH_KEY=
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# Secrets Authentik
|
||||||
|
|
||||||
|
Générés le 2026-07-21T01:03:29+02:00
|
||||||
|
|
||||||
|
- root CT203 : rj6cuKjHTP2WUHFE
|
||||||
|
- PG_PASS : XCYbxE3+7LmL6pv++F31IVNiHSPNHyAC
|
||||||
|
- AUTHENTIK_SECRET_KEY : EcJRrU3zmqKzt37gZgViQw4+SydEdPtg29rXCEScQVVFbI1nNROOdh+rQuWCqtic
|
||||||
|
- Authentik admin (akadmin) : PLytRPLmwa1+eemjKfAy
|
||||||
|
- Gateway CT203 : 192.168.0.254
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
postgresql:
|
||||||
|
image: docker.io/library/postgres:16-alpine
|
||||||
|
container_name: authentik-postgresql
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
|
||||||
|
start_period: 20s
|
||||||
|
interval: 30s
|
||||||
|
retries: 5
|
||||||
|
timeout: 5s
|
||||||
|
volumes:
|
||||||
|
- ./database:/var/lib/postgresql/data
|
||||||
|
environment:
|
||||||
|
POSTGRES_PASSWORD: ${PG_PASS}
|
||||||
|
POSTGRES_USER: ${PG_USER}
|
||||||
|
POSTGRES_DB: ${PG_DB}
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: docker.io/library/redis:alpine
|
||||||
|
container_name: authentik-redis
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
|
||||||
|
start_period: 20s
|
||||||
|
interval: 30s
|
||||||
|
retries: 5
|
||||||
|
timeout: 3s
|
||||||
|
volumes:
|
||||||
|
- ./redis:/data
|
||||||
|
|
||||||
|
server:
|
||||||
|
image: ghcr.io/goauthentik/server:2024.8.3
|
||||||
|
container_name: authentik-server
|
||||||
|
restart: unless-stopped
|
||||||
|
command: server
|
||||||
|
environment:
|
||||||
|
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
|
||||||
|
AUTHENTIK_REDIS__HOST: redis
|
||||||
|
AUTHENTIK_POSTGRESQL__HOST: postgresql
|
||||||
|
AUTHENTIK_POSTGRESQL__USER: ${PG_USER}
|
||||||
|
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB}
|
||||||
|
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
|
||||||
|
volumes:
|
||||||
|
- ./media:/media
|
||||||
|
- ./custom-templates:/templates
|
||||||
|
ports:
|
||||||
|
- "9000:9000"
|
||||||
|
depends_on:
|
||||||
|
- postgresql
|
||||||
|
- redis
|
||||||
|
|
||||||
|
worker:
|
||||||
|
image: ghcr.io/goauthentik/server:2024.8.3
|
||||||
|
container_name: authentik-worker
|
||||||
|
restart: unless-stopped
|
||||||
|
command: worker
|
||||||
|
environment:
|
||||||
|
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
|
||||||
|
AUTHENTIK_REDIS__HOST: redis
|
||||||
|
AUTHENTIK_POSTGRESQL__HOST: postgresql
|
||||||
|
AUTHENTIK_POSTGRESQL__USER: ${PG_USER}
|
||||||
|
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB}
|
||||||
|
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
|
||||||
|
volumes:
|
||||||
|
- ./media:/media
|
||||||
|
- ./certs:/certs
|
||||||
|
- ./custom-templates:/templates
|
||||||
|
depends_on:
|
||||||
|
- postgresql
|
||||||
|
- redis
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
# Déploiement Authentik - Projet Authent
|
||||||
|
|
||||||
|
## Statut du 21/07/2026
|
||||||
|
|
||||||
|
Déploiement d'Authentik sur un LXC Proxmox `203` sur `prox2`.
|
||||||
|
|
||||||
|
## Infos clés
|
||||||
|
|
||||||
|
- **Container LXC** : `203` sur `prox2` (`192.168.0.95`)
|
||||||
|
- **IP du CT203** : `192.168.0.203/24`
|
||||||
|
- **Gateway** : `192.168.0.254` (corrigée, n'était pas `192.168.0.1`)
|
||||||
|
- **DNS** : `192.168.0.92` (AdGuard)
|
||||||
|
- **Hostname** : `Authentik`
|
||||||
|
- **Domaine Authentik** : `https://auth.peis.fr`
|
||||||
|
- **Application cible** : `https://status.peis.fr` (Status Monitor)
|
||||||
|
- **Fichier des secrets** : `authentik-secrets.md` (mots de passe, clés)
|
||||||
|
|
||||||
|
## Ce qui a été fait
|
||||||
|
|
||||||
|
1. Suppression du LXC `203` existant.
|
||||||
|
2. Recréation propre du LXC `203` sur `prox2` avec les paramètres demandés.
|
||||||
|
3. Configuration SSH par clé (`id_ed25519`) depuis WSL.
|
||||||
|
4. Activation de `nesting=1` et `keyctl=1`.
|
||||||
|
5. Correction de la gateway : `192.168.0.1` → `192.168.0.254` (récupérée depuis `vmbr0` de `prox2`).
|
||||||
|
6. Installation de Docker et Docker Compose dans le LXC.
|
||||||
|
7. Déploiement d'Authentik `2024.8.3` avec PostgreSQL et Redis via `docker-compose.yml`.
|
||||||
|
8. Correction des permissions du volume `/opt/authentik/media` (`chown 1000:1000`).
|
||||||
|
9. Configuration Traefik pour exposer `auth.peis.fr` (`dynamic.yml` sur `ct200`).
|
||||||
|
10. Création du compte admin `akadmin` et du provider/application `Status Monitor` dans Authentik.
|
||||||
|
|
||||||
|
## Vérifications actuelles
|
||||||
|
|
||||||
|
| URL | Résultat |
|
||||||
|
|-----|----------|
|
||||||
|
| `https://auth.peis.fr` | `302` → page de login Authentik accessible |
|
||||||
|
| `https://status.peis.fr` | `200` → service restauré |
|
||||||
|
|
||||||
|
## Problème restant
|
||||||
|
|
||||||
|
Le `forwardAuth` pour protéger `status.peis.fr` a été configuré dans Traefik, mais l'`outpost` intégré d'Authentik retourne `404` sur `/outpost.goauthentik.io/auth/traefik`.
|
||||||
|
|
||||||
|
Le middleware a donc été désactivé temporairement dans `traefik-config/config/dynamic.yml` pour ne pas casser `status.peis.fr`.
|
||||||
|
|
||||||
|
## À faire demain
|
||||||
|
|
||||||
|
1. Se connecter à `https://auth.peis.fr` avec `akadmin`.
|
||||||
|
2. Vérifier dans l'UI Authentik :
|
||||||
|
- **Applications** → `Status Monitor` existe et est associée au provider `status-monitor`
|
||||||
|
- **Outposts** → `authentik Embedded Outpost` contient bien le provider `status-monitor`
|
||||||
|
3. Tester directement l'URL de l'outpost :
|
||||||
|
`curl -H "X-Forwarded-Host: status.peis.fr" -H "X-Forwarded-Proto: https" http://192.168.0.203:9000/outpost.goauthentik.io/auth/traefik`
|
||||||
|
4. Si l'outpost répond correctement (401 ou 302), réactiver le middleware dans `traefik-config/config/dynamic.yml` :
|
||||||
|
- Décommenter les lignes `middlewares: - "authentik-forwardauth"` sous `status-monitor`
|
||||||
|
- Copier `dynamic.yml` sur `ct200:/opt/traefik/config/dynamic.yml`
|
||||||
|
- `docker restart traefik-proxy` sur `ct200`
|
||||||
|
|
||||||
|
## Fichiers importants
|
||||||
|
|
||||||
|
- `authentik-secrets.md` : mots de passe générés
|
||||||
|
- `.env` : variables d'environnement Authentik
|
||||||
|
- `docker-compose.yml` : stack Authentik
|
||||||
|
- `../traefik-config/config/dynamic.yml` : configuration Traefik
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""Homelab Status Monitor v1.1.0"""
|
"""Homelab Status Monitor v1.1.1"""
|
||||||
|
|
||||||
import socket
|
import socket
|
||||||
import ssl
|
import ssl
|
||||||
@@ -9,7 +9,7 @@ import threading
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
||||||
|
|
||||||
VERSION = "1.1.0"
|
VERSION = "1.1.1"
|
||||||
|
|
||||||
# Service configuration: name, type (ssh/http/https), host, port, url (for http/https), insecure (for https)
|
# Service configuration: name, type (ssh/http/https), host, port, url (for http/https), insecure (for https)
|
||||||
SERVICES = {
|
SERVICES = {
|
||||||
@@ -37,6 +37,9 @@ SERVICES = {
|
|||||||
"ct201-status": {"name": "Status Monitor", "type": "ssh", "host": "192.168.0.201", "port": 22},
|
"ct201-status": {"name": "Status Monitor", "type": "ssh", "host": "192.168.0.201", "port": 22},
|
||||||
"ct201-status-http": {"name": "Status Monitor Web", "type": "http", "host": "192.168.0.201", "port": 80, "url": "/"},
|
"ct201-status-http": {"name": "Status Monitor Web", "type": "http", "host": "192.168.0.201", "port": 80, "url": "/"},
|
||||||
|
|
||||||
|
"ct202-gitea": {"name": "Gitea", "type": "ssh", "host": "192.168.0.202", "port": 22},
|
||||||
|
"ct202-gitea-http": {"name": "Gitea Web", "type": "http", "host": "192.168.0.202", "port": 3000, "url": "/"},
|
||||||
|
|
||||||
# VM
|
# VM
|
||||||
"vm100-ha": {"name": "Home Assistant", "type": "ssh", "host": "192.168.0.43", "port": 22},
|
"vm100-ha": {"name": "Home Assistant", "type": "ssh", "host": "192.168.0.43", "port": 22},
|
||||||
"vm100-ha-http": {"name": "Home Assistant Web", "type": "http", "host": "192.168.0.43", "port": 8123, "url": "/"},
|
"vm100-ha-http": {"name": "Home Assistant Web", "type": "http", "host": "192.168.0.43", "port": 8123, "url": "/"},
|
||||||
@@ -245,7 +248,7 @@ def generate_html():
|
|||||||
function setGlobalLoad(b) {
|
function setGlobalLoad(b) {
|
||||||
refreshInProgress = b;
|
refreshInProgress = b;
|
||||||
var elem = document.getElementById("global-loading");
|
var elem = document.getElementById("global-loading");
|
||||||
elem.innerHTML = b ? '<span class="loading-spinner"></span>' : '';
|
elem.innerHTML = b ? '<span class="loading-spinner"></span>' : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function render() {
|
function render() {
|
||||||
@@ -262,7 +265,7 @@ def generate_html():
|
|||||||
const pi = c.url ? c.host + ":" + c.port + c.url : c.host + ":" + c.port;
|
const pi = c.url ? c.host + ":" + c.port + c.url : c.host + ":" + c.port;
|
||||||
|
|
||||||
h += "<div class='card ' + bc + '>";
|
h += "<div class='card ' + bc + '>";
|
||||||
h += "<button class='refresh-btn' onclick="refreshService('" + id + "')" title="Refresh">🔄</button>";
|
h += "<button class='refresh-btn' onclick='refreshService(\'" + id + "\')' title='Refresh'>🔄</button>";
|
||||||
h += "<div class='header'><div class='name'>" + c.name + "</div><span class='type'>" + c.type + "</span></div>";
|
h += "<div class='header'><div class='name'>" + c.name + "</div><span class='type'>" + c.type + "</span></div>";
|
||||||
h += "<span class='badge " + bc + "'>" + s.replace(/_/g, " ") + "</span>";
|
h += "<span class='badge " + bc + "'>" + s.replace(/_/g, " ") + "</span>";
|
||||||
h += "<div class='details'>" + pi + "</div>";
|
h += "<div class='details'>" + pi + "</div>";
|
||||||
|
|||||||
@@ -4,37 +4,19 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
REPO_DIR="$(dirname "$SCRIPT_DIR")"
|
||||||
|
|
||||||
echo "[DEPLOY] Début du déploiement depuis Git..."
|
echo "[DEPLOY] Début du déploiement depuis Git..."
|
||||||
|
|
||||||
# Se connecte à CT201 via rebond CT200 et déploye
|
echo "[DEPLOY] Transfert des fichiers vers CT201..."
|
||||||
ssh -J root@192.168.0.100 root@192.168.0.201 << 'ENDSSH'
|
scp -J root@192.168.0.100 -i ~/.ssh/id_ed25519 "$SCRIPT_DIR/app.py" root@192.168.0.201:/tmp/app.py
|
||||||
cd /opt/status-monitor
|
|
||||||
|
|
||||||
echo "[DEPLOY] Mise à jour depuis Git..."
|
echo "[DEPLOY] Installation sur CT201..."
|
||||||
if [ ! -d "homelab-config" ]; then
|
ssh -J root@192.168.0.100 -i ~/.ssh/id_ed25519 root@192.168.0.201 << 'ENDSSH'
|
||||||
git clone https://VisualPCI:3N14E7GWVSgi3K@git.peis.fr/VisualPCI/homelab-config.git
|
mv /tmp/app.py /opt/status-monitor/app.py
|
||||||
echo "[DEPLOY] Dépôt cloné"
|
|
||||||
else
|
|
||||||
cd homelab-config
|
|
||||||
git pull
|
|
||||||
echo "[DEPLOY] Dépôt mis à jour"
|
|
||||||
cd ..
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "[DEPLOY] Copie des fichiers..."
|
|
||||||
cp -f homelab-config/status-monitor/app.py .
|
|
||||||
|
|
||||||
# Copier le service systemd si présent
|
|
||||||
if [ -f "homelab-config/status-monitor/status-monitor.service" ]; then
|
|
||||||
cp -f homelab-config/status-monitor/status-monitor.service /etc/systemd/system/
|
|
||||||
systemctl daemon-reload
|
|
||||||
echo "[DEPLOY] Service systemd mis à jour"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "[DEPLOY] Redémarrage du service..."
|
|
||||||
systemctl restart status-monitor
|
systemctl restart status-monitor
|
||||||
|
echo "[DEPLOY] ✅ Déploiement terminé sur CT201 !"
|
||||||
echo "[DEPLOY] ✅ Déploiement terminé !"
|
|
||||||
ENDSSH
|
ENDSSH
|
||||||
|
|
||||||
echo "[DEPLOY] Déploiement terminé avec succès !"
|
echo "[DEPLOY] Déploiement terminé avec succès !"
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ http:
|
|||||||
tls:
|
tls:
|
||||||
certResolver: "letsencrypt"
|
certResolver: "letsencrypt"
|
||||||
service: status-monitor
|
service: status-monitor
|
||||||
|
# middlewares:
|
||||||
|
# - "authentik-forwardauth" # TODO: reactiver apres validation UI Authentik
|
||||||
|
|
||||||
git-server:
|
git-server:
|
||||||
rule: "Host(`git.peis.fr`)"
|
rule: "Host(`git.peis.fr`)"
|
||||||
@@ -36,6 +38,25 @@ http:
|
|||||||
certResolver: "letsencrypt"
|
certResolver: "letsencrypt"
|
||||||
service: git-server
|
service: git-server
|
||||||
|
|
||||||
|
authentik:
|
||||||
|
rule: "Host(`auth.peis.fr`)"
|
||||||
|
entryPoints:
|
||||||
|
- "websecure"
|
||||||
|
tls:
|
||||||
|
certResolver: "letsencrypt"
|
||||||
|
service: authentik
|
||||||
|
middlewares:
|
||||||
|
- "security-headers"
|
||||||
|
|
||||||
|
authentik-outpost:
|
||||||
|
rule: "Host(`auth.peis.fr`) && PathPrefix(`/outpost.goauthentik.io/`)"
|
||||||
|
entryPoints:
|
||||||
|
- "websecure"
|
||||||
|
tls:
|
||||||
|
certResolver: "letsencrypt"
|
||||||
|
service: authentik
|
||||||
|
priority: 150
|
||||||
|
|
||||||
services:
|
services:
|
||||||
homeassistant:
|
homeassistant:
|
||||||
loadBalancer:
|
loadBalancer:
|
||||||
@@ -52,11 +73,26 @@ http:
|
|||||||
servers:
|
servers:
|
||||||
- url: "http://192.168.0.202:3000"
|
- url: "http://192.168.0.202:3000"
|
||||||
|
|
||||||
|
authentik:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: "http://192.168.0.203:9000"
|
||||||
|
|
||||||
middlewares:
|
middlewares:
|
||||||
auth:
|
auth:
|
||||||
basicAuth:
|
basicAuth:
|
||||||
users:
|
users:
|
||||||
- "admin:$apr1$xnK9sM6u$q81sJuvBe5R3rfefqDLuk1"
|
- "admin:$apr1$xnK9sM6u$q81sJuvBe5R3rfefqDLuk1"
|
||||||
|
authentik-forwardauth:
|
||||||
|
forwardAuth:
|
||||||
|
address: "http://192.168.0.203:9000/outpost.goauthentik.io/auth/traefik"
|
||||||
|
trustForwardHeader: true
|
||||||
|
authResponseHeaders:
|
||||||
|
- X-Forwarded-User
|
||||||
|
- X-Forwarded-Groups
|
||||||
|
- X-Forwarded-Email
|
||||||
|
- X-Forwarded-Preferred-Username
|
||||||
|
- X-Forwarded-User-Id
|
||||||
security-headers:
|
security-headers:
|
||||||
headers:
|
headers:
|
||||||
frameDeny: true
|
frameDeny: true
|
||||||
|
|||||||
Reference in New Issue
Block a user