- 6 docs racine (README, HANDOVER, ARCHITECTURE, DECISIONS, INSTALL, OPERATIONS) - 9 docs thématiques dans docs/ - 10 templates docker-compose dans configs/ - 7 scripts Python/Shell d'import Furious vers Zitadel - 2 matrices RBAC Etat infra au 5 juin 2026 : - 88 users Furious importes dans Zitadel - 8 roles RBAC crees et attribues - Intranet filtre les cartes selon role (Approche A) - 7 outils SSO operationnels
523 lines
14 KiB
Markdown
523 lines
14 KiB
Markdown
# INSTALL — Déploiement from scratch sur un nouveau serveur
|
|
|
|
> Procédure complète pour reproduire l'infrastructure Seize sur un nouveau serveur.
|
|
|
|
⏱️ **Temps total estimé** : 4-6h pour un sysadmin expérimenté.
|
|
|
|
---
|
|
|
|
## 📋 Prérequis
|
|
|
|
### Côté infrastructure
|
|
|
|
- [ ] **Serveur Linux** : 4 vCPU, 8 Go RAM minimum (16 Go recommandé), 80 Go disque
|
|
- [ ] **OS** : Debian 13 (Trixie) ou Ubuntu 22.04+
|
|
- [ ] **IP publique fixe** (chez Scaleway ou autre)
|
|
- [ ] **Ports ouverts** : 22 (SSH), 80 (HTTP), 443 (HTTPS)
|
|
|
|
### Côté domaine
|
|
|
|
- [ ] Un **domaine** que vous contrôlez (ex: `seizeconsulting.com`)
|
|
- [ ] Accès à la **zone DNS** pour ajouter des records A
|
|
|
|
### Côté tiers
|
|
|
|
- [ ] Compte **Furious Squad** avec droits admin (pour créer un compte API)
|
|
- [ ] (Optionnel) Compte **Microsoft 365** avec admin pour le SMTP
|
|
|
|
### Côté local
|
|
|
|
- [ ] Un **PC** avec SSH et SCP (Windows PowerShell, Linux, ou macOS)
|
|
- [ ] Un **gestionnaire de mots de passe** (Bitwarden, KeePass, 1Password)
|
|
|
|
---
|
|
|
|
## 🌐 Étape 0 — Configuration DNS
|
|
|
|
⏱️ **15 min** (mais propagation peut prendre 1h+)
|
|
|
|
Chez votre registrar (Scaleway, OVH, Gandi, etc.), ajouter les records A suivants :
|
|
|
|
| Record | Type | Valeur |
|
|
|---|---|---|
|
|
| `@` (ou `seizeconsulting.com`) | A | `<IP_DU_SERVEUR>` |
|
|
| `sso` | A | `<IP_DU_SERVEUR>` |
|
|
| `intranet` | A | `<IP_DU_SERVEUR>` |
|
|
| `git` | A | `<IP_DU_SERVEUR>` |
|
|
| `n8n` | A | `<IP_DU_SERVEUR>` |
|
|
| `portainer` | A | `<IP_DU_SERVEUR>` |
|
|
| `code` | A | `<IP_DU_SERVEUR>` |
|
|
| `status` | A | `<IP_DU_SERVEUR>` |
|
|
| `traefik` | A | `<IP_DU_SERVEUR>` |
|
|
|
|
**Vérification** :
|
|
```bash
|
|
nslookup sso.seizeconsulting.com
|
|
```
|
|
→ Doit retourner l'IP du serveur.
|
|
|
|
---
|
|
|
|
## 🐧 Étape 1 — Préparation du serveur
|
|
|
|
⏱️ **20 min**
|
|
|
|
### 1.1 — Connexion SSH initiale
|
|
|
|
```bash
|
|
ssh root@<IP_DU_SERVEUR>
|
|
```
|
|
|
|
### 1.2 — Créer un user non-root
|
|
|
|
```bash
|
|
adduser admin
|
|
usermod -aG sudo admin
|
|
mkdir -p /home/admin/.ssh
|
|
cp ~/.ssh/authorized_keys /home/admin/.ssh/
|
|
chown -R admin:admin /home/admin/.ssh
|
|
chmod 600 /home/admin/.ssh/authorized_keys
|
|
```
|
|
|
|
### 1.3 — Hardening SSH
|
|
|
|
Éditer `/etc/ssh/sshd_config` :
|
|
```
|
|
PermitRootLogin no
|
|
PasswordAuthentication no
|
|
PubkeyAuthentication yes
|
|
```
|
|
|
|
Restart : `systemctl restart sshd`
|
|
|
|
### 1.4 — Reconnexion en tant que l'utilisateur non-root
|
|
|
|
```bash
|
|
exit
|
|
ssh admin@<IP_DU_SERVEUR>
|
|
```
|
|
|
|
### 1.5 — Mise à jour système
|
|
|
|
```bash
|
|
sudo apt update && sudo apt upgrade -y
|
|
sudo apt install -y curl wget git vim htop unzip
|
|
```
|
|
|
|
---
|
|
|
|
## 🐳 Étape 2 — Installation Docker
|
|
|
|
⏱️ **10 min**
|
|
|
|
```bash
|
|
# Installation Docker depuis le repo officiel
|
|
curl -fsSL https://get.docker.com | sudo sh
|
|
|
|
# Ajouter l'utilisateur au groupe docker
|
|
sudo usermod -aG docker $USER
|
|
|
|
# Se relogger pour prendre en compte le groupe
|
|
exit
|
|
ssh admin@<IP_DU_SERVEUR>
|
|
|
|
# Vérification
|
|
docker --version
|
|
docker compose version
|
|
```
|
|
|
|
→ Tu dois voir : Docker version 27.x ou plus récent, Docker Compose v2.x
|
|
|
|
---
|
|
|
|
## 🌐 Étape 3 — Création des réseaux Docker
|
|
|
|
⏱️ **2 min**
|
|
|
|
```bash
|
|
docker network create web
|
|
docker network create backend
|
|
```
|
|
|
|
→ Ces réseaux seront partagés entre tous les services.
|
|
|
|
---
|
|
|
|
## 🛡️ Étape 4 — Installation Traefik
|
|
|
|
⏱️ **30 min**
|
|
|
|
Voir [docs/02-traefik-setup.md](./docs/02-traefik-setup.md) pour les détails.
|
|
|
|
### Résumé
|
|
|
|
```bash
|
|
mkdir -p ~/docker/traefik/letsencrypt
|
|
cd ~/docker/traefik
|
|
# Copier le docker-compose.yml depuis configs/traefik/
|
|
# Copier traefik.yml et dynamic.yml depuis configs/traefik/
|
|
# Adapter les emails Let's Encrypt
|
|
docker compose up -d
|
|
```
|
|
|
|
**Vérification** :
|
|
```bash
|
|
docker logs traefik
|
|
# Doit afficher "Server is up"
|
|
```
|
|
|
|
Visiter `https://traefik.seizeconsulting.com` → doit afficher la page de login basic auth.
|
|
|
|
---
|
|
|
|
## 🔐 Étape 5 — Installation Zitadel
|
|
|
|
⏱️ **45 min**
|
|
|
|
Voir [docs/03-zitadel-setup.md](./docs/03-zitadel-setup.md) pour les détails complets.
|
|
|
|
### Résumé des points clés
|
|
|
|
1. Créer `~/docker/zitadel/` avec son `docker-compose.yml` et `.env`
|
|
2. **Important** : Zitadel a son propre Traefik intégré + Postgres dédié
|
|
3. Lancer : `docker compose up -d`
|
|
4. Aller sur `https://sso.seizeconsulting.com/ui/console`
|
|
5. Créer le user **zitadel-admin** initial via console
|
|
6. Configurer les politiques :
|
|
- Password complexity (14 chars, maj+min+chiffres+symboles)
|
|
- MFA obligatoire
|
|
- Lockout après 5 échecs
|
|
|
|
⚠️ **Sauvegarder le mdp zitadel-admin** immédiatement dans le gestionnaire de mots de passe.
|
|
|
|
---
|
|
|
|
## 🗄️ Étape 6 — Installation Postgres (pour Gitea, n8n)
|
|
|
|
⏱️ **10 min**
|
|
|
|
```bash
|
|
mkdir -p ~/docker/postgres/data
|
|
cd ~/docker/postgres
|
|
# Copier docker-compose.yml et .env.example depuis configs/postgres/
|
|
# Renommer .env.example en .env et générer un mdp fort
|
|
cat > .env << EOF
|
|
POSTGRES_PASSWORD=$(openssl rand -base64 32 | tr -d '+/=')
|
|
EOF
|
|
chmod 600 .env
|
|
|
|
docker compose up -d
|
|
|
|
# Vérification
|
|
docker exec -it postgres psql -U postgres -c "SELECT version();"
|
|
```
|
|
|
|
### Créer les databases pour Gitea et n8n
|
|
|
|
```bash
|
|
docker exec -it postgres psql -U postgres << EOF
|
|
CREATE USER gitea WITH PASSWORD 'PWD_GITEA';
|
|
CREATE DATABASE gitea OWNER gitea;
|
|
CREATE USER n8n WITH PASSWORD 'PWD_N8N';
|
|
CREATE DATABASE n8n OWNER n8n;
|
|
EOF
|
|
```
|
|
|
|
⚠️ Remplacer `PWD_GITEA` et `PWD_N8N` par des mdp générés (`openssl rand -base64 24`) et les stocker dans le gestionnaire.
|
|
|
|
---
|
|
|
|
## 🐙 Étape 7 — Installation Gitea avec SSO Zitadel
|
|
|
|
⏱️ **45 min**
|
|
|
|
Voir [docs/05-applications.md](./docs/05-applications.md) section Gitea.
|
|
|
|
### Étapes principales
|
|
|
|
1. Créer `~/docker/gitea/` avec son `docker-compose.yml` et `.env`
|
|
2. Démarrer Gitea : `docker compose up -d`
|
|
3. Aller sur `https://git.seizeconsulting.com` → faire le setup initial
|
|
4. **Dans Zitadel** : créer une application "Gitea" dans le project "Infra Seize"
|
|
5. Configurer dans Gitea : Settings → Authentication Sources → Add OAuth2
|
|
6. **Activer auto-registration** dans `app.ini` :
|
|
```ini
|
|
[oauth2_client]
|
|
ENABLE_AUTO_REGISTRATION = true
|
|
USERNAME = preferred_username
|
|
```
|
|
7. Restart Gitea : `docker compose restart`
|
|
|
|
---
|
|
|
|
## 🔐 Étape 8 — Pattern OAuth2-Proxy pour les autres outils
|
|
|
|
⏱️ **2h** (à répéter pour chaque outil)
|
|
|
|
Voir [docs/04-oauth2-proxy-pattern.md](./docs/04-oauth2-proxy-pattern.md) pour le pattern complet.
|
|
|
|
### Outils à protéger via OAuth2-Proxy
|
|
|
|
- n8n
|
|
- Portainer
|
|
- Code Server
|
|
- Uptime Kuma
|
|
- Intranet
|
|
|
|
### Étapes par outil (exemple : n8n)
|
|
|
|
1. **Déployer l'outil** (sans SSO) :
|
|
```bash
|
|
mkdir -p ~/docker/n8n
|
|
# Copier docker-compose.yml depuis configs/n8n/
|
|
docker compose up -d
|
|
```
|
|
|
|
2. **Créer l'application dans Zitadel** :
|
|
- Console Zitadel → Projects → Infra Seize → Applications → New
|
|
- Type : Web
|
|
- Authentication Method : Basic
|
|
- Grant Types : Authorization Code
|
|
- Redirect URL : `https://n8n.seizeconsulting.com/oauth2/callback`
|
|
- Token Type : JWT
|
|
- Cocher : User roles inside ID Token, User profile info, Add user roles to access token
|
|
|
|
3. **Récupérer Client ID + Client Secret**
|
|
|
|
4. **Déployer OAuth2-Proxy dédié** :
|
|
```bash
|
|
mkdir -p ~/docker/oauth2-proxy-n8n
|
|
# Copier docker-compose.yml et .env.example depuis configs/oauth2-proxy/
|
|
# Adapter les valeurs (host, client_id, client_secret, upstream)
|
|
cd ~/docker/oauth2-proxy-n8n
|
|
docker compose up -d
|
|
```
|
|
|
|
5. **Tester** : aller sur `https://n8n.seizeconsulting.com` → doit rediriger vers Zitadel login.
|
|
|
|
---
|
|
|
|
## 🏠 Étape 9 — Installation Intranet avec RBAC
|
|
|
|
⏱️ **30 min**
|
|
|
|
Voir [docs/07-rbac-intranet.md](./docs/07-rbac-intranet.md) pour les détails.
|
|
|
|
### Étapes
|
|
|
|
1. **Créer le dossier intranet** :
|
|
```bash
|
|
mkdir -p ~/docker/intranet
|
|
```
|
|
|
|
2. **Copier les fichiers** depuis `configs/intranet/` :
|
|
- `docker-compose.yml`
|
|
- `nginx-rbac.conf`
|
|
- `index.html.template` (à personnaliser)
|
|
- `logo.png` (le logo Seize)
|
|
|
|
3. **Créer le `roles-mapping.json`** :
|
|
Il sera généré plus tard par le script `generate-roles-mapping.py` (cf. Étape 10).
|
|
|
|
En attendant, créer un mapping vide :
|
|
```bash
|
|
echo '{}' > roles-mapping.json
|
|
```
|
|
|
|
4. **Déployer OAuth2-Proxy pour l'intranet** : voir Étape 8 mais avec :
|
|
- Host : `intranet.seizeconsulting.com`
|
|
- Upstream : `http://intranet:80`
|
|
|
|
5. **Démarrer l'intranet** :
|
|
```bash
|
|
cd ~/docker/intranet
|
|
docker compose up -d
|
|
```
|
|
|
|
6. **Tester** : aller sur `https://intranet.seizeconsulting.com` → login Zitadel → voir les cartes (toutes affichées tant que roles-mapping.json est vide).
|
|
|
|
---
|
|
|
|
## 👥 Étape 10 — Import des users depuis Furious Squad
|
|
|
|
⏱️ **1h**
|
|
|
|
Voir [docs/06-import-furious.md](./docs/06-import-furious.md) pour la procédure complète.
|
|
|
|
### Étapes principales
|
|
|
|
1. **Créer un compte API Furious** :
|
|
- Connexion Furious → Configuration → Générer un nouvel utilisateur d'API
|
|
- Cocher les permissions : `User > Search` uniquement
|
|
- Sauvegarder identifiant + mdp dans le gestionnaire
|
|
|
|
2. **Créer le service account Zitadel** :
|
|
- Console Zitadel → Users → New → Service user
|
|
- Nom : `furious-import-service`
|
|
- Access Token Type : JWT
|
|
- Dans Default settings → IAM Members → ajouter ce service user avec rôle `IAM User Manager`
|
|
- Générer une clé : Keys → New → Type JSON → télécharger immédiatement
|
|
|
|
3. **Préparer l'environnement Python** :
|
|
```bash
|
|
mkdir -p ~/furious-to-zitadel
|
|
cd ~/furious-to-zitadel
|
|
python3 -m venv venv
|
|
source venv/bin/activate
|
|
pip install requests pyjwt cryptography
|
|
```
|
|
|
|
4. **Copier les scripts** depuis `scripts/furious-to-zitadel/` du repo.
|
|
|
|
5. **Créer le `.env`** :
|
|
```env
|
|
FURIOUS_USERNAME=<credentials créés à l'étape 1>
|
|
FURIOUS_PASSWORD=<credentials créés à l'étape 1>
|
|
FURIOUS_API_URL=https://seize-consulting.furious-squad.com/api/v2
|
|
```
|
|
`chmod 600 .env`
|
|
|
|
6. **Placer la clé JSON Zitadel** :
|
|
- Transférer la clé depuis le PC vers le serveur via SCP
|
|
- `chmod 600 zitadelfuriousimportkey.json`
|
|
|
|
7. **Lancer l'import** :
|
|
```bash
|
|
# Étape A : Lire les users depuis Furious
|
|
./read-all-users.sh
|
|
# → Génère furious-users-raw.json
|
|
|
|
# Étape B : Dry-run (simulation, aucune écriture)
|
|
python3 import-furious-to-zitadel.py --mode dry-run
|
|
|
|
# Étape C : Test sur 3 users
|
|
python3 import-furious-to-zitadel.py --mode test
|
|
|
|
# Étape D : Vérifier dans Zitadel UI que les 3 users sont créés avec metadata
|
|
|
|
# Étape E : Import production (les 85 restants)
|
|
python3 import-furious-to-zitadel.py --mode prod
|
|
```
|
|
|
|
8. **Gérer les doublons** (si users existaient déjà dans Zitadel) :
|
|
```bash
|
|
# Adapter DUPLICATES dans merge-duplicates.py selon ton cas
|
|
python3 merge-duplicates.py
|
|
```
|
|
|
|
9. **Vérifier le CSV** :
|
|
```bash
|
|
wc -l users-credentials.csv
|
|
# Doit être : 1 header + N users
|
|
```
|
|
|
|
---
|
|
|
|
## 🎭 Étape 11 — Configuration des rôles RBAC
|
|
|
|
⏱️ **30 min**
|
|
|
|
Voir [docs/07-rbac-intranet.md](./docs/07-rbac-intranet.md) pour les détails.
|
|
|
|
### Étapes
|
|
|
|
1. **Créer les 8 rôles dans Zitadel** :
|
|
- Console Zitadel → Projects → Infra Seize → Roles → New
|
|
- Créer un par un :
|
|
- direction / Direction / hierarchie
|
|
- manager / Manager / hierarchie
|
|
- expert / Expert / hierarchie
|
|
- consultant_senior / Consultant Senior / hierarchie
|
|
- consultant_junior / Consultant Junior / hierarchie
|
|
- alternant / Alternant / hierarchie
|
|
- stagiaire / Stagiaire / hierarchie
|
|
- support / Support / hierarchie
|
|
|
|
2. **Activer "Return user roles during authentication"** :
|
|
- Console Zitadel → Projects → Infra Seize → General
|
|
- Cocher "Return user roles during authentication"
|
|
- Save
|
|
|
|
3. **Activer "User roles inside ID Token"** sur chaque application :
|
|
- Pour chaque app (Intranet, n8n, etc.) : Token Settings
|
|
- Auth Token Type : JWT
|
|
- Cocher : User roles inside ID Token, Include user's profile info, Add user roles to the access token
|
|
|
|
4. **Modifier OAuth2-Proxy** pour demander le scope des rôles :
|
|
- Pour chaque OAuth2-Proxy : éditer `.env`
|
|
- Modifier : `OAUTH2_PROXY_SCOPE=openid email profile urn:zitadel:iam:org:project:roles`
|
|
- Restart : `docker compose down && docker compose up -d`
|
|
|
|
5. **Lancer les scripts d'attribution** :
|
|
```bash
|
|
cd ~/furious-to-zitadel
|
|
source venv/bin/activate
|
|
|
|
# Générer le mapping email → rôle (pour l'intranet)
|
|
python3 generate-roles-mapping.py
|
|
|
|
# Attribuer les rôles dans Zitadel (87 users)
|
|
python3 assign-roles.py
|
|
```
|
|
|
|
6. **Copier le mapping vers l'intranet** :
|
|
```bash
|
|
cp roles-mapping.json ~/docker/intranet/
|
|
```
|
|
|
|
7. **Restart de l'intranet** :
|
|
```bash
|
|
cd ~/docker/intranet
|
|
docker compose down
|
|
docker compose up -d
|
|
```
|
|
|
|
8. **Test final** :
|
|
- Login en incognito avec un user (ex: consultant_junior)
|
|
- Doit voir uniquement les cartes autorisées (Gitea + Code Server par défaut)
|
|
|
|
---
|
|
|
|
## ✅ Étape 12 — Validation finale
|
|
|
|
⏱️ **30 min**
|
|
|
|
### Checklist de validation
|
|
|
|
- [ ] Tous les conteneurs `Up` : `docker ps`
|
|
- [ ] Tous les sous-domaines répondent en HTTPS
|
|
- [ ] Login Zitadel fonctionne avec MFA
|
|
- [ ] Login intranet fonctionne et filtre les cartes
|
|
- [ ] Login Gitea fonctionne avec auto-registration
|
|
- [ ] Login n8n / Portainer / Code Server / Uptime Kuma fonctionne
|
|
- [ ] Le service account Furious peut lire l'API Furious
|
|
- [ ] Les scripts Python sont opérationnels
|
|
- [ ] Les fichiers sensibles ont `chmod 600`
|
|
- [ ] Les `.env` ne sont pas committés sur Git
|
|
- [ ] Backup automatique en place (à mettre en place — voir OPERATIONS.md)
|
|
|
|
---
|
|
|
|
## 🚨 Points d'attention pendant l'install
|
|
|
|
### Ne pas oublier
|
|
- ✅ Sauvegarder TOUS les secrets dans le gestionnaire de mdp
|
|
- ✅ Configurer le firewall (ufw ou iptables) pour limiter aux ports 22/80/443
|
|
- ✅ Tester chaque étape avant de passer à la suivante
|
|
- ✅ Documenter les écarts par rapport à cette procédure si tu en fais
|
|
|
|
### Pièges classiques
|
|
- ❌ Oublier d'ajouter le record DNS avant de tester le HTTPS (Let's Encrypt échoue)
|
|
- ❌ Lancer `docker compose up -d` sans avoir créé le `.env` (erreurs cryptiques)
|
|
- ❌ Donner IAM_OWNER au service account (utiliser IAM_USER_MANAGER)
|
|
- ❌ Coller un secret dans une conversation IA (gestionnaire de mdp uniquement)
|
|
|
|
---
|
|
|
|
## 📚 Pour aller plus loin
|
|
|
|
Une fois l'install terminée, consulter :
|
|
- [OPERATIONS.md](./OPERATIONS.md) pour la maintenance quotidienne
|
|
- [docs/09-troubleshooting.md](./docs/09-troubleshooting.md) pour les problèmes fréquents
|
|
- [HANDOVER.md](./HANDOVER.md) pour les actions à mener
|