Paillasse/portail/public/js/contenus-infra-3.js
Adam Belkacemi 30e14b1c54 ajoute le portail Laravel : connexion prof/élève, session unique, gestion de classe, salle d'attente
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-08 02:01:58 +02:00

172 lines
44 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Cours complets · Infra lot 3 : Kubernetes, supervision, annuaire LDAP / Active Directory
(function () {
var reg = function (c) {
(window.CONTENUS_PRO = window.CONTENUS_PRO || []).unshift(c.cours);
(window.CONTENUS_PLUS = window.CONTENUS_PLUS || {})[c.cours.id] = c.plus;
(window.CONTENUS_EXEMPLES = window.CONTENUS_EXEMPLES || {})[c.cours.id] = c.exemples;
(window.CONTENUS_SCHEMAS = window.CONTENUS_SCHEMAS || {})[c.cours.id] = { termes: c.termes, figs: [] };
};
reg({
cours: { id: 'k8s', match: /Kubernetes|k8s|orchestr/i,
titre: 'Kubernetes : orchestrer des conteneurs en production', duree: '',
niveau: 'BUT R&T DevCloud · BUT Informatique · AIS · Master',
prerequis: ['Conteneurs Docker', 'Docker Compose', 'Réseau : DNS, NAT, équilibrage'],
competences: ['BUT R&T DevCloud · Déployer et exploiter une plateforme de conteneurs', 'AIS · Administrer une infrastructure cloud', 'Master · Architecture des systèmes distribués'],
intro: 'Compose pilote une machine. Quand l’application doit tenir la charge de milliers d’utilisateurs, survivre à la panne d’un serveur et se mettre à jour sans coupure, il faut un orchestrateur. Kubernetes répartit les conteneurs sur un groupe de machines, les relance quand ils tombent, les déplace quand un nœud disparaît et ajuste leur nombre à la demande. Toutes les offres cloud françaises (Scaleway Kapsule, OVHcloud Managed Kubernetes, Outscale) le proposent. Ce module présente son architecture, ses objets principaux et le diagnostic d’un déploiement en panne.',
cm: [
{ t: 'Architecture d’un cluster', d: '', html: 'Un cluster se compose d’un <b>plan de contrôle</b> et de <b>nœuds de travail</b>. Le plan de contrôle comprend l’<b>API server</b>, point d’entrée unique de toutes les commandes ; <b>etcd</b>, base clé-valeur qui stocke l’état du cluster ; le <b>scheduler</b>, qui choisit le nœud de chaque nouveau pod ; et le <b>controller manager</b>, qui fait converger l’état réel vers l’état désiré. Chaque nœud exécute <b>kubelet</b>, qui démarre les conteneurs via un moteur (containerd), et <b>kube-proxy</b> ou un équivalent qui programme le réseau des services.<br><br>Le principe central est la <b>boucle de réconciliation</b> : on déclare un état (« 3 répliques de cette image ») et des contrôleurs corrigent sans cesse tout écart. On ne dit jamais « démarre un conteneur », on décrit ce qui doit exister.' },
{ t: 'Pods, Deployments et ReplicaSets', d: '', html: 'Le <b>pod</b> est la plus petite unité : un ou plusieurs conteneurs qui partagent une adresse IP et des volumes. On ne crée presque jamais un pod directement : un <b>Deployment</b> décrit l’image, le nombre de répliques et la stratégie de mise à jour, et crée un <b>ReplicaSet</b> qui maintient ce nombre de pods. Une mise à jour d’image crée un nouveau ReplicaSet et fait basculer progressivement les pods (rolling update) ; <code>kubectl rollout undo</code> revient à la version précédente.', exemple: 'apiVersion: apps/v1\nkind: Deployment\nmetadata: { name: resa, namespace: vie-scolaire }\nspec:\n replicas: 3\n selector: { matchLabels: { app: resa } }\n template:\n metadata: { labels: { app: resa } }\n spec:\n containers:\n - name: app\n image: registre.lycee.local/resa:9c1e4f2\n ports: [{ containerPort: 8000 }]\n resources:\n requests: { cpu: 100m, memory: 128Mi }\n limits: { memory: 256Mi }\n readinessProbe: { httpGet: { path: /health, port: 8000 } }\n livenessProbe: { httpGet: { path: /health, port: 8000 }, initialDelaySeconds: 10 }' },
{ t: 'Services et Ingress', d: '', html: 'Les pods sont éphémères et changent d’adresse. Un <b>Service</b> fournit une adresse stable et un nom DNS (resa.vie-scolaire.svc.cluster.local) et répartit le trafic entre les pods dont les <b>labels</b> correspondent à son sélecteur. Le type <b>ClusterIP</b> est interne, <b>NodePort</b> ouvre un port sur chaque nœud, <b>LoadBalancer</b> demande un équilibreur au fournisseur cloud.<br><br>Pour le trafic HTTP, un <b>Ingress</b> route selon le nom d’hôte et le chemin vers les services, et termine TLS. Il nécessite un contrôleur d’Ingress (ingress-nginx, Traefik) ; cert-manager y ajoute des certificats Let’s Encrypt automatiques.', attention: 'Un Service qui ne sélectionne aucun pod (faute de frappe dans un label) ne renvoie aucune erreur à sa création : il n’a simplement aucun endpoint. kubectl get endpoints le révèle immédiatement.' },
{ t: 'Configuration, secrets et stockage', d: '', html: 'Les <b>ConfigMap</b> portent la configuration non sensible, les <b>Secret</b> les mots de passe et clés ; ils s’injectent en variables ou en fichiers. Les Secret ne sont qu’encodés en base64 par défaut : on active le chiffrement d’etcd et on limite leur lecture par RBAC.<br><br>Le stockage persistant passe par des <b>PersistentVolumeClaim</b> : le pod demande « 10 Gi en lecture-écriture », et une <b>StorageClass</b> provisionne le volume chez le fournisseur. Pour une base de données, on utilise un <b>StatefulSet</b>, qui donne à chaque réplique un nom et un volume stables.' },
{ t: 'Sondes, ressources et haute disponibilité', d: '', html: 'La <b>readinessProbe</b> indique si un pod peut recevoir du trafic : tant qu’elle échoue, le Service ne lui envoie rien. La <b>livenessProbe</b> indique s’il est vivant : en cas d’échec répété, kubelet redémarre le conteneur. Confondre les deux provoque des redémarrages en boucle au démarrage d’une application lente.<br><br>Les <b>requests</b> servent au scheduler pour placer les pods ; les <b>limits</b> plafonnent la consommation. Un conteneur qui dépasse sa limite mémoire est tué (OOMKilled). Le <b>HorizontalPodAutoscaler</b> ajuste le nombre de répliques selon la charge, et un <b>PodDisruptionBudget</b> garantit un nombre minimal de pods pendant une maintenance.' },
{ t: 'Accès et sécurité', d: '', html: 'L’accès à l’API passe par des certificats ou des jetons, et les droits par <b>RBAC</b> : Role et ClusterRole définissent des verbes sur des ressources, RoleBinding les attribue. Les <b>namespaces</b> séparent les équipes ou les environnements. Les <b>NetworkPolicy</b> filtrent le trafic entre pods : sans elles, tout pod peut joindre tout autre pod. Les Pod Security Standards interdisent les conteneurs privilégiés ou en root.' }
],
synthese: ['Plan de contrôle (API server, etcd, scheduler, contrôleurs) et nœuds (kubelet)', 'État désiré et boucle de réconciliation', 'Deployment → ReplicaSet → pods ; rollout et rollout undo', 'Service stable par labels, Ingress pour HTTP et TLS', 'ConfigMap, Secret, PVC et StatefulSet', 'readiness ≠ liveness ; requests et limits', 'RBAC, namespaces, NetworkPolicy'],
qcm: [
['Quel composant stocke l’état du cluster ?', ['kubelet', 'etcd', 'kube-proxy', 'Ingress'], 1, 'Base clé-valeur répliquée.'],
['Que se passe-t-il si l’on supprime un pod géré par un Deployment ?', ['Il disparaît définitivement', 'Le ReplicaSet en recrée un', 'Le Deployment est supprimé', 'Le cluster s’arrête'], 1, 'Réconciliation.'],
['Comment un Service trouve-t-il ses pods ?', ['Par leur IP', 'Par sélecteur de labels', 'Par leur nom', 'Par le nœud'], 1, 'Les endpoints suivent les labels.'],
['Une readinessProbe qui échoue provoque :', ['un redémarrage', 'le retrait du pod du Service', 'la suppression du nœud', 'rien'], 1, 'La liveness, elle, redémarre.'],
['Que signifie OOMKilled ?', ['Réseau coupé', 'Dépassement de la limite mémoire', 'Image absente', 'Droits insuffisants'], 1, 'Le noyau tue le conteneur.'],
['Quel objet pour une base de données répliquée ?', ['Deployment', 'StatefulSet', 'DaemonSet', 'Job'], 1, 'Identités et volumes stables.'],
['Sans NetworkPolicy, les pods :', ['sont isolés', 'peuvent tous se joindre', 'n’ont pas de réseau', 'ne sortent pas'], 1, 'Tout est ouvert par défaut.']
],
td: [
{ n: 'Application', c: 'Écrire le Service ClusterIP et l’Ingress qui publient le Deployment resa sur resa.lycee.fr en HTTPS.', r: 'Service : selector app: resa, port 80 → targetPort 8000.\nIngress : host resa.lycee.fr, path /, backend service resa port 80, tls secretName resa-tls, annotation cert-manager.io/cluster-issuer.' },
{ n: 'Application', c: 'Mettre à jour l’image vers le tag 51ab0d7, suivre le déploiement, puis revenir en arrière.', r: 'kubectl -n vie-scolaire set image deploy/resa app=registre.lycee.local/resa:51ab0d7\nkubectl -n vie-scolaire rollout status deploy/resa\nkubectl -n vie-scolaire rollout undo deploy/resa' },
{ n: 'Approfondissement', c: 'Écrire une NetworkPolicy qui n’autorise vers la base PostgreSQL que les pods labellisés app: resa.', r: 'podSelector: { matchLabels: { app: postgres } }, policyTypes: [Ingress], ingress: [{ from: [{ podSelector: { matchLabels: { app: resa } } }], ports: [{ port: 5432 }] }]' }
],
tp: { type: 'Lab VM', url: 'apercu-labs.html', desc: 'Un cluster k3s à trois nœuds.', etapes: ['Déployer l’application en 3 répliques', 'La publier par Service et Ingress', 'Tuer un pod et observer la réconciliation', 'Mettre à jour puis revenir en arrière', 'Isoler la base par NetworkPolicy'] },
plusLoin: [['Documentation Kubernetes (fr)', 'https://kubernetes.io/fr/docs/home/'], ['k3s', 'https://k3s.io/'], ['ANSSI · Recommandations de sécurité relatives au déploiement de conteneurs', 'https://cyber.gouv.fr/publications/recommandations-de-securite-relatives-au-deploiement-de-conteneurs-docker']] },
plus: { cas: { titre: '', texte: '' },
resolu: { enonce: 'Après la mise à jour de l’application de réservation, le site renvoie « 503 Service Temporarily Unavailable ». Diagnostiquer et rétablir.', etapes: [
['Regarder les pods', 'kubectl -n vie-scolaire get pods -l app=resa\nNAME READY STATUS RESTARTS\nresa-7d9f6c5b8-2xkq4 0/1 CrashLoopBackOff 6\nresa-7d9f6c5b8-h7m2p 0/1 CrashLoopBackOff 6\n→ Aucun pod n’est prêt : l’Ingress n’a aucun backend, d’où les 503.'],
['Lire les événements et les journaux', 'kubectl -n vie-scolaire describe pod resa-7d9f6c5b8-2xkq4 | tail -3\nWarning Unhealthy Liveness probe failed: Get "http://10.42.1.17:8000/health": connection refused\nWarning BackOff Back-off restarting failed container\nkubectl -n vie-scolaire logs resa-7d9f6c5b8-2xkq4 --previous | tail -1\nRunning database migrations… (this may take 40s)\n→ La nouvelle version exécute des migrations au démarrage ; la livenessProbe démarre à 10 s et tue le conteneur avant la fin.'],
['Rétablir immédiatement', 'kubectl -n vie-scolaire rollout undo deploy/resa\nkubectl -n vie-scolaire rollout status deploy/resa\ndeployment "resa" successfully rolled out\n→ L’ancienne version est revenue ; le site répond.'],
['Corriger la cause', 'Migrations déplacées dans un Job exécuté avant le déploiement, et ajout d’une startupProbe :\nstartupProbe: { httpGet: { path: /health, port: 8000 }, failureThreshold: 30, periodSeconds: 5 }\n→ La liveness n’est évaluée qu’une fois la startupProbe réussie.'],
['Redéployer et documenter', 'kubectl apply -f resa.yaml ; kubectl -n vie-scolaire get pods -l app=resa\n3/3 Running\n→ Compte rendu : cause (liveness trop agressive face à des migrations), impact, rollback, correction, et test en préproduction avec une base de taille réelle.']
] },
erreurs: ['Confondre readiness et liveness', 'Pas de requests ni de limits', 'Utiliser latest comme image', 'Laisser les Secret non chiffrés et lisibles par tous', 'Aucune NetworkPolicy', 'Faute de label entre Service et pods', 'Base de données en Deployment sans volume persistant'],
memo: [['Commande', 'Usage'], ['kubectl get pods -A -o wide', 'tous les pods et leur nœud'], ['kubectl describe pod <p>', 'événements, sondes, raisons d’échec'], ['kubectl logs <p> --previous', 'journaux du conteneur précédent'], ['kubectl get events --sort-by=.lastTimestamp', 'derniers événements'], ['kubectl get endpoints <svc>', 'pods réellement derrière un Service'], ['kubectl rollout status|undo deploy/<d>', 'suivre ou annuler un déploiement'], ['kubectl exec -it <p> -- sh', 'shell dans un pod'], ['kubectl top pods', 'consommation CPU et mémoire'], ['kubectl apply -f fichier.yaml', 'appliquer un état désiré'], ['kubectl auth can-i <verbe> <ressource>', 'tester des droits RBAC']],
examen: { titre: 'Sujet type · 20 points', q: ['Décrire l’architecture d’un cluster. (4 pts)', 'Écrire Deployment, Service et Ingress pour une application donnée. (8 pts)', 'Expliquer readiness, liveness et startup probes. (3 pts)', 'Diagnostiquer un CrashLoopBackOff à partir de sorties fournies. (3 pts)', 'Citer deux mesures de sécurité. (2 pts)'], r: ['API server, etcd, scheduler, contrôleurs, kubelet', 'voir cours', 'trafic, redémarrage, démarrage lent', 'describe et logs --previous', 'RBAC, NetworkPolicy'] },
prof: { deroule: [['Ouverture', 'Arrêter un serveur Compose en direct, puis un nœud Kubernetes'], ['Cours', 'Architecture et réconciliation'], ['Pratique', 'Lab k3s'], ['Incident', 'CrashLoopBackOff'], ['Clôture', 'Quiz flash']], diff: 'Élèves en difficulté : manifestes à compléter. Élèves avancés : Helm, HPA, GitOps avec Argo CD.', eval: 'Lab validé, sujet type.' } },
exemples: [
['Voir où tournent les pods', 'Un nœud va être mis en maintenance.', 'kubectl get pods -n vie-scolaire -o wide', 'NAME READY STATUS NODE\nresa-6b8c7d-4kxz2 1/1 Running noeud-1\nresa-6b8c7d-9mpq7 1/1 Running noeud-1\nresa-6b8c7d-tt2r8 1/1 Running noeud-2', 'Deux répliques sont sur noeud-1 : drainer ce nœud en coupe deux sur trois. Un PodDisruptionBudget minAvailable: 2 et une règle d’anti-affinité répartiraient mieux la charge.'],
['Service sans endpoints', 'Le site renvoie 503 alors que les pods tournent.', 'kubectl -n vie-scolaire get endpoints resa', 'NAME ENDPOINTS AGE\nresa <none> 3d', 'Aucun pod ne correspond au sélecteur du Service. On compare kubectl get svc resa -o yaml (selector app: resa) avec les labels des pods (app: reservation) : faute de nommage.'],
['Conteneur tué pour mémoire', 'Redémarrages fréquents.', 'kubectl -n vie-scolaire describe pod resa-6b8c7d-4kxz2 | grep -A2 "Last State"', 'Last State: Terminated\n Reason: OOMKilled\n Exit Code: 137', 'La limite de 256 Mi est trop basse pour la charge actuelle. On mesure avec kubectl top pods puis on ajuste requests et limits.'],
['Suivre une mise à jour', 'Déploiement d’une nouvelle version.', 'kubectl -n vie-scolaire rollout status deploy/resa', 'Waiting for deployment "resa" rollout to finish: 1 of 3 updated replicas are available...\ndeployment "resa" successfully rolled out', 'Les pods sont remplacés un à un ; le service reste disponible pendant la mise à jour.'],
['Tester un droit RBAC', 'Un enseignant doit pouvoir lire les journaux de son namespace.', 'kubectl auth can-i get pods/log -n vie-scolaire --as prof-sio', 'yes', 'La commande vérifie les droits effectifs sans les tester réellement.'],
['Lire les derniers événements', 'Pod en Pending.', 'kubectl -n vie-scolaire get events --sort-by=.lastTimestamp | tail -2', 'Warning FailedScheduling pod/db-0 0/3 nodes are available: 3 Insufficient memory.', 'Aucun nœud n’a assez de mémoire libre pour la request demandée : réduire la request ou ajouter un nœud.']
],
termes: ['Kubernetes', 'cluster', 'pod', 'Deployment', 'ReplicaSet', 'StatefulSet', 'Service', 'ClusterIP', 'Ingress', 'ConfigMap', 'Secret', 'PersistentVolumeClaim', 'namespace', 'etcd', 'kubelet', 'API server', 'scheduler', 'readinessProbe', 'livenessProbe', 'startupProbe', 'requests', 'limits', 'OOMKilled', 'CrashLoopBackOff', 'RBAC', 'NetworkPolicy', 'kubectl', 'rollout', 'k3s']
});
reg({
cours: { id: 'supervision', match: /supervision|Zabbix|Prometheus|Grafana|monitoring|Nagios/i,
titre: 'Supervision : mesurer, alerter et anticiper avec Prometheus et Zabbix', duree: '',
niveau: 'BTS SIO SISR · BTS CIEL IR · BUT R&T · TSSR / AIS',
prerequis: ['Diagnostic réseau en ligne de commande', 'Services systemd'],
competences: ['BTS SIO SISR · Bloc 2 · Superviser une infrastructure', 'BTS CIEL · C09 · Maintenir', 'TSSR · Superviser l’infrastructure'],
intro: 'Un service informatique qui apprend une panne par un appel d’utilisateur a déjà perdu. La supervision mesure en permanence l’état des serveurs, des réseaux et des applications, déclenche une alerte avant que les utilisateurs ne soient gênés et conserve l’historique qui permet de comprendre un incident ou d’anticiper une saturation. Ce module présente les notions (métriques, seuils, alertes), puis les deux outils les plus répandus dans les établissements et les entreprises : Zabbix et le couple Prometheus-Grafana.',
cm: [
{ t: 'Que superviser ?', d: '', html: 'On distingue la <b>disponibilité</b> (le service répond-il ?), la <b>performance</b> (en combien de temps ?), la <b>capacité</b> (reste-t-il de la place, de la mémoire, de la bande passante ?) et les <b>erreurs</b> (taux de réponses 5xx, échecs de sauvegarde). Pour une application, la méthode des « quatre signaux d’or » résume l’essentiel : latence, trafic, erreurs, saturation.<br><br>On supervise à plusieurs niveaux : matériel (disques, température), système (CPU, mémoire, charge, espace disque), réseau (interfaces, pertes), services (ports, processus), et surtout <b>expérience utilisateur</b> : une sonde qui se connecte réellement à l’ENT et vérifie que la page de connexion s’affiche en moins de deux secondes.' },
{ t: 'Collecte : agent, SNMP, export', d: '', html: 'Trois modes de collecte coexistent. Un <b>agent</b> installé sur la machine (Zabbix agent, node_exporter) remonte des métriques système détaillées. <b>SNMP</b> interroge les équipements réseau qui ne peuvent pas recevoir d’agent : switchs, bornes, onduleurs, imprimantes ; on lit des valeurs identifiées par des OID dans des MIB. Les applications modernes <b>exposent</b> elles-mêmes leurs métriques sur une page HTTP (/metrics).<br><br>SNMPv1 et v2c transmettent la communauté (le « mot de passe ») en clair ; on utilise <b>SNMPv3</b>, avec authentification et chiffrement, ou à défaut on limite v2c en lecture seule à l’adresse du serveur de supervision.' },
{ t: 'Prometheus et Grafana', d: '', html: '<b>Prometheus</b> vient <b>chercher</b> (pull) les métriques des cibles à intervalle régulier et les stocke en séries temporelles, chaque série étant identifiée par un nom et des <b>labels</b> (instance, job, mountpoint). Le langage <b>PromQL</b> interroge ces séries : taux, moyennes, prédictions. Les <b>règles d’alerte</b> sont évaluées par Prometheus et envoyées à <b>Alertmanager</b>, qui regroupe, déduplique et notifie par courriel, messagerie ou SMS. <b>Grafana</b> affiche les tableaux de bord.', exemple: '# Espace disque libre en %\n100 * node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}\n\n# Règle : disque plein dans moins de 24 h au rythme actuel\n- alert: DisquePleinSous24h\n expr: predict_linear(node_filesystem_avail_bytes{mountpoint="/"}[6h], 24*3600) < 0\n for: 30m\n labels: { severity: warning }\n annotations: { summary: "{{ $labels.instance }} : disque plein sous 24 h" }' },
{ t: 'Zabbix', d: '', html: '<b>Zabbix</b> est une solution intégrée très répandue dans les collectivités et les établissements : serveur, base de données, interface web et agents. On y définit des <b>hôtes</b>, auxquels on applique des <b>modèles</b> (templates) qui regroupent <b>éléments</b> (items, les valeurs collectées), <b>déclencheurs</b> (triggers, les conditions d’alerte) et graphiques. Les modèles fournis couvrent Linux, Windows, les principaux switchs et les services courants. La découverte automatique (LLD) crée les éléments pour chaque disque ou chaque interface détectée.' },
{ t: 'Bien alerter', d: '', html: 'Une alerte doit être <b>actionnable</b> : si personne ne doit rien faire en la recevant, ce n’est pas une alerte mais une information pour un tableau de bord. Trop d’alertes produisent la <b>fatigue d’alerte</b> : l’équipe ne les lit plus, et la vraie panne passe inaperçue.<br><br>Les bonnes pratiques : alerter sur les symptômes vus par l’utilisateur plutôt que sur chaque cause possible ; ajouter une durée (for: 5m) pour ignorer les pics d’une seconde ; utiliser des seuils prédictifs (plein dans 24 h) plutôt que fixes ; hiérarchiser (info, avertissement, critique) ; et regrouper les alertes dépendantes : si le routeur d’un site tombe, on veut une alerte, pas cinquante.' },
{ t: 'Journaux centralisés', d: '', html: 'Les métriques disent qu’il se passe quelque chose ; les <b>journaux</b> disent quoi. On les centralise pour les consulter en un seul endroit et les conserver même si un serveur est compromis : rsyslog ou journald vers un serveur central, ou des piles comme Loki avec Grafana, ou Elasticsearch. La centralisation est aussi une exigence de sécurité : l’ANSSI recommande de conserver et d’horodater les journaux d’authentification et d’administration.' }
],
synthese: ['Disponibilité, performance, capacité, erreurs ; latence, trafic, erreurs, saturation', 'Agent, SNMP (v3), métriques exposées', 'Prometheus : pull, séries à labels, PromQL, Alertmanager ; Grafana pour l’affichage', 'Zabbix : hôtes, modèles, éléments, déclencheurs', 'Alertes actionnables, durée, seuils prédictifs, dépendances', 'Journaux centralisés et conservés'],
qcm: [
['Quel protocole pour superviser un switch sans agent ?', ['SSH', 'SNMP', 'SMTP', 'DHCP'], 1, 'Lecture d’OID.'],
['Pourquoi préférer SNMPv3 ?', ['Plus rapide', 'Authentification et chiffrement', 'Plus de métriques', 'Obligatoire'], 1, 'v2c envoie la communauté en clair.'],
['Prometheus collecte les métriques en mode :', ['push', 'pull', 'SNMP trap', 'courriel'], 1, 'Il interroge les cibles.'],
['Que fait for: 5m dans une règle d’alerte ?', ['Répète l’alerte', 'N’alerte que si la condition dure 5 minutes', 'Supprime l’alerte', 'Envoie 5 messages'], 1, 'Ignore les pics.'],
['Qu’est-ce qu’une alerte actionnable ?', ['Une alerte rouge', 'Une alerte qui demande une action précise', 'Une alerte fréquente', 'Une alerte par SMS'], 1, 'Sinon c’est du bruit.'],
['Dans Zabbix, un déclencheur est :', ['une valeur collectée', 'une condition qui génère un problème', 'un graphique', 'un agent'], 1, 'Trigger.']
],
td: [
{ n: 'Application', c: 'Lister ce qu’il faut superviser pour l’ENT d’un lycée, du matériel à l’expérience utilisateur, avec un seuil pour chaque élément.', r: 'Disque < 15 % · mémoire > 90 % pendant 10 min · charge > nb de cœurs · port 443 fermé · certificat expirant < 14 j · page de connexion > 2 s · taux de 5xx > 2 % · sauvegarde de la nuit en échec.' },
{ n: 'Application', c: 'Écrire la requête PromQL du taux d’erreurs HTTP 5xx sur 5 minutes, et la règle d’alerte associée.', r: 'sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) > 0.02 avec for: 10m.' },
{ n: 'Approfondissement', c: 'Le routeur du site B tombe : 40 alertes arrivent en même temps. Proposer la configuration pour n’en recevoir qu’une.', r: 'Zabbix : dépendance des déclencheurs des hôtes du site B envers celui du routeur. Alertmanager : inhibit_rules qui masquent les alertes d’un site quand l’alerte « routeur injoignable » du même site est active.' }
],
tp: { type: 'Lab VM', url: 'apercu-labs.html', desc: 'Prometheus, node_exporter, Alertmanager et Grafana sur deux VM.', etapes: ['Installer node_exporter', 'Déclarer la cible dans Prometheus', 'Créer un tableau de bord Grafana', 'Écrire une alerte disque prédictive', 'Remplir le disque et recevoir l’alerte'] },
plusLoin: [['Documentation Prometheus', 'https://prometheus.io/docs/'], ['Documentation Zabbix', 'https://www.zabbix.com/documentation/current/fr/manual'], ['Google SRE Book · Monitoring Distributed Systems', 'https://sre.google/sre-book/monitoring-distributed-systems/']] },
plus: { cas: { titre: '', texte: '' },
resolu: { enonce: 'Lundi 7 h 50 : l’alerte « DisquePleinSous24h » est arrivée à 2 h sur le serveur de fichiers, sans que personne ne réagisse. À 7 h 45 le disque est plein et les enseignants ne peuvent plus enregistrer. Rétablir puis fiabiliser la chaîne d’alerte.', etapes: [
['Rétablir le service', 'df -h /srv\n/dev/sdb1 500G 500G 0 100% /srv\nsudo du -xh --max-depth=2 /srv | sort -h | tail -3\n180G /srv/partage/tmp/exports-pronote\n→ Un script d’export mal configuré écrit un fichier toutes les minutes depuis vendredi.'],
['Arrêter la cause et libérer de la place', 'sudo systemctl stop export-pronote.timer\nsudo find /srv/partage/tmp/exports-pronote -mtime +0 -delete\ndf -h /srv\n/dev/sdb1 500G 322G 178G 65% /srv\n→ Les enseignants peuvent de nouveau enregistrer.'],
['Comprendre pourquoi l’alerte n’a servi à rien', 'amtool alert query DisquePleinSous24h\nalertname=DisquePleinSous24h severity=warning instance=fichiers:9100\n→ L’alerte a bien été émise, mais en severity warning, routée vers une adresse de courriel lue seulement en journée.'],
['Corriger le routage', 'route:\n routes:\n - matchers: [severity="critical"]\n receiver: astreinte-sms\n# nouvelle règle : disque plein sous 6 h → critical\n→ L’alerte à 24 h reste un avertissement par courriel ; une seconde règle à 6 h devient critique et part vers l’astreinte.'],
['Superviser la cause', '→ Ajout d’une alerte sur le nombre de fichiers créés par heure dans /srv/partage/tmp, et correction du script d’export (rotation des anciens fichiers). Compte rendu : l’outil avait détecté le problème six heures à l’avance ; le défaut était dans l’organisation de la réponse.']
] },
erreurs: ['Alerter sur tout, sans hiérarchie', 'Seuils fixes sans durée', 'Aucune supervision de l’expérience utilisateur', 'SNMP v2c en écriture avec la communauté public', 'Alertes envoyées à une boîte que personne ne lit', 'Oublier de superviser les sauvegardes et les certificats'],
memo: [['Outil / commande', 'Usage'], ['curl -s localhost:9100/metrics | head', 'vérifier un node_exporter'], ['promtool check config prometheus.yml', 'valider la configuration'], ['promtool check rules regles.yml', 'valider les règles d’alerte'], ['amtool alert query', 'alertes actives dans Alertmanager'], ['snmpwalk -v3 -l authPriv … <hôte> IF-MIB::ifOperStatus', 'lire l’état des ports d’un switch'], ['zabbix_get -s <hôte> -k system.cpu.load', 'tester un élément Zabbix'], ['systemctl status zabbix-agent2', 'état de l’agent'], ['journalctl -u prometheus', 'journaux du serveur'], ['rate(), increase(), predict_linear()', 'fonctions PromQL essentielles']],
examen: { titre: 'Sujet type · 20 points', q: ['Proposer un plan de supervision pour un service donné. (6 pts)', 'Comparer agent, SNMP et métriques exposées. (4 pts)', 'Écrire deux règles d’alerte avec seuils et durées. (5 pts)', 'Analyser un incident de fatigue d’alerte. (5 pts)'], r: ['matériel → expérience utilisateur', 'voir cours', 'expr + for + severity', 'actionnable, hiérarchie, dépendances'] },
prof: { deroule: [['Ouverture', 'Quelle panne avez-vous apprise par un utilisateur ?'], ['Cours', 'Quoi superviser, comment collecter'], ['Pratique', 'Lab Prometheus et Grafana'], ['Incident', 'Alerte émise mais ignorée'], ['Clôture', 'Quiz flash']], diff: 'Élèves en difficulté : tableau de bord importé, une seule alerte. Élèves avancés : SNMPv3, Loki, inhibitions.', eval: 'Alerte reçue pendant le lab, sujet type.' } },
exemples: [
['Vérifier une cible Prometheus', 'Un serveur n’apparaît plus dans Grafana.', 'curl -s http://prometheus:9090/api/v1/targets | jq -r \'.data.activeTargets[] | "\\(.labels.instance) \\(.health) \\(.lastError)"\'', 'fichiers:9100 up \nweb1:9100 down Get "http://web1:9100/metrics": dial tcp 10.62.40.21:9100: connect: connection refused', 'node_exporter ne tourne plus sur web1 (ou le pare-feu bloque 9100). systemctl status prometheus-node-exporter sur web1.'],
['Lire l’état des ports d’un switch', 'Un bâtiment signale des coupures.', 'snmpwalk -v3 -l authPriv -u supervision -a SHA -A "…" -x AES -X "…" sw-bat-b IF-MIB::ifOperStatus | grep -v up', 'IF-MIB::ifOperStatus.10017 = INTEGER: down(2)', 'Le port 17 est tombé. Avec ifAlias, on retrouve qu’il s’agit de la liaison montante vers le bâtiment B.'],
['Prédire la saturation', 'Planifier l’achat de disques.', 'predict_linear(node_filesystem_avail_bytes{instance="fichiers:9100",mountpoint="/srv"}[7d], 30*24*3600)', '-4.2e+10', 'Au rythme des sept derniers jours, il manquera environ 42 Go dans 30 jours : on commande avant l’incident.'],
['Tester un élément Zabbix', 'Un élément reste vide dans l’interface.', 'zabbix_get -s 10.62.40.10 -k vfs.fs.size[/srv,pfree]', 'ZBX_NOTSUPPORTED: Cannot obtain filesystem information: [2] No such file or directory', 'Le point de montage n’existe pas sur cet hôte : le modèle appliqué ne correspond pas à la machine. On utilise la découverte automatique des systèmes de fichiers.'],
['Voir les alertes actives', 'Point d’astreinte du matin.', 'amtool alert query --active', 'Alertname Starts At Summary\nCertificatExpire 2026-09-28 06:00 ent.lycee.fr expire dans 9 jours\nSauvegardeEchec 2026-09-30 03:12 sauvegarde nocturne de db1 en échec', 'Deux actions claires pour la journée : renouveler le certificat (vérifier certbot) et relancer la sauvegarde de db1.'],
['Valider les règles avant rechargement', 'Nouvelle règle d’alerte.', 'promtool check rules /etc/prometheus/regles.yml', 'Checking /etc/prometheus/regles.yml\n FAILED:\n group "systeme", rule 3: could not parse expression: unexpected "}"', 'Une accolade en trop dans la règle 3. Sans ce contrôle, Prometheus aurait refusé de recharger toute la configuration.']
],
termes: ['supervision', 'métrique', 'alerte', 'seuil', 'SNMP', 'SNMPv3', 'OID', 'MIB', 'agent', 'Prometheus', 'PromQL', 'node_exporter', 'Alertmanager', 'Grafana', 'Zabbix', 'déclencheur', 'modèle', 'predict_linear', 'rate', 'fatigue d’alerte', 'Loki', 'rsyslog']
});
reg({
cours: { id: 'annuaire', match: /LDAP|Active Directory|annuaire|AD DS|GPO|Samba/i,
titre: 'Annuaires : LDAP, Active Directory, GPO et Samba', duree: '',
niveau: 'BTS SIO SISR · BTS CIEL IR · BUT R&T · TSSR',
prerequis: ['DNS : résolution et zones', 'Droits et utilisateurs'],
competences: ['BTS SIO SISR · Bloc 2 · Administrer les services d’annuaire', 'BTS SIO · Bloc 3 · Gérer les identités et les accès', 'TSSR · Exploiter un annuaire'],
intro: 'Dans un établissement de 1 500 comptes, créer chaque utilisateur sur chaque serveur est impossible. L’annuaire centralise les identités, les groupes et les droits : un élève se connecte avec le même identifiant sur n’importe quel poste, au Wi-Fi, à l’imprimante et aux applications. Active Directory domine dans les établissements et les entreprises ; il repose sur des standards ouverts (LDAP, Kerberos, DNS) que l’on retrouve dans Samba et OpenLDAP. Ce module en décrit le fonctionnement, l’administration et la sécurisation.',
cm: [
{ t: 'LDAP : un arbre d’objets', d: '', html: 'LDAP (Lightweight Directory Access Protocol) est le protocole d’interrogation des annuaires. Les données forment un <b>arbre</b> (DIT) : chaque entrée a un <b>DN</b> (Distinguished Name) unique, lu de la feuille vers la racine, par exemple <code>CN=Léa M.,OU=SIO1,OU=Eleves,DC=lycee,DC=local</code>. Les entrées appartiennent à des <b>classes d’objets</b> (user, group, organizationalUnit) qui définissent leurs <b>attributs</b> (sAMAccountName, mail, memberOf). LDAP écoute sur le port 389, LDAPS (chiffré) sur 636.' },
{ t: 'Active Directory : domaine, forêt, contrôleurs', d: '', html: 'Un <b>domaine</b> AD regroupe comptes, groupes et ordinateurs sous une même autorité, avec un nom DNS (lycee.local, ou mieux un sous-domaine d’un domaine possédé : ad.lycee-exemple.fr). Les <b>contrôleurs de domaine</b> (DC) hébergent l’annuaire et le répliquent entre eux ; on en installe au moins deux. Plusieurs domaines peuvent former une <b>forêt</b>.<br><br>AD dépend entièrement du <b>DNS</b> : les clients trouvent les DC grâce aux enregistrements SRV (<code>_ldap._tcp.dc._msdcs.lycee.local</code>). Un poste qui n’utilise pas le DNS du domaine ne peut pas le rejoindre. L’authentification repose sur <b>Kerberos</b>, qui impose des horloges synchronisées à cinq minutes près.' },
{ t: 'Organiser : OU, groupes et délégation', d: '', html: 'Les <b>unités d’organisation</b> (OU) rangent les objets pour appliquer des stratégies et déléguer l’administration : OU Eleves, Professeurs, Administration, Ordinateurs\\Salles. Les <b>groupes</b> portent les droits. La méthode AGDLP résume la bonne pratique : les comptes (A) vont dans des groupes globaux par fonction (G, « Profs-SIO »), placés dans des groupes locaux de domaine par ressource (DL, « Partage-SIO-Modification »), auxquels on donne les permissions (P). On ne donne jamais un droit directement à un utilisateur.' },
{ t: 'Stratégies de groupe (GPO)', d: '', html: 'Une <b>GPO</b> applique des paramètres aux ordinateurs et aux utilisateurs d’une OU : fond d’écran, lecteurs réseau, imprimantes, mises à jour, pare-feu, restrictions, déploiement de logiciels. L’ordre d’application est LSDOU : local, site, domaine, OU (de la plus haute à la plus basse) ; la dernière appliquée l’emporte, sauf blocage ou application forcée. <code>gpupdate /force</code> applique immédiatement, <code>gpresult /r</code> montre les GPO effectivement reçues.' },
{ t: 'Samba et intégration Linux', d: '', html: '<b>Samba</b> partage des fichiers et des imprimantes avec les postes Windows (protocole SMB) et peut même servir de <b>contrôleur de domaine</b> compatible AD, solution répandue dans les établissements attachés aux logiciels libres. Un serveur Linux rejoint un domaine AD avec <b>realmd</b> et <b>SSSD</b> (<code>realm join</code>) : les comptes du domaine s’y connectent en SSH et les groupes AD pilotent les droits sudo.', exemple: 'sudo realm discover lycee.local\nsudo realm join -U administrateur lycee.local\nid lea.martin@lycee.local\nuid=1854201103(lea.martin@lycee.local) … groupes=…(eleves-sio1@lycee.local)' },
{ t: 'Sécurité de l’annuaire', d: '', html: 'L’annuaire est la cible principale des attaquants : compromettre un compte d’administrateur du domaine, c’est posséder tout le réseau. Les recommandations de l’ANSSI s’organisent en niveaux (tiering) : les comptes d’administration du domaine ne se connectent qu’aux DC, jamais à un poste utilisateur. Autres mesures : comptes d’administration séparés des comptes du quotidien, mots de passe longs, <b>LAPS</b> pour des mots de passe administrateur local différents sur chaque poste, désactivation des protocoles anciens (NTLMv1, SMBv1), LDAPS ou signature LDAP, et audit régulier avec des outils comme PingCastle.' }
],
synthese: ['LDAP : arbre, DN, classes et attributs ; 389 et 636', 'AD : domaine, forêt, au moins deux DC ; dépend du DNS et de Kerberos', 'OU pour organiser et appliquer, groupes pour les droits (AGDLP)', 'GPO appliquées en LSDOU ; gpresult pour vérifier', 'Samba, realmd et SSSD pour Linux', 'Tiering, comptes séparés, LAPS, protocoles anciens désactivés'],
qcm: [
['Que désigne un DN ?', ['Un nom DNS', 'Le chemin unique d’une entrée dans l’arbre LDAP', 'Un groupe', 'Un port'], 1, 'Distinguished Name.'],
['Pourquoi un poste ne trouve-t-il pas le domaine ?', ['Pare-feu Windows', 'Il n’utilise pas le DNS du domaine', 'Mauvais fond d’écran', 'LAPS'], 1, 'Enregistrements SRV.'],
['Quel écart d’horloge maximal tolère Kerberos par défaut ?', ['1 s', '5 min', '1 h', 'Aucun'], 1, 'D’où NTP obligatoire.'],
['Où donner une permission sur un partage selon AGDLP ?', ['À l’utilisateur', 'À un groupe local de domaine', 'À l’OU', 'Au DC'], 1, 'Comptes → global → local → permission.'],
['Quelle commande montre les GPO reçues par un poste ?', ['gpupdate', 'gpresult /r', 'ipconfig', 'netstat'], 1, 'Résultat de la stratégie.'],
['Quel outil donne un mot de passe administrateur local différent à chaque poste ?', ['GPO', 'LAPS', 'SSSD', 'Kerberos'], 1, 'Local Administrator Password Solution.']
],
td: [
{ n: 'Application', c: 'Proposer l’arborescence d’OU et les groupes d’un lycée avec BTS SIO, sa salle de TP et le partage « Sujets » accessible en modification aux profs de SIO, en lecture aux élèves de SIO.', r: 'OU Utilisateurs\\Eleves\\SIO1, SIO2 · OU Utilisateurs\\Profs · OU Ordinateurs\\Salles\\B204 · groupes globaux G-Eleves-SIO, G-Profs-SIO · groupes locaux DL-Sujets-Lecture, DL-Sujets-Modif · permissions NTFS et partage sur ces DL.' },
{ n: 'Application', c: 'Écrire la requête ldapsearch qui liste les comptes de l’OU SIO1 avec leur adresse mail.', r: 'ldapsearch -H ldaps://dc1.lycee.local -D "cn=lecture,…" -W -b "OU=SIO1,OU=Eleves,DC=lycee,DC=local" "(objectClass=user)" sAMAccountName mail' },
{ n: 'Approfondissement', c: 'Expliquer pourquoi un administrateur du domaine ne doit pas ouvrir de session sur un poste d’élève.', r: 'Son jeton ou ses identifiants restent en mémoire du poste ; si celui-ci est compromis, l’attaquant les récupère et devient administrateur du domaine (modèle de tiering de l’ANSSI).' }
],
tp: { type: 'Lab VM', url: 'apercu-labs.html', desc: 'Un contrôleur Samba AD, un client Windows et un serveur Linux.', etapes: ['Provisionner le domaine Samba AD', 'Vérifier les enregistrements SRV', 'Créer OU, comptes et groupes', 'Joindre le serveur Linux avec realmd', 'Appliquer une GPO de lecteur réseau'] },
plusLoin: [['ANSSI · Recommandations de sécurité relatives à Active Directory', 'https://cyber.gouv.fr/publications/recommandations-de-securite-relatives-active-directory'], ['Samba Wiki · Setting up Samba as an AD DC', 'https://wiki.samba.org/index.php/Setting_up_Samba_as_an_Active_Directory_Domain_Controller'], ['PingCastle', 'https://www.pingcastle.com/']] },
plus: { cas: { titre: '', texte: '' },
resolu: { enonce: 'Ce matin, aucun élève de la salle B204 ne parvient à ouvrir de session (« La relation d’approbation entre cette station de travail et le domaine principal a échoué » sur certains postes, « L’heure du serveur diffère » sur d’autres). Les autres salles fonctionnent.', etapes: [
['Vérifier l’heure', 'Sur un poste de B204 (session locale) : w32tm /stripchart /computer:dc1.lycee.local /samples:1\n11:47:02, d:+00.0012s o:-00:07:41.3\n→ Le poste a 7 min 41 s de retard sur le DC : Kerberos refuse l’authentification au-delà de 5 minutes.'],
['Trouver pourquoi', 'w32tm /query /source\nLocal CMOS Clock\n→ Les postes de B204, réinstallés pendant les vacances à partir d’une image, ne prennent plus l’heure du domaine.'],
['Corriger l’heure', 'w32tm /config /syncfromflags:domhier /update\nnet stop w32time && net start w32time\nw32tm /resync\n→ Le poste se synchronise sur la hiérarchie du domaine.'],
['Réparer la relation d’approbation', 'Sur les postes au message « relation d’approbation » :\nTest-ComputerSecureChannel -Repair -Credential lycee\\technicien\nTrue\n→ Le mot de passe du compte ordinateur, restauré depuis une image ancienne, ne correspondait plus à celui de l’annuaire ; le canal sécurisé est réinitialisé.'],
['Généraliser et prévenir', '→ La correction est déployée par GPO sur l’OU Salles (source de temps du domaine) ; les images de poste sont préparées avec Sysprep et jointes au domaine après déploiement. Compte rendu rédigé.']
] },
erreurs: ['Postes qui n’utilisent pas le DNS du domaine', 'Horloges non synchronisées', 'Un seul contrôleur de domaine', 'Droits donnés directement aux utilisateurs', 'Administrateur du domaine utilisé sur les postes', 'Même mot de passe administrateur local partout', 'LDAP simple non chiffré'],
memo: [['Commande', 'Usage'], ['nslookup -type=SRV _ldap._tcp.dc._msdcs.lycee.local', 'trouver les contrôleurs de domaine'], ['ldapsearch -H ldaps://… -b … "(filtre)"', 'interroger l’annuaire'], ['gpupdate /force', 'appliquer les GPO'], ['gpresult /r', 'GPO effectivement appliquées'], ['w32tm /query /status', 'source et écart de temps'], ['Test-ComputerSecureChannel -Repair', 'réparer la relation avec le domaine'], ['samba-tool user create|list', 'gérer les comptes Samba AD'], ['samba-tool drs showrepl', 'état de la réplication'], ['realm join -U admin domaine', 'joindre un Linux au domaine'], ['id utilisateur@domaine', 'vérifier un compte depuis Linux']],
examen: { titre: 'Sujet type · 20 points', q: ['Décrire le rôle de DNS et Kerberos dans AD. (4 pts)', 'Proposer OU et groupes pour un cas donné selon AGDLP. (6 pts)', 'Expliquer l’ordre d’application des GPO et diagnostiquer une GPO non appliquée. (5 pts)', 'Citer cinq mesures de sécurité de l’annuaire. (5 pts)'], r: ['SRV, tickets, horloge', 'voir TD', 'LSDOU, gpresult', 'tiering, LAPS, comptes séparés, NTLMv1/SMBv1, audit'] },
prof: { deroule: [['Ouverture', 'Combien de mots de passe auriez-vous sans annuaire ?'], ['Cours', 'LDAP, AD, DNS, Kerberos'], ['Pratique', 'Lab Samba AD'], ['Incident', 'Heure et relation d’approbation'], ['Clôture', 'Quiz flash']], diff: 'Élèves en difficulté : arborescence fournie. Élèves avancés : audit PingCastle, tiering.', eval: 'Lab validé, sujet type.' } },
exemples: [
['Trouver les contrôleurs de domaine', 'Un poste ne rejoint pas le domaine.', 'nslookup -type=SRV _ldap._tcp.dc._msdcs.lycee.local', '_ldap._tcp.dc._msdcs.lycee.local SRV service location:\n priority = 0, weight = 100, port = 389, svr hostname = dc1.lycee.local\n priority = 0, weight = 100, port = 389, svr hostname = dc2.lycee.local', 'Les deux DC sont annoncés. Si la commande échoue, le poste n’interroge pas le DNS du domaine : on vérifie sa configuration DNS avant tout le reste.'],
['Chercher un compte', 'Retrouver les groupes d’un élève.', 'ldapsearch -LLL -H ldaps://dc1.lycee.local -D "CN=lecture,OU=Services,DC=lycee,DC=local" -W -b "DC=lycee,DC=local" "(sAMAccountName=lea.martin)" memberOf', 'dn: CN=Léa M.,OU=SIO1,OU=Eleves,DC=lycee,DC=local\nmemberOf: CN=G-Eleves-SIO,OU=Groupes,DC=lycee,DC=local', 'LDAPS chiffre l’échange ; le compte de lecture dédié n’a aucun autre droit.'],
['Vérifier les GPO d’un poste', 'Le lecteur réseau n’apparaît pas.', 'gpresult /r /scope:user', 'Objets Stratégie de groupe appliqués\n GPO-Eleves-Fond\nLes GPO suivants n’ont pas été appliqués car ils ont été filtrés\n GPO-Lecteurs-SIO\n Filtrage : Refusé (Sécurité)', 'La GPO des lecteurs est filtrée par sécurité : le groupe de l’élève n’a pas le droit « Appliquer la stratégie de groupe ».'],
['Contrôler la réplication', 'Un compte créé sur dc1 n’existe pas sur dc2.', 'sudo samba-tool drs showrepl | grep -A3 "INBOUND" | tail -3', 'DC=lycee,DC=local\n Default-First-Site-Name\\DC1 via RPC\n Last attempt @ … failed, result 1256 (WERR_NO_SUCH_SERVICE)', 'La réplication de dc1 vers dc2 échoue. On vérifie la résolution de dc1 depuis dc2 et l’ouverture des ports RPC.'],
['Joindre un Linux au domaine', 'Nouveau serveur Debian.', 'sudo realm join -U technicien lycee.local && realm list | grep -E "realm-name|configured"', 'realm-name: LYCEE.LOCAL\nconfigured: kerberos-member', 'Le serveur est membre ; les comptes du domaine peuvent s’y connecter selon les règles de realm permit.'],
['Repérer les mots de passe qui n’expirent pas', 'Audit des comptes.', 'Get-ADUser -Filter {PasswordNeverExpires -eq $true -and Enabled -eq $true} | Select Name', 'Name\n----\nsvc-sauvegarde\nancien.stagiaire', 'Un compte de stagiaire parti est encore actif avec un mot de passe éternel : on le désactive. Le compte de service doit devenir un compte de service géré (gMSA).']
],
termes: ['LDAP', 'LDAPS', 'DN', 'OU', 'Active Directory', 'domaine', 'forêt', 'contrôleur de domaine', 'Kerberos', 'SRV', 'GPO', 'LSDOU', 'AGDLP', 'gpupdate', 'gpresult', 'Samba', 'SSSD', 'realmd', 'LAPS', 'tiering', 'NTLM', 'SMB', 'ldapsearch', 'samba-tool']
});
})();