Aller au contenu
TAAF-OPS --:-- UTC

TP — SSO Active Directory ↔ NextCloud

3h00 Acte 2 · SIEM Intermédiaire → Avancé Identité · AD · NextCloud · OIDC

Auteur : Thibaut Fontaine — Kodetis Institution : Université de la Réunion Date : 2026 Position dans le parcours : prérequis de l’Acte 2 (SIEM) — fait le pont Active DirectoryNextCloud.



📡 Poste SOC · La Réunion — vous armez Alfred Faure (Crozet), à ~2 900 km : AD hub et données classifiées du réseau. Liaison SATCOM nominale.

🎯 Objectif métier — arrêter de gérer des comptes en double : une seule identité TAAF (Active Directory) pour ouvrir NextCloud, avec des accès pilotés par les groupes AD.

Aujourd’hui, NextCloud crée ses utilisateurs en local, déconnectés de l’AD. Vous allez en faire un service consommateur d’identité de l’AD TAAF-AD-001. Cette intégration est le socle de l’Acte 2 : sans elle, le SIEM ne pourrait pas corréler une auth AD avec un accès NextCloud (l’identité serait deux choses différentes).

  • Brancher NextCloud sur l’AD via LDAP(S) (authentification centralisée).
  • Mapper les groupes AD aux dossiers métier (les 4 rôles TAAF).
  • (Bonus) Mettre en place un vrai SSO OIDC via un IdP fédéré à l’AD.
  • Durcir la chaîne d’identité (compte break-glass, MFA, deprovisioning).

Dans l’incident rejoué au jour J, le compte AD e.bernard est compromis à 08h00 UTC. Une fois NextCloud branché sur l’AD, cette même identité déverrouille aussi les fichiers classifiés NextCloud (CLASSIFIED-VAULT-X/KER-2024-002.fasta, vu dans les events Falco à 10:05Z). L’identité devient le pivot unique : AD + VPN + NextCloud — c’est ce qui rend le phishing initial si dévastateur, et c’est aussi ce qu’on auditera à l’Acte 3.

graph LR
 subgraph "Identités TAAF"
 AD[(Active Directory
TAAF-AD-001
univ-taaf.internal)] end subgraph "Niveau 1 — LDAP backend" LDAP[LDAP bind
port 389] NC1[NextCloud
user_ldap] end subgraph "Niveau 2 — SSO OIDC (bonus)" IDP[IdP fédéré
Authentik/Keycloak] NC2[NextCloud
user_oidc] end AD -->|sAMAccountName + groupes| LDAP LDAP --> NC1 AD -->|LDAP fed| IDP IDP -->|OIDC token + MFA| NC2 USER([Utilisateur AD]) -->|creds| NC1 USER -->|redirect SSO| NC2 classDef ad fill:#ffcc99,stroke:#333,stroke-width:2px classDef nc fill:#99ccff,stroke:#333,stroke-width:2px classDef sso fill:#99ff99,stroke:#333,stroke-width:2px class AD ad class NC1,NC2 nc class LDAP,IDP sso

Fenêtre de terminal
# Sur le DC, vérifier le domaine
Get-ADDomain | Select-Object DNSRoot, NetBIOSName
# → DNSRoot=univ-taaf.internal, NetBIOSName=UNIV-TAAF

Sur la VM monitoring :

Fenêtre de terminal
docker exec -u www-data nextcloud-alfred-faure php occ status
# → installed: true, version: 28.x
# Vérifier la connectivité vers le DC
docker exec nextcloud-alfred-faure ping -c 2 IP_AD
# → 2 packets transmitted, 2 received

Avant tout, vérifiez que le compte admin.cloud.af fonctionne et notez son mot de passe. Si l’AD tombe ou la config LDAP casse, c’est votre seule porte d’entrée.


3. Niveau 1 — Intégration LDAP/AD (obligatoire)

Section intitulée « 3. Niveau 1 — Intégration LDAP/AD (obligatoire) »

Sur le DC (TAAF-AD-001), via PowerShell :

Fenêtre de terminal
# Créer les 4 groupes métier (correspondent aux 4 dossiers NextCloud)
$ouPath = "OU=TAAF-Groups,DC=univ-taaf,DC=internal"
New-ADOrganizationalUnit -Name "TAAF-Groups" -Path "DC=univ-taaf,DC=internal" -ErrorAction SilentlyContinue
$groups = @(
@{Name="G-TAAF-Administratif"; Desc="Accès dossier Administratif/"},
@{Name="G-TAAF-IT"; Desc="Accès dossier Document-Technique/"},
@{Name="G-TAAF-Biologie"; Desc="Accès dossier Biologie-Marine/"},
@{Name="G-TAAF-Sismologie"; Desc="Accès dossier Sismologie/"}
)
foreach ($g in $groups) {
New-ADGroup -Name $g.Name -GroupScope Global -GroupCategory Security `
-Path $ouPath -Description $g.Desc
}
# Créer un compte de service lecture-seule pour le bind LDAP NextCloud
New-ADUser -Name "svc_nc_ldap" -SamAccountName "svc_nc_ldap" `
-UserPrincipalName "svc_nc_ldap@univ-taaf.internal" `
-Path "OU=TAAF-Users,DC=univ-taaf,DC=internal" `
-AccountPassword (ConvertTo-SecureString "ReadOnly_NC_2026!" -AsPlainText -Force) `
-Enabled $true -PasswordNeverExpires $true
# Ajouter e.bernard au groupe Biologie (rôle TAAF d'Emilie Bernard)
Add-ADGroupMember -Identity "G-TAAF-Biologie" -Members "e.bernard"

Checkpoint :

Fenêtre de terminal
Get-ADGroupMember -Identity "G-TAAF-Biologie" | Select-Object SamAccountName
# → e.bernard

Sur la VM monitoring :

Fenêtre de terminal
# Activer l'app LDAP (livrée avec NextCloud)
docker exec -u www-data nextcloud-alfred-faure php occ app:enable user_ldap
# Créer une configuration LDAP (config s01)
docker exec -u www-data nextcloud-alfred-faure php occ ldap:create-empty-config
# → Created new configuration with configID 's01'
# Configurer le bind
docker exec -u www-data nextcloud-alfred-faure php occ ldap:set-config s01 ldapHost "ldap://IP_AD"
docker exec -u www-data nextcloud-alfred-faure php occ ldap:set-config s01 ldapPort 389
docker exec -u www-data nextcloud-alfred-faure php occ ldap:set-config s01 ldapBase "DC=univ-taaf,DC=internal"
docker exec -u www-data nextcloud-alfred-faure php occ ldap:set-config s01 ldapBaseUsers "OU=TAAF-Users,DC=univ-taaf,DC=internal"
docker exec -u www-data nextcloud-alfred-faure php occ ldap:set-config s01 ldapBaseGroups "OU=TAAF-Groups,DC=univ-taaf,DC=internal"
docker exec -u www-data nextcloud-alfred-faure php occ ldap:set-config s01 ldapAgentName "CN=svc_nc_ldap,OU=TAAF-Users,DC=univ-taaf,DC=internal"
docker exec -u www-data nextcloud-alfred-faure php occ ldap:set-config s01 ldapAgentPassword "ReadOnly_NC_2026!"
# Filtres et mapping
docker exec -u www-data nextcloud-alfred-faure php occ ldap:set-config s01 ldapUserFilter "(&(objectClass=user)(memberOf=CN=G-TAAF-*,OU=TAAF-Groups,DC=univ-taaf,DC=internal))"
docker exec -u www-data nextcloud-alfred-faure php occ ldap:set-config s01 ldapLoginFilter "(&(objectClass=user)(sAMAccountName=%uid))"
docker exec -u www-data nextcloud-alfred-faure php occ ldap:set-config s01 ldapGroupFilter "(&(objectClass=group)(cn=G-TAAF-*))"
docker exec -u www-data nextcloud-alfred-faure php occ ldap:set-config s01 ldapUserDisplayName "displayName"
docker exec -u www-data nextcloud-alfred-faure php occ ldap:set-config s01 ldapExpertUsernameAttr "sAMAccountName"
# Activer la config
docker exec -u www-data nextcloud-alfred-faure php occ ldap:set-config s01 ldapConfigurationActive 1

Test de bind :

Fenêtre de terminal
docker exec -u www-data nextcloud-alfred-faure php occ ldap:test-config s01
# → The configuration is valid and the connection could be established!

Lister les utilisateurs AD remontés :

Fenêtre de terminal
docker exec -u www-data nextcloud-alfred-faure php occ ldap:search "e.bernard"
# → e.bernard | Emilie BERNARD | ...

Ouvrez http://IP_VM2:8081 en navigation privée. Connectez-vous avec :

UserPass
e.bernard(mot de passe AD défini sur le DC)

📸 Capture obligatoire #1 : page d’accueil NextCloud connectée en tant que e.bernard avec son displayName AD visible en haut à droite.

Pour chaque dossier, créez un partage de groupe (Groupfolders, app gratuite NextCloud) :

Fenêtre de terminal
# Activer l'app Groupfolders
docker exec -u www-data nextcloud-alfred-faure php occ app:enable groupfolders
# Créer les 4 group folders et lier au groupe AD correspondant
for pair in "Administratif:G-TAAF-Administratif" "Document-Technique:G-TAAF-IT" "Biologie-Marine:G-TAAF-Biologie" "Sismologie:G-TAAF-Sismologie"; do
folder="${pair%:*}"
group="${pair#*:}"
fid=$(docker exec -u www-data nextcloud-alfred-faure php occ groupfolders:create "$folder" | grep -oE '[0-9]+')
docker exec -u www-data nextcloud-alfred-faure php occ groupfolders:group "$fid" "$group" --add-permissions 31
echo "[+] $folder$group (fid=$fid)"
done
# Importer les fichiers réels depuis data/NextCloud/
docker cp data/NextCloud/Administratif/. nextcloud-alfred-faure:/var/www/html/data/__groupfolders/1/
docker cp data/NextCloud/Document-Technique/. nextcloud-alfred-faure:/var/www/html/data/__groupfolders/2/
docker cp data/NextCloud/Biologie-Marine/. nextcloud-alfred-faure:/var/www/html/data/__groupfolders/3/
docker cp data/NextCloud/Sismologie/. nextcloud-alfred-faure:/var/www/html/data/__groupfolders/4/
# Re-scanner pour indexer
docker exec -u www-data nextcloud-alfred-faure php occ files:scan --all

Reconnectez-vous en tant que e.bernard (membre de G-TAAF-Biologie uniquement) :

Dossier visible ?AttenduRéel
Biologie-Marine/
Administratif/
Document-Technique/
Sismologie/

📸 Capture obligatoire #2 : vue NextCloud de e.bernard montrant uniquement Biologie-Marine/.

Matrice d’accès attendue (livrable) :

Groupe ADAdministratifDoc-TechBiologieSismologie
G-TAAF-Administratif
G-TAAF-IT
G-TAAF-Biologie
G-TAAF-Sismologie

Le Niveau 1 (LDAP) suffit à valider le TP. Ce niveau ajoute le vrai SSO : token, session unique, déconnexion centralisée, MFA imposée côté IdP. Il nécessite un IdP — c’est la seule partie qui en demande un.

Sur la VM monitoring, dans le dépôt monitoring, créez docker-compose-authentik.yml :

services:
authentik-postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: authentik
POSTGRES_USER: authentik
POSTGRES_PASSWORD: AuthentikDB_2026!
volumes: [authentik_db:/var/lib/postgresql/data]
networks: [taaf]
authentik-redis:
image: redis:alpine
networks: [taaf]
authentik-server:
image: ghcr.io/goauthentik/server:2026.1
command: server
environment:
AUTHENTIK_SECRET_KEY: "change-me-32-chars-min-1234567890ab"
AUTHENTIK_POSTGRESQL__HOST: authentik-postgres
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: AuthentikDB_2026!
AUTHENTIK_REDIS__HOST: authentik-redis
ports: ["9000:9000"]
networks: [taaf]
authentik-worker:
image: ghcr.io/goauthentik/server:2026.1
command: worker
environment:
AUTHENTIK_SECRET_KEY: "change-me-32-chars-min-1234567890ab"
AUTHENTIK_POSTGRESQL__HOST: authentik-postgres
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: AuthentikDB_2026!
AUTHENTIK_REDIS__HOST: authentik-redis
networks: [taaf]
volumes:
authentik_db:
networks:
taaf:
external: true
Fenêtre de terminal
docker compose -f docker-compose-authentik.yml up -d
sleep 30
docker compose -f docker-compose-authentik.yml exec authentik-server ak create_admin_group admin
# → initial admin password printed in logs

Accès : http://IP_VM2:9000/if/flow/initial-setup/ (création admin Authentik).

4.2 — Fédérer Authentik à l’AD (LDAP source)

Section intitulée « 4.2 — Fédérer Authentik à l’AD (LDAP source) »

Dans l’UI Authentik :

  1. DirectoryFederation & Social loginCreateLDAP Source
  2. Server URI : ldap://IP_AD:389
  3. Bind CN : CN=svc_nc_ldap,OU=TAAF-Users,DC=univ-taaf,DC=internal + password
  4. Base DN : DC=univ-taaf,DC=internal
  5. Sync activé → laissez tourner 1 minute → vérifiez que les users AD apparaissent dans Authentik.

4.3 — Déclarer NextCloud comme client OIDC dans Authentik

Section intitulée « 4.3 — Déclarer NextCloud comme client OIDC dans Authentik »
  1. ApplicationsProvidersCreateOAuth2/OpenID Provider

  2. Name : nextcloud-oidc

  3. Authorization flow : default-provider-authorization-explicit-consent

  4. Client type : Confidential

  5. Notez le Client ID et le Client Secret.

  6. Redirect URIs : http://IP_VM2:8081/apps/user_oidc/code

  7. ApplicationsApplicationsCreate → name NextCloud, provider nextcloud-oidc, slug nextcloud.

Fenêtre de terminal
# Activer l'app
docker exec -u www-data nextcloud-alfred-faure php occ app:install user_oidc
docker exec -u www-data nextcloud-alfred-faure php occ app:enable user_oidc
# Déclarer le provider Authentik
docker exec -u www-data nextcloud-alfred-faure php occ user_oidc:provider authentik \
--clientid="<CLIENT_ID>" \
--clientsecret="<CLIENT_SECRET>" \
--discoveryuri="http://IP_VM2:9000/application/o/nextcloud/.well-known/openid-configuration" \
--scope="openid email profile" \
--mapping-uid="preferred_username" \
--mapping-display-name="name" \
--mapping-email="email"
  1. Déconnectez-vous de NextCloud.
  2. Ouvrez http://IP_VM2:8081 en navigation privée.
  3. Cliquez sur Log in with authentik.
  4. Redirection vers Authentik → login e.bernard + password AD.
  5. Retour sur NextCloud authentifié, sans ressaisir les credentials.

📸 Capture obligatoire #3 : URL bar montrant la redirection http://IP_VM2:9000/if/flow/... puis retour NextCloud authentifié.

  1. Flows & StagesStagesCreateAuthenticator TOTP Stage.
  2. Ajoutez ce stage au flow default-authentication-flow.
  3. À la prochaine connexion, NextCloud (via Authentik) demandera l’enrôlement TOTP.

📸 Capture obligatoire #4 : écran d’enrôlement TOTP d’Authentik.

Bénéfice : toute application derrière le SSO Authentik hérite de la MFA — pas seulement NextCloud.


PiègeSymptômeMitigation
Suppression du compte admin localAD/IdP down → personne ne peut entrerToujours garder admin.cloud.af actif, mot de passe en coffre-fort
Bind LDAP en clairCreds en sniff réseau (MitM TAAF)LDAPS (636) en prod — audité Acte 3
SPOF d’authentificationAD/Authentik down → NextCloud inutilisableÀ assumer comme propriété, mentionner dans analyse de risque
Provisioning manuelCompte AD désactivé mais NextCloud encore actifSync LDAP régulière (cron) + tester deprovisioning
Pas de logs LDAP côté NextCloudImpossible de voir les binds dans le SIEMActiver nextcloud.log niveau DEBUG sur user_ldap → push vers Loki
Fenêtre de terminal
docker exec -u www-data nextcloud-alfred-faure php occ log:manage --level=debug
docker exec -u www-data nextcloud-alfred-faure php occ config:app:set user_ldap turnOnPasswordChange --value=0

Vérifiez dans Grafana Explore :

{job="nextcloud"} | json | app="user_ldap"

→ Vous devez voir des lignes pour chaque tentative de login. C’est cette source que vos règles Sigma TP1 viendront chercher pour détecter e.bernard qui se connecte depuis une IP externe.


  1. Configuration LDAP fonctionnelle :
    • Sortie de php occ ldap:test-config s01 (status OK)
    • Sortie de php occ ldap:search "e.bernard"
  2. Matrice d’accès groupe → dossier (markdown ou PDF)
  3. 4 captures :
    • NextCloud authentifié comme e.bernard
    • Cloisonnement (seul Biologie-Marine/ visible)
    • (Bonus) Flux SSO Authentik
    • (Bonus) Enrôlement TOTP
  4. Paragraphe d’analyse (1 page) :
    • Surface d’attaque introduite par la centralisation d’identité
    • Comment e.bernard compromis ouvre simultanément VPN + NextCloud
    • Plan de migration LDAP clair → LDAPS
CritèrePondération
LDAP backend NextCloud fonctionnel (ldap:test-config OK + 4 users AD listés)25 %
Groupfolders mappés sur 4 groupes AD + cloisonnement testé20 %
Matrice d’accès complète et vérifiée (pas juste théorique)15 %
Compte break-glass préservé et documenté10 %
(Bonus) SSO OIDC fonctionnel10 %
(Bonus) MFA TOTP active côté IdP10 %
Paragraphe analyse de risque (blast radius identité)10 %

Format de rendu : PDF nom-prenom-promo.pdf sur Moodle.


  1. [Facile] Quelle différence entre « backend LDAP » et « vrai SSO » (token/OIDC) ?
  2. [Facile] Pourquoi conserver un compte admin local malgré le SSO ?
  3. [Moyen] Vous avez configuré le bind en LDAP clair (389). Quel est le risque concret, que verrait un attaquant en MitM, et comment cette faiblesse apparaîtra-t-elle dans l’audit AD (Acte 3) ?
  4. [Moyen] Comment le mapping groupes AD → dossiers applique-t-il le moindre privilège ?
  5. [Avancé] En quoi le SSO augmente le blast radius d’un compte compromis ? Reliez à l’incident e.bernard.
  6. [Avancé] Où placer la MFA pour qu’elle protège toutes les applis d’un coup ? Pourquoi ?

  1. LDAP backend = NextCloud demande les creds à l’utilisateur puis les valide auprès de l’AD (creds passent par NextCloud). SSO/OIDC = NextCloud redirige vers l’IdP, l’utilisateur s’authentifie chez l’IdP, qui renvoie un token. Avantages SSO : pas de pop-up creds par appli, déconnexion centralisée, MFA gérée en un point.

  2. Compte break-glass : si l’AD/IdP tombe (panne, défaillance certificat, attaque), c’est la seule porte d’entrée pour intervenir. Sans lui, perte d’accès NextCloud + tout ce qui est derrière.

  3. Risque LDAP clair : creds en clair sur le réseau → un attaquant en MitM (ARP spoof, comme dans le Module 2 PQC) capture tout. L’attaquant verrait : BindRequest [user=svc_nc_ldap pwd=ReadOnly_NC_2026!]. Dans PingCastle (Acte 3), la finding apparaît comme « LDAP signing not required » / « LDAP channel binding not configured » — score “Stale Objects” / “Anomalies” élevé.

  4. Moindre privilège : chaque utilisateur AD reçoit uniquement le groupe correspondant à son rôle (ex. e.bernardG-TAAF-Biologie uniquement). Ce groupe est mappé à un seul dossier NextCloud (Biologie-Marine/). Conséquence : un compte compromis n’ouvre que le périmètre de son rôle, pas tout NextCloud.

  5. Blast radius SSO : avant SSO, compromettre e.bernard = accès VPN. Avec SSO, compromettre e.bernard = accès VPN + NextCloud + (toutes les autres applis SSO). C’est ce qui s’est passé jour J : un seul phishing a ouvert l’accès au coffre CLASSIFIED-VAULT-X (via NextCloud) ET au VPN ET aux ressources internes. Compromis = SSO doit être protégé par MFA forte + monitoring d’auth anormale.

  6. MFA côté IdP : si la MFA est sur NextCloud uniquement, les autres applis SSO n’en bénéficient pas. En la posant sur l’IdP (Authentik), toutes les applis qui s’y fédèrent en héritent. C’est la bonne place architecturalement.

  • Bind avec un compte admin AD (au lieu d’un compte de service lecture-seule) → -10 % (mauvaise pratique). Doit être svc_nc_ldap avec uniquement Read sur l’OU.
  • Filtre LDAP (objectClass=*) au lieu d’un filtre restrictif → -5 % (perf + sécurité).
  • Pas de matrice de cloisonnement vérifiée (juste théorique) → -10 %.
  • Compte break-glass désactivé « pour faire propre » → -15 % (faute majeure).

À la fin de ce TP, e.bernard peut se connecter à NextCloud avec son compte AD. Les logs d’auth NextCloud sont désormais corrélables avec les logs AD (même identité, même sAMAccountName). C’est ce qui rend possible la règle Sigma du TP 1 — Détection Sigma :

“auth VPN e.bernard depuis IP externe 09:12Z” → corrèle avec “ouverture coffre NextCloud par e.bernard à 10:05Z

→ Sans cette intégration LDAP, les deux événements seraient des comptes différents dans deux logs séparés. Impossible de tracer la chaîne.


ÉlémentRéférence
Comptes valides / identitéATT&CK T1078 (Valid Accounts)
Bind LDAP en clairATT&CK T1557.002 (LLMNR/NBT-NS, MitM) — mitigation : chiffrement
MFA comme contre-mesureReco n°2 ANSSI · NIS 2 Art. 21
Cloisonnement par groupesMoindre privilège (ANSSI / IGI 1337)
Centralisation d’identité (risque blast radius)NIS 2 Art. 21 §2.j (gestion crises)

Prochain pas (Acte 3) : maintenant que l’AD protège NextCloud, on audite cet AD et on le met en conformité → TP Audit AD & conformité (PingCastle).