Initial lab release: Docker-based Active Directory lab
Complete Active Directory teaching environment based on dockurr/windows: - Windows Server domain controller, Windows 11 client, Debian 12 client - docker-compose orchestration, env-driven configuration - Bilingual documentation (FR + EN) for students - Dual approach (GUI + PowerShell) in every procedure - Instructor course plan and reference scripts - RDP launcher scripts for Linux, macOS and Windows Made by AcadéNice - https://acadenice.fr/
This commit is contained in:
commit
8e1b06e090
38 changed files with 3299 additions and 0 deletions
31
.env.example
Normal file
31
.env.example
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# lab_AD_Complet - configuration locale
|
||||
# Copiez ce fichier en .env et adaptez les valeurs avant le premier lancement.
|
||||
# Fait par AcadéNice - https://acadenice.fr/
|
||||
|
||||
AD_DOMAIN=corp.lab
|
||||
AD_DOMAIN_NETBIOS=CORP
|
||||
AD_ORG_NAME=CORP
|
||||
|
||||
# Doit respecter la politique AD : 10+ caractères, majuscule, minuscule, chiffre, spécial.
|
||||
AD_ADMIN_PASSWORD=AdminP@ss!2026
|
||||
AD_DEMO_PASSWORD=UserP@ss!2026
|
||||
|
||||
DC_RAM=6G
|
||||
DC_CPU=2
|
||||
DC_DISK=64G
|
||||
|
||||
CLIENT_RAM=4G
|
||||
CLIENT_CPU=2
|
||||
CLIENT_DISK=40G
|
||||
|
||||
DC_WINDOWS_VERSION=2022
|
||||
CLIENT_WINDOWS_VERSION=11
|
||||
|
||||
DC_WEB_PORT=8006
|
||||
DC_RDP_PORT=3389
|
||||
CLIENT_WEB_PORT=8009
|
||||
CLIENT_RDP_PORT=3391
|
||||
|
||||
VM_LANGUAGE=French
|
||||
VM_REGION=fr-FR
|
||||
VM_KEYBOARD=fr-FR
|
||||
21
.gitignore
vendored
Normal file
21
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# Secrets / configuration locale
|
||||
.env
|
||||
|
||||
# Storage des VMs Windows (plusieurs Go)
|
||||
storage/
|
||||
storage-*/
|
||||
|
||||
# Dossier partage RDP
|
||||
shared/*
|
||||
!shared/.gitkeep
|
||||
|
||||
# Artefacts OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
22
LICENSE
Normal file
22
LICENSE
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2026 AcadéNice - https://acadenice.fr/
|
||||
and lab_AD_Complet contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
131
README.md
Normal file
131
README.md
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
# lab_AD_Complet
|
||||
|
||||
Lab Active Directory reproductible, basé sur Docker, pour la formation et l'auto-apprentissage.
|
||||
|
||||
> English version : [README_EN.md](README_EN.md)
|
||||
|
||||
## Contenu du lab
|
||||
|
||||
Un environnement Active Directory complet, isolé, comprenant :
|
||||
|
||||
- **DC01** : contrôleur de domaine Windows Server (AD DS + DNS)
|
||||
- **PC01** : poste client Windows 11 destiné à être joint au domaine
|
||||
- **linux01** : poste client Debian 12 destiné à être joint au domaine (realmd + SSSD)
|
||||
|
||||
Tout est orchestré via un seul `docker-compose.yml`, entièrement configurable par variables d'environnement.
|
||||
|
||||
## Pré-requis
|
||||
|
||||
Le lab exige un accès à la virtualisation matérielle (KVM sous Linux, WSL2 + nested virt sous Windows).
|
||||
|
||||
| Système | Supporté | Remarques |
|
||||
|---|---|---|
|
||||
| Linux (kernel >= 5.x avec KVM) | Oui | Configuration la plus simple |
|
||||
| Windows 10/11 Pro + Docker Desktop | Oui | Activer la virtualisation imbriquée dans `.wslconfig` |
|
||||
| macOS Intel | Partiel | Performances dégradées, non recommandé |
|
||||
| macOS Apple Silicon (M1/M2/M3) | Non | Utilisez une VM Linux (UTM) - voir `docs/etudiant/fr/00-prerequis.md` |
|
||||
|
||||
Ressources minimales :
|
||||
|
||||
- 16 Go de RAM recommandés (12 Go minimum)
|
||||
- 80 Go d'espace disque libre (installation Windows + snapshots)
|
||||
- Processeur avec VT-x / AMD-V activé dans le BIOS
|
||||
|
||||
Scripts de vérification fournis :
|
||||
|
||||
```bash
|
||||
./scripts/check-prereqs.sh # Linux, macOS
|
||||
.\scripts\check-prereqs.ps1 # Windows
|
||||
```
|
||||
|
||||
## Démarrage rapide
|
||||
|
||||
```bash
|
||||
git clone <url-du-repo> lab_AD_Complet
|
||||
cd lab_AD_Complet
|
||||
cp .env.example .env # adaptez les variables
|
||||
./scripts/check-prereqs.sh
|
||||
docker compose up -d dc01
|
||||
```
|
||||
|
||||
L'installation de Windows Server se fait automatiquement en arrière-plan (20 à 40 minutes selon votre connexion). Suivez l'avancement via :
|
||||
|
||||
- Interface web : http://localhost:8006
|
||||
- Logs : `docker compose logs -f dc01`
|
||||
|
||||
Une fois Windows installé, la configuration AD (promotion, OU, utilisateurs, GPO, partages) reste à la charge de l'apprenant. Les guides détaillés sont dans `docs/etudiant/fr/`.
|
||||
|
||||
## Accès aux postes
|
||||
|
||||
Deux méthodes disponibles :
|
||||
|
||||
### Interface web (noVNC)
|
||||
|
||||
- DC : http://localhost:8006
|
||||
- PC Windows : http://localhost:8009
|
||||
- Utile pour observer le boot / l'installation, mais lente et sans copier-coller.
|
||||
|
||||
### RDP (recommandé)
|
||||
|
||||
```bash
|
||||
./scripts/rdp-dc.sh # ouvre une session RDP sur DC01
|
||||
./scripts/rdp-client.sh # ouvre une session RDP sur PC01
|
||||
```
|
||||
|
||||
Sous Windows :
|
||||
|
||||
```powershell
|
||||
.\scripts\rdp-dc.ps1
|
||||
```
|
||||
|
||||
RDP fournit un copier-coller natif, un partage de dossier (`\\tsclient\shared`) et de bien meilleures performances.
|
||||
|
||||
## Structure du projet
|
||||
|
||||
```
|
||||
lab_AD_Complet/
|
||||
docker-compose.yml Définit les 3 conteneurs
|
||||
.env.example Variables configurables
|
||||
linux-client/ Image Debian pré-équipée (SSSD/realmd)
|
||||
scripts/ Vérification de prérequis + lancement RDP
|
||||
shared/ Dossier partagé avec les VMs Windows via RDP
|
||||
docs/
|
||||
etudiant/ Guides d'apprentissage (FR + EN)
|
||||
formateur/ Supports et corrigés (non distribués aux étudiants)
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
- `docs/etudiant/fr/00-prerequis.md` : installation de Docker et vérifications
|
||||
- `docs/etudiant/fr/01-installation-lab.md` : premier démarrage du lab
|
||||
- `docs/etudiant/fr/02-promotion-dc.md` : promotion d'un contrôleur de domaine (GUI + PowerShell)
|
||||
- `docs/etudiant/fr/03-ou-utilisateurs-groupes.md` : arborescence OU, utilisateurs, groupes, AGDLP
|
||||
- `docs/etudiant/fr/04-gpo.md` : création et liaison de GPO
|
||||
- `docs/etudiant/fr/05-partages-ntfs.md` : partages SMB et permissions NTFS
|
||||
- `docs/etudiant/fr/06-jonction-poste-windows.md` : rejoindre PC01 au domaine
|
||||
- `docs/etudiant/fr/07-jonction-poste-linux.md` : rejoindre linux01 au domaine
|
||||
- `docs/etudiant/fr/troubleshooting.md` : problèmes fréquents
|
||||
|
||||
Chaque procédure est documentée en double approche : **interface graphique** (Server Manager, ADUC, GPMC) et **scripting PowerShell**.
|
||||
|
||||
## Arrêter le lab
|
||||
|
||||
```bash
|
||||
docker compose stop # arrêt sans perte d'état
|
||||
docker compose down # arrêt et suppression des conteneurs
|
||||
docker compose down -v # suppression complète y compris les disques VM
|
||||
```
|
||||
|
||||
Les disques Windows sont stockés dans `./storage-dc01/` et `./storage-pc01/` à la racine du projet. Supprimer ces dossiers revient à repartir d'une installation vierge.
|
||||
|
||||
## Licence
|
||||
|
||||
MIT - voir [LICENSE](LICENSE).
|
||||
|
||||
## Contribuer
|
||||
|
||||
Les contributions sont bienvenues (corrections, traductions, nouveaux exercices). Ouvrez une issue ou proposez un merge request.
|
||||
|
||||
---
|
||||
|
||||
Fait par [AcadéNice](https://acadenice.fr/).
|
||||
131
README_EN.md
Normal file
131
README_EN.md
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
# lab_AD_Complet
|
||||
|
||||
Reproducible Active Directory lab, based on Docker, for training and self-study.
|
||||
|
||||
> Version française : [README.md](README.md)
|
||||
|
||||
## Lab content
|
||||
|
||||
A complete, isolated Active Directory environment comprising:
|
||||
|
||||
- **DC01**: Windows Server domain controller (AD DS + DNS)
|
||||
- **PC01**: Windows 11 client workstation to join the domain
|
||||
- **linux01**: Debian 12 client to join the domain (realmd + SSSD)
|
||||
|
||||
Everything is orchestrated via a single `docker-compose.yml`, fully configurable via environment variables.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
The lab requires hardware virtualization access (KVM on Linux, WSL2 + nested virt on Windows).
|
||||
|
||||
| System | Supported | Notes |
|
||||
|---|---|---|
|
||||
| Linux (kernel >= 5.x with KVM) | Yes | Simplest setup |
|
||||
| Windows 10/11 Pro + Docker Desktop | Yes | Enable nested virtualization in `.wslconfig` |
|
||||
| macOS Intel | Partial | Degraded performance, not recommended |
|
||||
| macOS Apple Silicon (M1/M2/M3) | No | Use a Linux VM (UTM) - see `docs/etudiant/en/00-prerequisites.md` |
|
||||
|
||||
Minimum resources:
|
||||
|
||||
- 16 GB RAM recommended (12 GB minimum)
|
||||
- 80 GB free disk space (Windows install + snapshots)
|
||||
- CPU with VT-x / AMD-V enabled in BIOS
|
||||
|
||||
Check scripts provided:
|
||||
|
||||
```bash
|
||||
./scripts/check-prereqs.sh # Linux, macOS
|
||||
.\scripts\check-prereqs.ps1 # Windows
|
||||
```
|
||||
|
||||
## Quick start
|
||||
|
||||
```bash
|
||||
git clone <repo-url> lab_AD_Complet
|
||||
cd lab_AD_Complet
|
||||
cp .env.example .env # adapt variables
|
||||
./scripts/check-prereqs.sh
|
||||
docker compose up -d dc01
|
||||
```
|
||||
|
||||
Windows Server installation runs automatically in the background (20 to 40 minutes depending on your connection). Monitor progress via:
|
||||
|
||||
- Web UI: http://localhost:8006
|
||||
- Logs: `docker compose logs -f dc01`
|
||||
|
||||
Once Windows is installed, AD configuration (promotion, OUs, users, GPOs, shares) is left to the learner. Detailed guides are in `docs/etudiant/en/`.
|
||||
|
||||
## Accessing the hosts
|
||||
|
||||
Two methods available:
|
||||
|
||||
### Web UI (noVNC)
|
||||
|
||||
- DC: http://localhost:8006
|
||||
- Windows client: http://localhost:8009
|
||||
- Useful to observe boot / installation, but slow and no clipboard sync.
|
||||
|
||||
### RDP (recommended)
|
||||
|
||||
```bash
|
||||
./scripts/rdp-dc.sh # opens RDP session on DC01
|
||||
./scripts/rdp-client.sh # opens RDP session on PC01
|
||||
```
|
||||
|
||||
On Windows:
|
||||
|
||||
```powershell
|
||||
.\scripts\rdp-dc.ps1
|
||||
```
|
||||
|
||||
RDP provides native clipboard, folder redirection (`\\tsclient\shared`) and much better performance.
|
||||
|
||||
## Project structure
|
||||
|
||||
```
|
||||
lab_AD_Complet/
|
||||
docker-compose.yml Defines the 3 containers
|
||||
.env.example Configurable variables
|
||||
linux-client/ Debian image pre-equipped (SSSD/realmd)
|
||||
scripts/ Prerequisite checks + RDP launchers
|
||||
shared/ Folder shared with Windows VMs via RDP
|
||||
docs/
|
||||
etudiant/ Learning guides (FR + EN)
|
||||
formateur/ Instructor materials and solutions (not distributed)
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
- `docs/etudiant/en/00-prerequisites.md`: Docker install and checks
|
||||
- `docs/etudiant/en/01-lab-startup.md`: first lab startup
|
||||
- `docs/etudiant/en/02-dc-promotion.md`: domain controller promotion (GUI + PowerShell)
|
||||
- `docs/etudiant/en/03-ou-users-groups.md`: OU tree, users, groups, AGDLP
|
||||
- `docs/etudiant/en/04-gpo.md`: GPO creation and linking
|
||||
- `docs/etudiant/en/05-shares-ntfs.md`: SMB shares and NTFS permissions
|
||||
- `docs/etudiant/en/06-join-windows-client.md`: joining PC01 to the domain
|
||||
- `docs/etudiant/en/07-join-linux-client.md`: joining linux01 to the domain
|
||||
- `docs/etudiant/en/troubleshooting.md`: common issues
|
||||
|
||||
Each procedure is documented with a dual approach: **graphical interface** (Server Manager, ADUC, GPMC) and **PowerShell scripting**.
|
||||
|
||||
## Stop the lab
|
||||
|
||||
```bash
|
||||
docker compose stop # stop without losing state
|
||||
docker compose down # stop and remove containers
|
||||
docker compose down -v # remove everything including VM disks
|
||||
```
|
||||
|
||||
Windows disks are stored in `./storage-dc01/` and `./storage-pc01/` at the project root. Removing these directories resets everything to a fresh install.
|
||||
|
||||
## License
|
||||
|
||||
MIT - see [LICENSE](LICENSE).
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome (fixes, translations, new exercises). Open an issue or submit a merge request.
|
||||
|
||||
---
|
||||
|
||||
Made by [AcadéNice](https://acadenice.fr/).
|
||||
83
docker-compose.yml
Normal file
83
docker-compose.yml
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
services:
|
||||
dc01:
|
||||
image: dockurr/windows
|
||||
container_name: lab-dc01
|
||||
hostname: DC01
|
||||
environment:
|
||||
VERSION: "${DC_WINDOWS_VERSION:-2022}"
|
||||
RAM_SIZE: "${DC_RAM:-6G}"
|
||||
CPU_CORES: "${DC_CPU:-2}"
|
||||
DISK_SIZE: "${DC_DISK:-64G}"
|
||||
USERNAME: "Administrator"
|
||||
PASSWORD: "${AD_ADMIN_PASSWORD:-AdminP@ss!2026}"
|
||||
LANGUAGE: "${VM_LANGUAGE:-French}"
|
||||
REGION: "${VM_REGION:-fr-FR}"
|
||||
KEYBOARD: "${VM_KEYBOARD:-fr-FR}"
|
||||
devices:
|
||||
- /dev/kvm
|
||||
- /dev/net/tun
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
ports:
|
||||
- "${DC_WEB_PORT:-8006}:8006"
|
||||
- "127.0.0.1:${DC_RDP_PORT:-3389}:3389/tcp"
|
||||
- "127.0.0.1:${DC_RDP_PORT:-3389}:3389/udp"
|
||||
volumes:
|
||||
- ./storage-dc01:/storage
|
||||
- ./shared:/shared:ro
|
||||
networks:
|
||||
- adlan
|
||||
stop_grace_period: 2m
|
||||
restart: unless-stopped
|
||||
|
||||
pc01:
|
||||
image: dockurr/windows
|
||||
container_name: lab-pc01
|
||||
hostname: PC01
|
||||
environment:
|
||||
VERSION: "${CLIENT_WINDOWS_VERSION:-11}"
|
||||
RAM_SIZE: "${CLIENT_RAM:-4G}"
|
||||
CPU_CORES: "${CLIENT_CPU:-2}"
|
||||
DISK_SIZE: "${CLIENT_DISK:-40G}"
|
||||
USERNAME: "LocalAdmin"
|
||||
PASSWORD: "${AD_ADMIN_PASSWORD:-AdminP@ss!2026}"
|
||||
LANGUAGE: "${VM_LANGUAGE:-French}"
|
||||
REGION: "${VM_REGION:-fr-FR}"
|
||||
KEYBOARD: "${VM_KEYBOARD:-fr-FR}"
|
||||
devices:
|
||||
- /dev/kvm
|
||||
- /dev/net/tun
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
ports:
|
||||
- "${CLIENT_WEB_PORT:-8009}:8006"
|
||||
- "127.0.0.1:${CLIENT_RDP_PORT:-3391}:3389/tcp"
|
||||
- "127.0.0.1:${CLIENT_RDP_PORT:-3391}:3389/udp"
|
||||
volumes:
|
||||
- ./storage-pc01:/storage
|
||||
networks:
|
||||
- adlan
|
||||
stop_grace_period: 2m
|
||||
restart: unless-stopped
|
||||
|
||||
linux01:
|
||||
build: ./linux-client
|
||||
container_name: lab-linux01
|
||||
hostname: linux01
|
||||
environment:
|
||||
AD_DOMAIN: "${AD_DOMAIN:-corp.lab}"
|
||||
AD_DOMAIN_NETBIOS: "${AD_DOMAIN_NETBIOS:-CORP}"
|
||||
AD_ADMIN_USER: "Administrator"
|
||||
AD_ADMIN_PASSWORD: "${AD_ADMIN_PASSWORD:-AdminP@ss!2026}"
|
||||
DC_CONTAINER_IP: "lab-dc01"
|
||||
cap_add:
|
||||
- SYS_ADMIN
|
||||
networks:
|
||||
- adlan
|
||||
depends_on:
|
||||
- dc01
|
||||
restart: unless-stopped
|
||||
|
||||
networks:
|
||||
adlan:
|
||||
driver: bridge
|
||||
72
docs/etudiant/en/00-prerequisites.md
Normal file
72
docs/etudiant/en/00-prerequisites.md
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# Prerequisites
|
||||
|
||||
Before starting the lab, make sure your workstation can run several VMs in
|
||||
parallel. The domain controller and the Windows client are full Windows VMs
|
||||
(Server and Windows 11).
|
||||
|
||||
## Hardware
|
||||
|
||||
| Resource | Recommended | Minimum |
|
||||
|---|---|---|
|
||||
| RAM | 16 GB | 12 GB |
|
||||
| CPU | 4 cores | 2 cores |
|
||||
| Free disk | 150 GB | 80 GB |
|
||||
| CPU virtualization | VT-x or AMD-V enabled in BIOS | required |
|
||||
|
||||
## Software
|
||||
|
||||
- Recent Docker Engine (>= 24) with Compose v2 plugin
|
||||
- An RDP client (optional but strongly recommended)
|
||||
|
||||
Install Docker according to your OS:
|
||||
|
||||
- Linux: `docker` and `docker-compose-plugin` packages
|
||||
- Windows: Docker Desktop with WSL2 backend
|
||||
- macOS Intel: Docker Desktop
|
||||
- macOS Apple Silicon: not supported (see the dedicated section below)
|
||||
|
||||
## macOS Apple Silicon
|
||||
|
||||
M1/M2/M3/M4 chips do not expose an x86 `/dev/kvm`. The `dockurr/windows` image
|
||||
refuses to start without KVM, and full x86 emulation via QEMU TCG is too slow
|
||||
to be usable.
|
||||
|
||||
Workaround: install a Linux VM with Docker inside, then clone and run the lab
|
||||
from there. [UTM](https://mac.getutm.app/) works well. You get a Debian or
|
||||
Ubuntu VM that hosts the whole lab, and you access the lab VMs via RDP from
|
||||
your Mac.
|
||||
|
||||
## Automated check
|
||||
|
||||
A script validates the critical items:
|
||||
|
||||
```
|
||||
./scripts/check-prereqs.sh # Linux, macOS
|
||||
.\scripts\check-prereqs.ps1 # Windows PowerShell
|
||||
```
|
||||
|
||||
It reports `[ OK ]`, `[WARN]`, `[FAIL]` for each check.
|
||||
|
||||
## Windows-specific setup
|
||||
|
||||
Nested virtualization must be enabled in WSL2. Create
|
||||
`%USERPROFILE%\.wslconfig` with:
|
||||
|
||||
```
|
||||
[wsl2]
|
||||
nestedVirtualization=true
|
||||
memory=16GB
|
||||
processors=4
|
||||
```
|
||||
|
||||
Then restart WSL:
|
||||
|
||||
```
|
||||
wsl --shutdown
|
||||
```
|
||||
|
||||
Docker Desktop will restart with nested virt available.
|
||||
|
||||
## Next
|
||||
|
||||
Once prerequisites check out, continue to `01-lab-startup.md`.
|
||||
75
docs/etudiant/en/01-lab-startup.md
Normal file
75
docs/etudiant/en/01-lab-startup.md
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
# Lab startup
|
||||
|
||||
Goal: clone the project, adapt its configuration, then start the domain
|
||||
controller. Clients (PC01 and linux01) will be started later in the journey.
|
||||
|
||||
## Get the project
|
||||
|
||||
```
|
||||
git clone <repo-url> lab_AD_Complet
|
||||
cd lab_AD_Complet
|
||||
```
|
||||
|
||||
## Adapt the configuration
|
||||
|
||||
`.env.example` lists every variable (names, passwords, VM resources). Copy it:
|
||||
|
||||
```
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
At minimum, change:
|
||||
|
||||
- `AD_DOMAIN` and `AD_DOMAIN_NETBIOS` if you want something else than `corp.lab`
|
||||
- `AD_ADMIN_PASSWORD`: must match the default AD policy (10+ chars, uppercase,
|
||||
lowercase, digit, special)
|
||||
|
||||
Other variables (RAM, CPU, ports) can stay as-is.
|
||||
|
||||
## Check prerequisites
|
||||
|
||||
```
|
||||
./scripts/check-prereqs.sh
|
||||
```
|
||||
|
||||
Fix any `[FAIL]` before continuing.
|
||||
|
||||
## Start the domain controller
|
||||
|
||||
`docker-compose.yml` defines three services:
|
||||
|
||||
- `dc01`: Windows Server (domain controller)
|
||||
- `pc01`: Windows 11 (client)
|
||||
- `linux01`: Debian 12 (client)
|
||||
|
||||
For now, only `dc01`:
|
||||
|
||||
```
|
||||
docker compose up -d dc01
|
||||
```
|
||||
|
||||
The `dockurr/windows` image downloads (~1 GB), then fetches the Windows Server
|
||||
ISO and runs an unattended install. Depending on your connection, allow 20 to
|
||||
45 minutes.
|
||||
|
||||
## Track progress
|
||||
|
||||
- Logs: `docker compose logs -f dc01`
|
||||
- Web console: [http://localhost:8006](http://localhost:8006)
|
||||
|
||||
## Accessing DC01
|
||||
|
||||
Once Windows is up:
|
||||
|
||||
- Web: http://localhost:8006 (slow, unreliable clipboard)
|
||||
- RDP: `./scripts/rdp-dc.sh` (recommended)
|
||||
|
||||
Default credentials for first login:
|
||||
|
||||
- User: `Administrator`
|
||||
- Password: value of `AD_ADMIN_PASSWORD` in your `.env`
|
||||
|
||||
## Next
|
||||
|
||||
The server is installed but not yet a DC. Promotion happens in
|
||||
`02-dc-promotion.md`.
|
||||
110
docs/etudiant/en/02-dc-promotion.md
Normal file
110
docs/etudiant/en/02-dc-promotion.md
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
# Promoting the server to a domain controller
|
||||
|
||||
Goal: turn the freshly installed Windows Server into the first DC of a new
|
||||
Active Directory forest. We also install the DNS role, required by AD.
|
||||
|
||||
## What we create
|
||||
|
||||
An Active Directory forest is a logical structure containing one or more
|
||||
domains. Here we create:
|
||||
|
||||
- a new forest with the configured domain at its root (`corp.lab` by default)
|
||||
- a first domain controller (`DC01`) hosting the AD database and DNS
|
||||
|
||||
A DC is critical: it handles authentication, GPOs, internal DNS. Production
|
||||
setups use at least two for redundancy. One is enough for this lab.
|
||||
|
||||
## Preparation
|
||||
|
||||
Rename the machine first. Once promoted, a DC cannot be renamed without being
|
||||
demoted.
|
||||
|
||||
### GUI
|
||||
|
||||
1. `Settings > System > About > Rename this PC` (or `Win + Pause` > "Change settings")
|
||||
2. New name: `DC01`
|
||||
3. Restart
|
||||
|
||||
### PowerShell
|
||||
|
||||
```
|
||||
Rename-Computer -NewName "DC01" -Restart
|
||||
```
|
||||
|
||||
If `Rename-Computer` refuses authentication on a fresh install, use the GUI
|
||||
or the registry approach (see `troubleshooting.md`).
|
||||
|
||||
## Install the roles
|
||||
|
||||
After the reboot, open a session as Administrator.
|
||||
|
||||
### GUI
|
||||
|
||||
1. Open `Server Manager`
|
||||
2. `Manage > Add Roles and Features`
|
||||
3. Select:
|
||||
- `AD DS`
|
||||
- `DNS Server`
|
||||
4. Leave defaults, install
|
||||
5. When done, click the warning flag > `Promote this server to a domain controller`
|
||||
|
||||
### PowerShell
|
||||
|
||||
```
|
||||
Install-WindowsFeature -Name AD-Domain-Services, DNS -IncludeManagementTools
|
||||
```
|
||||
|
||||
## Promote to domain controller
|
||||
|
||||
### GUI
|
||||
|
||||
1. In the AD DS configuration wizard:
|
||||
2. `Add a new forest` > Root name: `corp.lab`
|
||||
3. Functional levels: keep the suggested value
|
||||
4. Check `DNS Server` and `Global Catalog`
|
||||
5. Set a DSRM password (Directory Services Restore Mode)
|
||||
6. Ignore DNS warnings (normal on a brand new DC)
|
||||
7. Validate, let the machine reboot
|
||||
|
||||
### PowerShell
|
||||
|
||||
```
|
||||
$dsrmPwd = Read-Host -AsSecureString "DSRM password"
|
||||
Install-ADDSForest `
|
||||
-DomainName "corp.lab" `
|
||||
-DomainNetbiosName "CORP" `
|
||||
-InstallDns `
|
||||
-SafeModeAdministratorPassword $dsrmPwd `
|
||||
-Force
|
||||
```
|
||||
|
||||
Key cmdlets:
|
||||
|
||||
- `Install-ADDSForest` creates a new forest
|
||||
- `Install-ADDSDomainController` adds a DC to an existing forest
|
||||
|
||||
## Validation
|
||||
|
||||
After reboot, log back in (account is now `CORP\Administrator`):
|
||||
|
||||
```
|
||||
Get-ADDomain
|
||||
Get-ADForest
|
||||
dcdiag
|
||||
```
|
||||
|
||||
The first two return domain/forest info. `dcdiag` runs integrity tests.
|
||||
Minor DNS warnings are normal on a standalone DC.
|
||||
|
||||
## Notes
|
||||
|
||||
- The DSRM password is independent of Administrator's. It is used in AD
|
||||
recovery mode. Keep it in your password manager.
|
||||
- Once promoted, a DC cannot be renamed without demotion first
|
||||
(`Uninstall-ADDSDomainController`).
|
||||
- Fresh dockur installs come with an auto-generated hostname (`WIN-xxxx`).
|
||||
Renaming **before** promotion is crucial.
|
||||
|
||||
## Next
|
||||
|
||||
AD is live but empty. Create OUs, users and groups in `03-ou-users-groups.md`.
|
||||
146
docs/etudiant/en/03-ou-users-groups.md
Normal file
146
docs/etudiant/en/03-ou-users-groups.md
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
# Organizational Units, users, groups
|
||||
|
||||
Goal: build the AD tree (OUs), populate it with users and groups, apply the
|
||||
AGDLP nesting recommended by Microsoft.
|
||||
|
||||
## What is an OU
|
||||
|
||||
An Organizational Unit is a logical container for AD objects (users,
|
||||
computers, groups). OUs are used to apply policies, delegate admin, or just
|
||||
structure the directory.
|
||||
|
||||
An OU grants no permission by itself. It is purely a structuring tool.
|
||||
|
||||
## Proposed tree
|
||||
|
||||
```
|
||||
corp.lab
|
||||
└── CORP
|
||||
├── Users
|
||||
│ ├── Direction
|
||||
│ ├── Teaching
|
||||
│ ├── IT
|
||||
│ ├── Admin
|
||||
│ └── Students
|
||||
├── Computers
|
||||
│ └── (same sub-OUs)
|
||||
├── Groups
|
||||
└── Services
|
||||
```
|
||||
|
||||
Mirror or adapt to your context.
|
||||
|
||||
## Creating OUs
|
||||
|
||||
### GUI
|
||||
|
||||
1. Open `Active Directory Users and Computers` (`dsa.msc`)
|
||||
2. Right-click domain > `New > Organizational Unit`
|
||||
3. Name it `CORP`
|
||||
4. Inside, create `Users`, `Computers`, `Groups`, `Services`
|
||||
5. Create department sub-OUs under `Users` and `Computers`
|
||||
|
||||
### PowerShell
|
||||
|
||||
Key cmdlet: `New-ADOrganizationalUnit`.
|
||||
|
||||
```
|
||||
New-ADOrganizationalUnit -Name "CORP" -Path "DC=corp,DC=lab"
|
||||
New-ADOrganizationalUnit -Name "Users" -Path "OU=CORP,DC=corp,DC=lab"
|
||||
```
|
||||
|
||||
Loop for departments:
|
||||
|
||||
```
|
||||
$deps = @("Direction","Teaching","IT","Admin","Students")
|
||||
foreach ($d in $deps) {
|
||||
New-ADOrganizationalUnit -Name $d -Path "OU=Users,OU=CORP,DC=corp,DC=lab"
|
||||
}
|
||||
```
|
||||
|
||||
## Creating users
|
||||
|
||||
### GUI
|
||||
|
||||
1. Right-click a department OU > `New > User`
|
||||
2. Fill in the fields (First, Last, SamAccountName, UPN)
|
||||
3. Initial password, tick `User must change password at next logon`
|
||||
|
||||
### PowerShell
|
||||
|
||||
Key cmdlet: `New-ADUser`.
|
||||
|
||||
```
|
||||
New-ADUser `
|
||||
-Name "Paul Martin" `
|
||||
-GivenName "Paul" `
|
||||
-Surname "Martin" `
|
||||
-SamAccountName "pmartin" `
|
||||
-UserPrincipalName "pmartin@corp.lab" `
|
||||
-Path "OU=Teaching,OU=Users,OU=CORP,DC=corp,DC=lab" `
|
||||
-AccountPassword (ConvertTo-SecureString "UserP@ss!2026" -AsPlainText -Force) `
|
||||
-Enabled $true `
|
||||
-ChangePasswordAtLogon $true
|
||||
```
|
||||
|
||||
## Creating groups
|
||||
|
||||
Two group types:
|
||||
|
||||
- **Global groups (GG)**: group users by department/role. `GG_Teaching`, `GG_Students`.
|
||||
- **Domain local groups (DL)**: hold permissions on resources.
|
||||
`DL_Share_Common_R`, `DL_Share_Teaching_RW`.
|
||||
|
||||
### GUI
|
||||
|
||||
1. Right-click `OU=Groups` > `New > Group`
|
||||
2. Scope: `Global` or `Domain local` as needed
|
||||
3. Type: `Security`
|
||||
|
||||
### PowerShell
|
||||
|
||||
Key cmdlet: `New-ADGroup`.
|
||||
|
||||
```
|
||||
New-ADGroup -Name "GG_Teaching" -GroupScope Global -GroupCategory Security `
|
||||
-Path "OU=Groups,OU=CORP,DC=corp,DC=lab"
|
||||
|
||||
New-ADGroup -Name "DL_Share_Common_R" -GroupScope DomainLocal -GroupCategory Security `
|
||||
-Path "OU=Groups,OU=CORP,DC=corp,DC=lab"
|
||||
```
|
||||
|
||||
## Apply AGDLP nesting
|
||||
|
||||
AGDLP is a Microsoft convention:
|
||||
|
||||
- **A**ccount in
|
||||
- **G**lobal group (department) member of
|
||||
- **D**omain **L**ocal group (resource) holding the
|
||||
- **P**ermission
|
||||
|
||||
Concretely:
|
||||
|
||||
1. Add users to matching global groups
|
||||
2. Add global groups to matching domain local groups
|
||||
3. Put NTFS/share permissions on domain local groups
|
||||
|
||||
Key cmdlet: `Add-ADGroupMember`.
|
||||
|
||||
```
|
||||
Add-ADGroupMember -Identity "GG_Teaching" -Members "pmartin"
|
||||
Add-ADGroupMember -Identity "DL_Share_Common_R" -Members "GG_Teaching","GG_Students"
|
||||
```
|
||||
|
||||
## Validation
|
||||
|
||||
```
|
||||
Get-ADUser -Filter * -SearchBase "OU=CORP,DC=corp,DC=lab" | Select Name, SamAccountName
|
||||
Get-ADGroup -Filter * -SearchBase "OU=Groups,OU=CORP,DC=corp,DC=lab" | Select Name, GroupScope
|
||||
Get-ADGroupMember -Identity "GG_Teaching"
|
||||
```
|
||||
|
||||
`dsa.msc` should show your hierarchy, users in their OUs, groups with members.
|
||||
|
||||
## Next
|
||||
|
||||
`04-gpo.md` for Group Policy.
|
||||
121
docs/etudiant/en/04-gpo.md
Normal file
121
docs/etudiant/en/04-gpo.md
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
# Group Policy Objects (GPO)
|
||||
|
||||
Goal: create and link a few representative GPOs.
|
||||
|
||||
## What is a GPO
|
||||
|
||||
A Group Policy Object is a set of settings applied to users or computers. It
|
||||
is stored in `SYSVOL` (on DCs) and replicated to all domain-joined machines.
|
||||
|
||||
Two main scopes:
|
||||
|
||||
- `Computer configuration`: applied at boot
|
||||
- `User configuration`: applied at logon
|
||||
|
||||
A GPO is **linked** to a container (site, domain, OU). Objects in that
|
||||
container and its descendants inherit the GPO. You thus use OUs as scoping
|
||||
targets: link a GPO to `Students` OU and it will only apply to those users.
|
||||
|
||||
## Lab scenarios
|
||||
|
||||
Three GPOs:
|
||||
|
||||
1. Strengthen the domain password policy
|
||||
2. Force a wallpaper on students
|
||||
3. Restrict Control Panel access for students
|
||||
|
||||
## Password policy
|
||||
|
||||
Lives in the `Default Domain Policy`, applied domain-wide.
|
||||
|
||||
### GUI
|
||||
|
||||
1. Open `Group Policy Management` (`gpmc.msc`)
|
||||
2. Domain > `Default Domain Policy` > right-click > `Edit`
|
||||
3. `Computer Configuration > Policies > Windows Settings > Security Settings > Account Policies > Password Policy`
|
||||
4. Tune minimum length, complexity, history, age
|
||||
|
||||
### PowerShell
|
||||
|
||||
Key cmdlet: `Set-ADDefaultDomainPasswordPolicy`.
|
||||
|
||||
```
|
||||
Set-ADDefaultDomainPasswordPolicy -Identity corp.lab `
|
||||
-MinPasswordLength 10 `
|
||||
-ComplexityEnabled $true `
|
||||
-PasswordHistoryCount 5 `
|
||||
-MaxPasswordAge (New-TimeSpan -Days 90) `
|
||||
-LockoutThreshold 5 `
|
||||
-LockoutDuration (New-TimeSpan -Minutes 15)
|
||||
```
|
||||
|
||||
## Wallpaper GPO
|
||||
|
||||
### GUI
|
||||
|
||||
1. `gpmc.msc` > Domain > right-click `OU=Students,OU=Users,OU=CORP` > `Create a GPO in this domain, and link it here`
|
||||
2. Name it (e.g. `GPO_Students_Wallpaper`)
|
||||
3. Right-click GPO > `Edit`
|
||||
4. `User Configuration > Policies > Administrative Templates > Desktop > Desktop`
|
||||
5. Setting `Desktop Wallpaper` > `Enabled`, set the image path and style
|
||||
|
||||
### PowerShell
|
||||
|
||||
Key cmdlets: `New-GPO`, `New-GPLink`, `Set-GPRegistryValue`.
|
||||
|
||||
```
|
||||
New-GPO -Name "GPO_Students_Wallpaper"
|
||||
|
||||
Set-GPRegistryValue -Name "GPO_Students_Wallpaper" `
|
||||
-Key "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System" `
|
||||
-ValueName "Wallpaper" -Type String -Value "C:\Windows\Web\Wallpaper\Windows\img0.jpg"
|
||||
|
||||
New-GPLink -Name "GPO_Students_Wallpaper" `
|
||||
-Target "OU=Students,OU=Users,OU=CORP,DC=corp,DC=lab"
|
||||
```
|
||||
|
||||
## Control Panel restriction GPO
|
||||
|
||||
Same steps via GUI, setting:
|
||||
|
||||
`User Configuration > Policies > Administrative Templates > Control Panel > Prohibit access to Control Panel and PC settings > Enabled`
|
||||
|
||||
PowerShell:
|
||||
|
||||
```
|
||||
New-GPO -Name "GPO_Students_NoCP"
|
||||
|
||||
Set-GPRegistryValue -Name "GPO_Students_NoCP" `
|
||||
-Key "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" `
|
||||
-ValueName "NoControlPanel" -Type DWord -Value 1
|
||||
|
||||
New-GPLink -Name "GPO_Students_NoCP" `
|
||||
-Target "OU=Students,OU=Users,OU=CORP,DC=corp,DC=lab"
|
||||
```
|
||||
|
||||
## Test
|
||||
|
||||
On a client machine with a student logged in:
|
||||
|
||||
```
|
||||
gpupdate /force
|
||||
gpresult /r
|
||||
```
|
||||
|
||||
`gpresult` lists effective GPOs. If yours is missing, check:
|
||||
|
||||
- the user is in the right OU
|
||||
- the GPO is linked to the right OU
|
||||
- the user has `Apply Group Policy` permission (security filtering)
|
||||
- no WMI filter blocks it
|
||||
|
||||
## Notes
|
||||
|
||||
- Don't stuff the `Default Domain Policy`. Always create dedicated GPOs for
|
||||
anything beyond the password policy.
|
||||
- GPO precedence: Local > Site > Domain > OU (closer wins on conflicts).
|
||||
- `Block Inheritance` breaks the chain for a child OU. Use sparingly.
|
||||
|
||||
## Next
|
||||
|
||||
`05-shares-ntfs.md` for SMB shares and NTFS permissions.
|
||||
113
docs/etudiant/en/05-shares-ntfs.md
Normal file
113
docs/etudiant/en/05-shares-ntfs.md
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
# SMB shares and NTFS permissions
|
||||
|
||||
Goal: expose three shares on `DC01`, secure them with the AD groups created
|
||||
earlier, and verify permissions behave as expected.
|
||||
|
||||
Note: in production, shares live on a dedicated file server, not on a DC. We
|
||||
simplify here.
|
||||
|
||||
## Shares to create
|
||||
|
||||
| Share | Path | Access |
|
||||
|---|---|---|
|
||||
| `Common` | `C:\Shares\Common` | read for everyone, write for Direction/Teaching/Admin |
|
||||
| `Teaching` | `C:\Shares\Teaching` | restricted to GG_Teaching |
|
||||
| `Direction` | `C:\Shares\Direction` | restricted to GG_Direction |
|
||||
|
||||
## AGDLP reminder
|
||||
|
||||
Permissions are **never** placed directly on global groups or users. They go
|
||||
on a **domain local group**, which contains the matching global groups.
|
||||
|
||||
Example for `Common`:
|
||||
|
||||
- Global groups: `GG_Teaching`, `GG_Students`, ...
|
||||
- DL groups: `DL_Share_Common_R` (read), `DL_Share_Common_RW` (write)
|
||||
- NTFS ACLs: set on `DL_Share_Common_R` and `DL_Share_Common_RW`
|
||||
- Nesting:
|
||||
- `GG_Students` member of `DL_Share_Common_R`
|
||||
- `GG_Teaching` member of `DL_Share_Common_RW`
|
||||
|
||||
## Create folders and shares
|
||||
|
||||
### GUI
|
||||
|
||||
1. Create `C:\Shares\Common` in Explorer
|
||||
2. Right-click > `Properties > Sharing > Advanced Sharing`
|
||||
3. Tick `Share this folder`, name the share, click `Permissions`
|
||||
4. Remove `Everyone`, add the relevant AD groups with appropriate rights
|
||||
5. `Security` tab > `Edit`: define NTFS ACLs
|
||||
6. Disable inheritance if you want an explicit ACL
|
||||
|
||||
### PowerShell
|
||||
|
||||
Key cmdlets: `New-SmbShare`, `Get-Acl`, `Set-Acl`, `FileSystemAccessRule`.
|
||||
|
||||
```
|
||||
New-Item -Path C:\Shares\Common -ItemType Directory -Force
|
||||
|
||||
New-SmbShare -Name "Common" -Path "C:\Shares\Common" `
|
||||
-FullAccess "CORP\Domain Admins" `
|
||||
-ReadAccess "CORP\DL_Share_Common_R" `
|
||||
-ChangeAccess "CORP\DL_Share_Common_RW"
|
||||
```
|
||||
|
||||
NTFS permissions:
|
||||
|
||||
```
|
||||
$acl = Get-Acl "C:\Shares\Common"
|
||||
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
|
||||
"CORP\DL_Share_Common_R", "ReadAndExecute", "ContainerInherit,ObjectInherit", "None", "Allow")
|
||||
$acl.AddAccessRule($rule)
|
||||
Set-Acl "C:\Shares\Common" $acl
|
||||
```
|
||||
|
||||
Repeat per (DL, rights) pair.
|
||||
|
||||
## Test from a Windows client
|
||||
|
||||
On `PC01`, logged in as an AD user:
|
||||
|
||||
```
|
||||
\\DC01\Common
|
||||
```
|
||||
|
||||
via `Run` (`Win + R`) or the Explorer address bar.
|
||||
|
||||
Tests:
|
||||
|
||||
- as a `GG_Students` member: read OK, write denied
|
||||
- as a `GG_Teaching` member: read and write OK
|
||||
- attempt to access `\\DC01\Teaching` as a student: denied
|
||||
|
||||
## Test from Linux
|
||||
|
||||
If `linux01` is domain-joined (see `07-join-linux-client.md`):
|
||||
|
||||
```
|
||||
smbclient //DC01/Common -U pmartin%<password>
|
||||
# then:
|
||||
ls
|
||||
put /etc/hostname
|
||||
```
|
||||
|
||||
or mount via `cifs-utils`:
|
||||
|
||||
```
|
||||
mkdir /mnt/common
|
||||
mount -t cifs //DC01/Common /mnt/common -o username=pmartin,domain=CORP
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- **Both** layers (Share and NTFS) apply. The effective access is the
|
||||
intersection. Common practice: `Full Control` at share level, then refine
|
||||
via NTFS.
|
||||
- An already-connected user does not see group membership changes until
|
||||
relogon (or `klist purge`).
|
||||
- Never ACL a user directly. They leave, you are left with cleanup.
|
||||
|
||||
## Next
|
||||
|
||||
`06-join-windows-client.md` to join `PC01` and test these shares from a
|
||||
client.
|
||||
155
docs/etudiant/en/06-join-windows-client.md
Normal file
155
docs/etudiant/en/06-join-windows-client.md
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
# Join the Windows client to the domain
|
||||
|
||||
Goal: start the `pc01` container, install Windows 11, then join the machine
|
||||
to `corp.lab`.
|
||||
|
||||
## Start the container
|
||||
|
||||
```
|
||||
docker compose up -d pc01
|
||||
```
|
||||
|
||||
Windows 11 installs unattended, same as `DC01`. Allow 20 to 40 minutes. Track
|
||||
via:
|
||||
|
||||
- [http://localhost:8009](http://localhost:8009)
|
||||
- `docker compose logs -f pc01`
|
||||
|
||||
Once the desktop is available:
|
||||
|
||||
```
|
||||
./scripts/rdp-client.sh
|
||||
```
|
||||
|
||||
Local credentials: `LocalAdmin` / `AD_ADMIN_PASSWORD` (same value as DC01 in
|
||||
this lab).
|
||||
|
||||
## Step 1: prepare the client
|
||||
|
||||
### Rename
|
||||
|
||||
Fresh dockurr installs ship with an auto-generated hostname (`WIN-xxxxxxx`).
|
||||
Rename before joining. GUI: `Settings > System > About > Rename this PC`. Or
|
||||
PowerShell:
|
||||
|
||||
```
|
||||
Rename-Computer -NewName "PC01" -Restart
|
||||
```
|
||||
|
||||
### Point DNS to the DC
|
||||
|
||||
Without correct DNS, the join fails. PC01 must query DC01 to resolve
|
||||
`corp.lab` and AD SRV records.
|
||||
|
||||
GUI: `Settings > Network > Network adapter properties > Edit DNS settings`.
|
||||
|
||||
PowerShell:
|
||||
|
||||
```
|
||||
Get-NetAdapter | Format-Table Name, Status
|
||||
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses <DC_IP>
|
||||
```
|
||||
|
||||
See the docker specifics block below to pick the IP.
|
||||
|
||||
### Docker lab specifics
|
||||
|
||||
`dockurr/windows` runs Windows inside a VM with internal NAT. The DC
|
||||
advertises its internal VM IP in DNS, which is not routable from `PC01`. But
|
||||
the DC container has a DNAT rule forwarding all ports to its VM.
|
||||
|
||||
Solution: use the DC **container** IP (visible via `docker inspect lab-dc01`)
|
||||
and add a `hosts` entry so name resolution lands on it.
|
||||
|
||||
In PowerShell on PC01:
|
||||
|
||||
```
|
||||
# Replace <DC_CONTAINER_IP> with the value from:
|
||||
# docker inspect lab-dc01 --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
|
||||
Add-Content C:\Windows\System32\drivers\etc\hosts "`n<DC_CONTAINER_IP> corp.lab dc01.corp.lab dc01"
|
||||
ipconfig /flushdns
|
||||
```
|
||||
|
||||
Test:
|
||||
|
||||
```
|
||||
Test-NetConnection -ComputerName corp.lab -Port 389
|
||||
nslookup corp.lab
|
||||
```
|
||||
|
||||
## Step 2: join the domain
|
||||
|
||||
### GUI
|
||||
|
||||
1. `Settings > System > About > Join a domain`
|
||||
2. Or `sysdm.cpl > Change`
|
||||
3. Enter `corp.lab`, confirm
|
||||
4. Enter `CORP\Administrator` credentials
|
||||
5. Restart when prompted
|
||||
|
||||
### PowerShell
|
||||
|
||||
Key cmdlet: `Add-Computer`.
|
||||
|
||||
```
|
||||
$pass = ConvertTo-SecureString "AdminP@ss!2026" -AsPlainText -Force
|
||||
$cred = New-Object System.Management.Automation.PSCredential("CORP\Administrator", $pass)
|
||||
|
||||
Add-Computer -DomainName corp.lab -Credential $cred -Restart
|
||||
```
|
||||
|
||||
## Step 3: allow an AD user to RDP
|
||||
|
||||
By default, only local `Administrators` can RDP. After joining, the local
|
||||
`Administrators` contains `CORP\Domain Admins`, so a domain admin can RDP.
|
||||
Standard users must be explicitly added.
|
||||
|
||||
### GUI
|
||||
|
||||
1. Right-click `This PC > Properties > Remote Desktop settings`
|
||||
2. `Select users` > add `CORP\pmartin` (or an AD group)
|
||||
|
||||
### PowerShell
|
||||
|
||||
```
|
||||
Add-LocalGroupMember -Group "Remote Desktop Users" -Member "CORP\pmartin"
|
||||
```
|
||||
|
||||
In practice, create a dedicated AD group (e.g. `GG_RDPUsers`) and push it via
|
||||
GPO to the local group on every machine.
|
||||
|
||||
## Step 4: test with an AD user
|
||||
|
||||
From Linux/macOS host:
|
||||
|
||||
```
|
||||
xfreerdp3 /v:127.0.0.1:3391 /u:pmartin /d:CORP /p:'<pwd>' /cert:ignore +clipboard /size:1600x900 /dynamic-resolution
|
||||
```
|
||||
|
||||
On Windows, use `mstsc` with `CORP\pmartin`.
|
||||
|
||||
Once logged in, validate:
|
||||
|
||||
```
|
||||
whoami
|
||||
whoami /groups
|
||||
Get-ComputerInfo | Select CsDomain, CsDomainRole
|
||||
```
|
||||
|
||||
You should see `CORP\pmartin`, AD groups, and `CsDomainRole : MemberWorkstation`.
|
||||
|
||||
## Notes
|
||||
|
||||
- An account with "must change password at next logon" cannot RDP via NLA.
|
||||
Either unset the flag on the DC
|
||||
(`Set-ADUser -ChangePasswordAtLogon $false`) or force `/sec:rdp` to get the
|
||||
change-password screen.
|
||||
- If `Add-Computer` hits `The mapping between account names and SIDs was not
|
||||
done`, the PC is in a broken domain state. Switch to workgroup
|
||||
(`Add-Computer -WorkgroupName "WORKGROUP" -Force`) then retry.
|
||||
- Clean up stale computer accounts in `CN=Computers` when you recreate a
|
||||
client.
|
||||
|
||||
## Next
|
||||
|
||||
`07-join-linux-client.md` for the Linux side.
|
||||
136
docs/etudiant/en/07-join-linux-client.md
Normal file
136
docs/etudiant/en/07-join-linux-client.md
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
# Join the Linux client to the domain
|
||||
|
||||
Goal: configure the Debian client `linux01` to authenticate against AD, and
|
||||
validate resolution of AD users and groups.
|
||||
|
||||
Standard stack on Debian/Ubuntu/RHEL:
|
||||
|
||||
- `realmd`: domain discovery and join
|
||||
- `sssd`: daemon handling the integration (cache, Kerberos, NSS, PAM)
|
||||
- `adcli`: low-level AD client
|
||||
- `krb5`: Kerberos layer
|
||||
|
||||
All these packages are baked into the image (see `linux-client/Dockerfile`).
|
||||
|
||||
## Start the container
|
||||
|
||||
```
|
||||
docker compose up -d linux01
|
||||
docker exec -it lab-linux01 bash
|
||||
```
|
||||
|
||||
The entrypoint auto-configures `/etc/resolv.conf` to point at the DC container
|
||||
IP and adds `hosts` overrides for AD names.
|
||||
|
||||
Check:
|
||||
|
||||
```
|
||||
cat /etc/resolv.conf
|
||||
cat /etc/hosts | tail
|
||||
ping -c 2 corp.lab
|
||||
```
|
||||
|
||||
## Domain discovery
|
||||
|
||||
Key tool: `realm discover`.
|
||||
|
||||
```
|
||||
realm discover corp.lab
|
||||
```
|
||||
|
||||
You should see structured output with `type: kerberos` and
|
||||
`server-software: active-directory`.
|
||||
|
||||
If empty, check DNS: the DC must answer on port 53 at the used IP.
|
||||
|
||||
## Join
|
||||
|
||||
Key tool: `realm join`.
|
||||
|
||||
```
|
||||
realm join -U Administrator corp.lab
|
||||
# Enter CORP\Administrator password when asked
|
||||
```
|
||||
|
||||
Under the hood, `realmd`:
|
||||
|
||||
1. Creates a `LINUX01` computer account in `CN=Computers`
|
||||
2. Generates a Kerberos keytab at `/etc/krb5.keytab`
|
||||
3. Configures `/etc/sssd/sssd.conf`
|
||||
4. Enables `sssd` as NSS backend and PAM module
|
||||
|
||||
## Start sssd
|
||||
|
||||
In a container, systemd may be absent. Start sssd directly:
|
||||
|
||||
```
|
||||
sssd --daemon
|
||||
```
|
||||
|
||||
## Validation
|
||||
|
||||
NSS resolution:
|
||||
|
||||
```
|
||||
id pmartin@corp.lab
|
||||
getent passwd pmartin@corp.lab
|
||||
getent group 'GG_Teaching@corp.lab'
|
||||
```
|
||||
|
||||
You should see:
|
||||
|
||||
- a UID assigned by sssd (large number derived from the SID)
|
||||
- the AD groups of the user, including AGDLP-nested ones
|
||||
|
||||
Kerberos auth:
|
||||
|
||||
```
|
||||
kinit pmartin@CORP.LAB
|
||||
klist
|
||||
```
|
||||
|
||||
`klist` must show a valid TGT.
|
||||
|
||||
## SSH with an AD account
|
||||
|
||||
If you enabled SSH in the container (default with the provided Dockerfile):
|
||||
|
||||
```
|
||||
ssh pmartin@lab-linux01
|
||||
# or the container IP
|
||||
```
|
||||
|
||||
The home directory is auto-created on first login via `pam_mkhomedir`
|
||||
configured by the entrypoint.
|
||||
|
||||
## Restrict access to specific AD groups
|
||||
|
||||
By default, any AD user can log in. To restrict:
|
||||
|
||||
```
|
||||
realm permit -g "GG_Teaching@corp.lab"
|
||||
```
|
||||
|
||||
Or the opposite (deny-all with exceptions) via `/etc/sssd/sssd.conf`.
|
||||
|
||||
## Notes
|
||||
|
||||
- `realm join` fails with bad DNS, or if clock drift > 5 minutes vs the DC.
|
||||
Fresh containers inherit the host clock, that's fine.
|
||||
- In this lab, DNS resolution is tricky: the DC advertises a non-routable
|
||||
internal IP. We work around via `/etc/hosts`. In production, the DC is
|
||||
directly reachable on the network.
|
||||
- `sssd` caches users for 6h by default. To flush: `sss_cache -E` or restart
|
||||
`sssd`.
|
||||
|
||||
## Leave the domain
|
||||
|
||||
```
|
||||
realm leave corp.lab
|
||||
```
|
||||
|
||||
Removes the computer account on the DC, the keytab, disables sssd.
|
||||
|
||||
## Next
|
||||
|
||||
The lab is fully operational. See `troubleshooting.md` for issues.
|
||||
153
docs/etudiant/en/troubleshooting.md
Normal file
153
docs/etudiant/en/troubleshooting.md
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
# Troubleshooting
|
||||
|
||||
Common issues encountered while setting up the lab.
|
||||
|
||||
## Windows installation stuck
|
||||
|
||||
Symptom: http://localhost:8006 stays on the ISO download screen.
|
||||
|
||||
Causes:
|
||||
|
||||
- Slow/interrupted internet (ISO is several GB)
|
||||
- Not enough host disk space
|
||||
- `btrfs` filesystem on `/storage` (dockurr warns, rarely blocking)
|
||||
|
||||
Check `docker compose logs -f dc01`, restart if needed.
|
||||
|
||||
## /dev/kvm not accessible
|
||||
|
||||
Symptom: `KVM acceleration not available` in dockurr logs.
|
||||
|
||||
Causes:
|
||||
|
||||
- Virtualization disabled in BIOS
|
||||
- Your user not in the `kvm` group
|
||||
- WSL2 without nested virt (Windows)
|
||||
|
||||
Fixes:
|
||||
|
||||
- Linux: `sudo usermod -aG kvm $USER`, reconnect
|
||||
- Windows: edit `%USERPROFILE%\.wslconfig` with `nestedVirtualization=true`
|
||||
- macOS Apple Silicon: unsupported, use UTM
|
||||
|
||||
## Rename-Computer rejects authentication
|
||||
|
||||
Symptom: `Rename-Computer : ... The user name or password is incorrect.`
|
||||
|
||||
Happens on a fresh install before any domain membership. The cmdlet attempts
|
||||
a local authentication that fails for obscure reasons.
|
||||
|
||||
Fixes:
|
||||
|
||||
- Use the GUI: `sysdm.cpl > Change`
|
||||
- Or the registry:
|
||||
```
|
||||
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "Hostname" -Value "NEW"
|
||||
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "NV Hostname" -Value "NEW"
|
||||
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName" -Name "ComputerName" -Value "NEW"
|
||||
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName" -Name "ComputerName" -Value "NEW"
|
||||
Restart-Computer -Force
|
||||
```
|
||||
|
||||
## Add-Computer: "the computer is already in this domain"
|
||||
|
||||
The PC has a partial domain state (DNS suffix, workgroup with the same name
|
||||
as the domain NetBIOS, prior join). Clean first:
|
||||
|
||||
```
|
||||
Add-Computer -WorkgroupName "WORKGROUP" -Force
|
||||
Restart-Computer -Force
|
||||
```
|
||||
|
||||
If `Remove-Computer` fails with `The mapping between account names and SIDs
|
||||
was not done`, force via WMI:
|
||||
|
||||
```
|
||||
$cs = Get-WmiObject Win32_ComputerSystem
|
||||
$cs.UnjoinDomainOrWorkgroup($null, $null, 0)
|
||||
Restart-Computer -Force
|
||||
```
|
||||
|
||||
## RDP denies the AD user
|
||||
|
||||
Symptom: `ERRCONNECT_CONNECT_TRANSPORT_FAILED` after NLA with freerdp, or
|
||||
"access denied" with mstsc.
|
||||
|
||||
Cause: by default only local `Administrators` can RDP. Domain users aren't
|
||||
granted.
|
||||
|
||||
Fix on the client:
|
||||
|
||||
```
|
||||
Add-LocalGroupMember -Group "Remote Desktop Users" -Member "CORP\pmartin"
|
||||
```
|
||||
|
||||
Push via GPO in production.
|
||||
|
||||
## "Password must change" over freerdp
|
||||
|
||||
Symptom: `ERRCONNECT_PASSWORD_MUST_CHANGE`.
|
||||
|
||||
freerdp with NLA cannot display the change-password screen. Two options:
|
||||
|
||||
- Clear the flag on the DC:
|
||||
```
|
||||
Set-ADAccountPassword -Identity pmartin -Reset -NewPassword (ConvertTo-SecureString "NewP@ss!2026" -AsPlainText -Force)
|
||||
Set-ADUser -Identity pmartin -ChangePasswordAtLogon $false
|
||||
```
|
||||
- Or bypass NLA:
|
||||
```
|
||||
xfreerdp3 /sec:rdp ...
|
||||
```
|
||||
|
||||
## realm discover returns nothing
|
||||
|
||||
Causes:
|
||||
|
||||
- Wrong DNS on `linux01` (check `/etc/resolv.conf`)
|
||||
- DC not answering on port 53
|
||||
- `dbus` not running in the container:
|
||||
```
|
||||
dbus-daemon --system --fork
|
||||
```
|
||||
|
||||
## sssd fails to start
|
||||
|
||||
Symptom: `Invalid option -f: unknown option` when `realm join` runs
|
||||
`service sssd restart`.
|
||||
|
||||
Context: docker images without full init (no systemd). Start manually:
|
||||
|
||||
```
|
||||
/usr/sbin/sssd --daemon
|
||||
```
|
||||
|
||||
## AD user not resolved on Linux
|
||||
|
||||
```
|
||||
id pmartin@corp.lab
|
||||
# "no such user"
|
||||
```
|
||||
|
||||
Common causes:
|
||||
|
||||
- sssd not running (see above)
|
||||
- sssd cache out of sync: `sss_cache -E`
|
||||
- Domain missing from `realm list`: the join silently failed, retry with
|
||||
`realm join -v`
|
||||
|
||||
## Share inaccessible from a client
|
||||
|
||||
- User not in the DL group: `Get-ADGroupMember DL_Share_Common_R`
|
||||
- Kerberos token not refreshed: relogon
|
||||
- Restrictive NTFS ACL: check via `Get-Acl` or Security tab
|
||||
|
||||
## Full lab reset
|
||||
|
||||
To start fresh without touching the rest of your system:
|
||||
|
||||
```
|
||||
docker compose down -v
|
||||
rm -rf ./storage-dc01 ./storage-pc01
|
||||
docker compose up -d dc01
|
||||
```
|
||||
76
docs/etudiant/fr/00-prerequis.md
Normal file
76
docs/etudiant/fr/00-prerequis.md
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
# Prérequis
|
||||
|
||||
Avant de lancer le lab, vérifie que ton poste est équipé pour faire tourner
|
||||
plusieurs machines virtuelles en parallèle. Le contrôleur de domaine et le
|
||||
client Windows sont deux VMs complètes (Windows Server et Windows 11).
|
||||
|
||||
## Ressources matérielles
|
||||
|
||||
| Ressource | Recommandé | Minimum |
|
||||
|---|---|---|
|
||||
| RAM | 16 Go | 12 Go |
|
||||
| CPU | 4 cœurs | 2 cœurs |
|
||||
| Disque libre | 150 Go | 80 Go |
|
||||
| Virtualisation CPU | VT-x ou AMD-V activés dans le BIOS | obligatoire |
|
||||
|
||||
## Logiciels requis
|
||||
|
||||
- Docker Engine récent (>= 24) avec le plugin Compose v2
|
||||
- Un client RDP (facultatif mais fortement recommandé)
|
||||
|
||||
Installation de Docker selon ton système :
|
||||
|
||||
- Linux : paquets `docker` et `docker-compose-plugin` de ta distribution
|
||||
- Windows : Docker Desktop avec backend WSL2
|
||||
- macOS Intel : Docker Desktop
|
||||
- macOS Apple Silicon : non supporté (voir la section dédiée plus bas)
|
||||
|
||||
## Cas spécifique macOS Apple Silicon
|
||||
|
||||
Les processeurs M1/M2/M3/M4 n'exposent pas de `/dev/kvm` x86. L'image
|
||||
`dockurr/windows` refuse de démarrer sans KVM, et l'émulation x86 complète
|
||||
via QEMU TCG est trop lente pour être exploitable.
|
||||
|
||||
Solution proposée : installer une VM Linux avec Docker, puis cloner et lancer
|
||||
le lab dans cette VM. L'outil [UTM](https://mac.getutm.app/) fonctionne bien
|
||||
pour ça. Tu obtiens une Debian ou une Ubuntu qui hébergera tout le lab, et tu
|
||||
accèdes aux VMs du lab via RDP depuis ton Mac.
|
||||
|
||||
## Vérification automatique
|
||||
|
||||
Un script vérifie les points critiques :
|
||||
|
||||
```
|
||||
./scripts/check-prereqs.sh # Linux, macOS
|
||||
.\scripts\check-prereqs.ps1 # Windows PowerShell
|
||||
```
|
||||
|
||||
Il remonte, pour chaque critère :
|
||||
|
||||
- `[ OK ]` : validé
|
||||
- `[WARN]` : fonctionnel mais dégradé
|
||||
- `[FAIL]` : bloquant, à corriger avant de continuer
|
||||
|
||||
## Configuration Windows spécifique
|
||||
|
||||
La virtualisation imbriquée doit être activée dans WSL2. Crée le fichier
|
||||
`%USERPROFILE%\.wslconfig` avec :
|
||||
|
||||
```
|
||||
[wsl2]
|
||||
nestedVirtualization=true
|
||||
memory=16GB
|
||||
processors=4
|
||||
```
|
||||
|
||||
Puis relance WSL :
|
||||
|
||||
```
|
||||
wsl --shutdown
|
||||
```
|
||||
|
||||
Docker Desktop repartira avec la nested virt disponible.
|
||||
|
||||
## Étape suivante
|
||||
|
||||
Une fois les prérequis validés, passe à `01-installation-lab.md`.
|
||||
86
docs/etudiant/fr/01-installation-lab.md
Normal file
86
docs/etudiant/fr/01-installation-lab.md
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
# Installation du lab
|
||||
|
||||
Objectif : récupérer le projet, adapter sa configuration, puis démarrer le
|
||||
contrôleur de domaine. Les clients (PC01 et linux01) seront démarrés plus tard
|
||||
dans le parcours.
|
||||
|
||||
## Récupérer le projet
|
||||
|
||||
```
|
||||
git clone <url-du-repo> lab_AD_Complet
|
||||
cd lab_AD_Complet
|
||||
```
|
||||
|
||||
## Adapter la configuration
|
||||
|
||||
Le fichier `.env.example` contient toutes les variables (noms, mots de passe,
|
||||
ressources allouées aux VMs). Copie-le et ouvre-le :
|
||||
|
||||
```
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Modifie au minimum :
|
||||
|
||||
- `AD_DOMAIN` et `AD_DOMAIN_NETBIOS` si tu veux un autre nom que `corp.lab`
|
||||
- `AD_ADMIN_PASSWORD` : doit respecter la politique AD par défaut
|
||||
(10+ caractères, majuscule, minuscule, chiffre, caractère spécial)
|
||||
|
||||
Les autres variables (RAM, CPU, ports) peuvent rester par défaut.
|
||||
|
||||
## Vérifier les prérequis
|
||||
|
||||
```
|
||||
./scripts/check-prereqs.sh
|
||||
```
|
||||
|
||||
Corrige les `[FAIL]` avant de continuer.
|
||||
|
||||
## Démarrer le contrôleur de domaine
|
||||
|
||||
Le lab expose trois services dans `docker-compose.yml` :
|
||||
|
||||
- `dc01` : Windows Server (contrôleur de domaine)
|
||||
- `pc01` : Windows 11 (poste client)
|
||||
- `linux01` : Debian 12 (poste client)
|
||||
|
||||
On démarre uniquement `dc01` pour l'instant :
|
||||
|
||||
```
|
||||
docker compose up -d dc01
|
||||
```
|
||||
|
||||
L'image `dockurr/windows` se télécharge (~1 Go), puis télécharge l'ISO Windows
|
||||
Server et lance une installation automatisée. Selon ta connexion, l'ensemble
|
||||
prend entre 20 et 45 minutes.
|
||||
|
||||
## Suivre la progression
|
||||
|
||||
Deux moyens complémentaires :
|
||||
|
||||
- Via les logs du conteneur :
|
||||
```
|
||||
docker compose logs -f dc01
|
||||
```
|
||||
- Via l'interface web de dockurr :
|
||||
[http://localhost:8006](http://localhost:8006)
|
||||
|
||||
L'interface web affiche la console graphique de la VM. Tu y vois l'installeur
|
||||
Windows se dérouler en temps réel.
|
||||
|
||||
## Accès à DC01
|
||||
|
||||
Une fois Windows démarré et un bureau visible dans l'interface web :
|
||||
|
||||
- Session web : [http://localhost:8006](http://localhost:8006) (lent, pas de copier-coller fiable)
|
||||
- Session RDP : `./scripts/rdp-dc.sh` (recommandé)
|
||||
|
||||
Identifiants par défaut pour le premier login :
|
||||
|
||||
- Utilisateur : `Administrator`
|
||||
- Mot de passe : valeur de `AD_ADMIN_PASSWORD` dans ton `.env`
|
||||
|
||||
## Étape suivante
|
||||
|
||||
Le serveur est installé mais il n'est pas encore contrôleur de domaine. La
|
||||
promotion se fait dans `02-promotion-dc.md`.
|
||||
121
docs/etudiant/fr/02-promotion-dc.md
Normal file
121
docs/etudiant/fr/02-promotion-dc.md
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
# Promouvoir le serveur en contrôleur de domaine
|
||||
|
||||
Objectif : transformer le Windows Server fraîchement installé en premier DC
|
||||
d'une nouvelle forêt Active Directory. On installera aussi le rôle DNS, requis
|
||||
par AD.
|
||||
|
||||
## Ce qu'est AD DS et ce qu'on crée
|
||||
|
||||
Une forêt Active Directory est une structure logique qui contient un ou
|
||||
plusieurs domaines. On va ici créer :
|
||||
|
||||
- une nouvelle forêt dont la racine est le domaine configuré (`corp.lab` par
|
||||
défaut)
|
||||
- un premier contrôleur de domaine (`DC01`) qui héberge la base AD et le DNS
|
||||
|
||||
Le DC est une machine critique : il gère l'authentification, les stratégies de
|
||||
groupe, les enregistrements DNS internes. En production, on en déploie toujours
|
||||
au moins deux pour la redondance. Dans ce lab, un seul suffit.
|
||||
|
||||
## Préparation
|
||||
|
||||
Avant toute chose, on renomme la machine. C'est un geste obligatoire : une
|
||||
fois promue DC, elle ne pourra plus être renommée sans dépromotion.
|
||||
|
||||
### Approche graphique
|
||||
|
||||
1. `Paramètres > Système > À propos > Renommer ce PC` (ou `Win + Pause` puis
|
||||
"Modifier les paramètres")
|
||||
2. Nouveau nom : `DC01`
|
||||
3. Redémarrer
|
||||
|
||||
### Approche PowerShell
|
||||
|
||||
```
|
||||
Rename-Computer -NewName "DC01" -Restart
|
||||
```
|
||||
|
||||
Si `Rename-Computer` refuse l'authentification sur une install fraîche, passe
|
||||
par la GUI ou par le registre (voir `troubleshooting.md`).
|
||||
|
||||
## Installation des rôles
|
||||
|
||||
Après le redémarrage, ouvre une session Administrator.
|
||||
|
||||
### Approche graphique
|
||||
|
||||
1. Ouvre le `Gestionnaire de serveur`
|
||||
2. `Gérer > Ajouter des rôles et fonctionnalités`
|
||||
3. Sélectionne :
|
||||
- `Services AD DS`
|
||||
- `Serveur DNS`
|
||||
4. Laisse les fonctionnalités par défaut, valide et installe
|
||||
5. Une fois l'installation terminée, clique sur le drapeau
|
||||
d'avertissement en haut à droite puis sur
|
||||
`Promouvoir ce serveur en contrôleur de domaine`
|
||||
|
||||
### Approche PowerShell
|
||||
|
||||
```
|
||||
Install-WindowsFeature -Name AD-Domain-Services, DNS -IncludeManagementTools
|
||||
```
|
||||
|
||||
## Promotion en contrôleur de domaine
|
||||
|
||||
### Approche graphique
|
||||
|
||||
1. Dans l'assistant de configuration des services de domaine Active Directory :
|
||||
2. `Ajouter une nouvelle forêt` > Nom racine : `corp.lab`
|
||||
3. Niveaux fonctionnels : laisse `Windows Server 2016` (ou la valeur proposée)
|
||||
4. Coche `Serveur DNS`, `Catalogue global`
|
||||
5. Saisis un mot de passe DSRM (mode restauration des services d'annuaire)
|
||||
6. Ignore les avertissements DNS (normaux sur un DC tout neuf)
|
||||
7. Valide et laisse la machine redémarrer
|
||||
|
||||
### Approche PowerShell
|
||||
|
||||
```
|
||||
$dsrmPwd = Read-Host -AsSecureString "Mot de passe DSRM"
|
||||
Install-ADDSForest `
|
||||
-DomainName "corp.lab" `
|
||||
-DomainNetbiosName "CORP" `
|
||||
-InstallDns `
|
||||
-SafeModeAdministratorPassword $dsrmPwd `
|
||||
-Force
|
||||
```
|
||||
|
||||
Cmdlets clés :
|
||||
|
||||
- `Install-ADDSForest` crée une nouvelle forêt
|
||||
- `Install-ADDSDomainController` joint un DC existant à une forêt
|
||||
(utile quand tu ajoutes un second DC)
|
||||
|
||||
## Validation
|
||||
|
||||
Après redémarrage, reconnecte-toi (compte `CORP\Administrator` désormais) et
|
||||
lance :
|
||||
|
||||
```
|
||||
Get-ADDomain
|
||||
Get-ADForest
|
||||
dcdiag
|
||||
```
|
||||
|
||||
Les deux premières commandes renvoient les infos du domaine. `dcdiag` exécute
|
||||
une batterie de tests d'intégrité. Des avertissements DNS mineurs sont normaux
|
||||
sur un DC isolé.
|
||||
|
||||
## Points d'attention
|
||||
|
||||
- Le mot de passe DSRM est indépendant de celui d'Administrator. Il sert en
|
||||
mode de récupération si AD est corrompu. Note-le dans ton gestionnaire de
|
||||
mots de passe.
|
||||
- Une fois la machine promue DC, elle ne peut plus être renommée sans d'abord
|
||||
être dépromotée (`Uninstall-ADDSDomainController`).
|
||||
- Sur une installation fraîche dockur, la VM a parfois un nom généré
|
||||
automatiquement (`WIN-xxxx`). Rename **avant** la promotion est crucial.
|
||||
|
||||
## Étape suivante
|
||||
|
||||
Le DC est prêt, AD est vide. On passe à la création des OU, utilisateurs et
|
||||
groupes dans `03-ou-utilisateurs-groupes.md`.
|
||||
149
docs/etudiant/fr/03-ou-utilisateurs-groupes.md
Normal file
149
docs/etudiant/fr/03-ou-utilisateurs-groupes.md
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
# Unités d'organisation, utilisateurs, groupes
|
||||
|
||||
Objectif : construire l'arborescence AD (OU), peupler le domaine avec des
|
||||
utilisateurs et des groupes, et appliquer l'imbrication AGDLP recommandée par
|
||||
Microsoft.
|
||||
|
||||
## Qu'est-ce qu'une OU
|
||||
|
||||
Une unité d'organisation (Organizational Unit) est un conteneur logique qui
|
||||
permet de regrouper des objets AD (utilisateurs, ordinateurs, groupes) pour
|
||||
leur appliquer des stratégies, déléguer leur administration, ou les organiser.
|
||||
|
||||
Une OU n'accorde aucun droit en soi. C'est un outil de structuration.
|
||||
|
||||
## Arborescence proposée
|
||||
|
||||
```
|
||||
corp.lab
|
||||
└── CORP
|
||||
├── Utilisateurs
|
||||
│ ├── Direction
|
||||
│ ├── Pedagogie
|
||||
│ ├── Informatique
|
||||
│ ├── Administration
|
||||
│ └── Etudiants
|
||||
├── Ordinateurs
|
||||
│ └── (mêmes sous-OU)
|
||||
├── Groupes
|
||||
└── Services
|
||||
```
|
||||
|
||||
Tu peux calquer cette structure ou l'adapter à ton contexte.
|
||||
|
||||
## Création des OU
|
||||
|
||||
### Approche graphique
|
||||
|
||||
1. Ouvrir `Utilisateurs et ordinateurs Active Directory` (`dsa.msc`)
|
||||
2. Clic droit sur le domaine > `Nouveau > Unité d'organisation`
|
||||
3. Nommer `CORP`
|
||||
4. Dans `CORP`, créer les sous-OU `Utilisateurs`, `Ordinateurs`, `Groupes`, `Services`
|
||||
5. Créer les OU départementales sous `Utilisateurs` et `Ordinateurs`
|
||||
|
||||
### Approche PowerShell
|
||||
|
||||
Cmdlet clé : `New-ADOrganizationalUnit`.
|
||||
|
||||
```
|
||||
New-ADOrganizationalUnit -Name "CORP" -Path "DC=corp,DC=lab"
|
||||
New-ADOrganizationalUnit -Name "Utilisateurs" -Path "OU=CORP,DC=corp,DC=lab"
|
||||
```
|
||||
|
||||
Boucle pour créer les départements :
|
||||
|
||||
```
|
||||
$deps = @("Direction","Pedagogie","Informatique","Administration","Etudiants")
|
||||
foreach ($d in $deps) {
|
||||
New-ADOrganizationalUnit -Name $d -Path "OU=Utilisateurs,OU=CORP,DC=corp,DC=lab"
|
||||
}
|
||||
```
|
||||
|
||||
## Création des utilisateurs
|
||||
|
||||
### Approche graphique
|
||||
|
||||
1. Clic droit sur l'OU département > `Nouveau > Utilisateur`
|
||||
2. Remplir les champs (Nom, Prénom, SamAccountName, UPN)
|
||||
3. Mot de passe initial, cocher `L'utilisateur doit changer de mot de passe à la prochaine ouverture de session`
|
||||
|
||||
### Approche PowerShell
|
||||
|
||||
Cmdlet clé : `New-ADUser`.
|
||||
|
||||
```
|
||||
New-ADUser `
|
||||
-Name "Paul Martin" `
|
||||
-GivenName "Paul" `
|
||||
-Surname "Martin" `
|
||||
-SamAccountName "pmartin" `
|
||||
-UserPrincipalName "pmartin@corp.lab" `
|
||||
-Path "OU=Pedagogie,OU=Utilisateurs,OU=CORP,DC=corp,DC=lab" `
|
||||
-AccountPassword (ConvertTo-SecureString "UserP@ss!2026" -AsPlainText -Force) `
|
||||
-Enabled $true `
|
||||
-ChangePasswordAtLogon $true
|
||||
```
|
||||
|
||||
## Création des groupes
|
||||
|
||||
Deux types de groupes vont nous servir :
|
||||
|
||||
- **Groupes globaux (GG)** : regroupent des utilisateurs par département,
|
||||
projet, fonction. Exemples : `GG_Pedagogie`, `GG_Etudiants`.
|
||||
- **Groupes de domaine locaux (DL)** : se voient attribuer les permissions
|
||||
sur les ressources. Exemples : `DL_Partage_Commun_R`, `DL_Partage_Pedago_RW`.
|
||||
|
||||
### Approche graphique
|
||||
|
||||
1. Clic droit sur `OU=Groupes` > `Nouveau > Groupe`
|
||||
2. Portée : `Global` ou `Domaine local` selon le cas
|
||||
3. Type : `Sécurité`
|
||||
|
||||
### Approche PowerShell
|
||||
|
||||
Cmdlet clé : `New-ADGroup`.
|
||||
|
||||
```
|
||||
New-ADGroup -Name "GG_Pedagogie" -GroupScope Global -GroupCategory Security `
|
||||
-Path "OU=Groupes,OU=CORP,DC=corp,DC=lab"
|
||||
|
||||
New-ADGroup -Name "DL_Partage_Commun_R" -GroupScope DomainLocal -GroupCategory Security `
|
||||
-Path "OU=Groupes,OU=CORP,DC=corp,DC=lab"
|
||||
```
|
||||
|
||||
## Appliquer l'imbrication AGDLP
|
||||
|
||||
AGDLP est une convention Microsoft :
|
||||
|
||||
- **A**ccount (utilisateur) dans
|
||||
- **G**lobal group (département) membre de
|
||||
- **D**omain **L**ocal group (ressource) qui détient la
|
||||
- **P**ermission
|
||||
|
||||
Concrètement :
|
||||
|
||||
1. Ajoute les utilisateurs aux groupes globaux correspondants
|
||||
2. Ajoute les groupes globaux aux groupes de domaine local correspondants
|
||||
3. Pose les permissions NTFS/partages sur les groupes de domaine local
|
||||
|
||||
Cmdlet clé : `Add-ADGroupMember`.
|
||||
|
||||
```
|
||||
Add-ADGroupMember -Identity "GG_Pedagogie" -Members "pmartin"
|
||||
Add-ADGroupMember -Identity "DL_Partage_Commun_R" -Members "GG_Pedagogie","GG_Etudiants"
|
||||
```
|
||||
|
||||
## Validation
|
||||
|
||||
```
|
||||
Get-ADUser -Filter * -SearchBase "OU=CORP,DC=corp,DC=lab" | Select Name, SamAccountName
|
||||
Get-ADGroup -Filter * -SearchBase "OU=Groupes,OU=CORP,DC=corp,DC=lab" | Select Name, GroupScope
|
||||
Get-ADGroupMember -Identity "GG_Pedagogie"
|
||||
```
|
||||
|
||||
Côté graphique, la console `dsa.msc` doit afficher la hiérarchie créée, les
|
||||
utilisateurs dans leurs OU, et les membres des groupes.
|
||||
|
||||
## Étape suivante
|
||||
|
||||
L'AD est peuplé. On passe aux stratégies de groupe dans `04-gpo.md`.
|
||||
130
docs/etudiant/fr/04-gpo.md
Normal file
130
docs/etudiant/fr/04-gpo.md
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
# Stratégies de groupe (GPO)
|
||||
|
||||
Objectif : créer et lier quelques GPO représentatives d'un cas réel.
|
||||
|
||||
## Ce qu'est une GPO
|
||||
|
||||
Une stratégie de groupe (Group Policy Object) est un ensemble de paramètres
|
||||
qui s'appliquent aux utilisateurs ou aux ordinateurs. Elle s'écrit dans
|
||||
`SYSVOL` (stocké sur les DC) et se synchronise sur toutes les machines jointes
|
||||
au domaine.
|
||||
|
||||
Deux portées principales :
|
||||
|
||||
- `Configuration ordinateur` : s'applique quand la machine démarre
|
||||
- `Configuration utilisateur` : s'applique quand un utilisateur ouvre session
|
||||
|
||||
Une GPO est **liée** à un conteneur (site, domaine, OU). Les objets situés dans
|
||||
ce conteneur et ses descendants héritent de la GPO. On utilise donc les OU
|
||||
pour cibler : tu peux lier une GPO à l'OU `Etudiants` et elle ne s'appliquera
|
||||
qu'aux utilisateurs de cette OU.
|
||||
|
||||
## Scénarios à mettre en place
|
||||
|
||||
Pour ce lab, on va créer trois GPO typiques :
|
||||
|
||||
1. Durcir la politique de mot de passe du domaine
|
||||
2. Imposer un fond d'écran aux étudiants
|
||||
3. Restreindre l'accès au Panneau de configuration pour les étudiants
|
||||
|
||||
## Politique de mot de passe
|
||||
|
||||
Stockée dans la `Default Domain Policy`, elle s'applique à tout le domaine.
|
||||
|
||||
### Approche graphique
|
||||
|
||||
1. Ouvrir la console `Gestion des stratégies de groupe` (`gpmc.msc`)
|
||||
2. Domaine > `Default Domain Policy` > clic droit > `Modifier`
|
||||
3. `Configuration ordinateur > Stratégies > Paramètres Windows > Paramètres de sécurité > Stratégies de compte > Stratégie de mot de passe`
|
||||
4. Ajuste les paramètres : longueur minimale, complexité, historique, durée
|
||||
|
||||
### Approche PowerShell
|
||||
|
||||
Cmdlet clé : `Set-ADDefaultDomainPasswordPolicy`.
|
||||
|
||||
```
|
||||
Set-ADDefaultDomainPasswordPolicy -Identity corp.lab `
|
||||
-MinPasswordLength 10 `
|
||||
-ComplexityEnabled $true `
|
||||
-PasswordHistoryCount 5 `
|
||||
-MaxPasswordAge (New-TimeSpan -Days 90) `
|
||||
-LockoutThreshold 5 `
|
||||
-LockoutDuration (New-TimeSpan -Minutes 15)
|
||||
```
|
||||
|
||||
## GPO "fond d'écran imposé"
|
||||
|
||||
### Approche graphique
|
||||
|
||||
1. `gpmc.msc` > Domaine > clic droit sur `OU=Etudiants,OU=Utilisateurs,OU=CORP` > `Créer un objet GPO dans ce domaine et le lier ici`
|
||||
2. Nomme la GPO (ex : `GPO_Etudiants_FondEcran`)
|
||||
3. Clic droit sur la GPO > `Modifier`
|
||||
4. `Configuration utilisateur > Stratégies > Modèles d'administration > Bureau > Bureau`
|
||||
5. Paramètre `Papier peint du bureau` > `Activé`, renseigne le chemin de
|
||||
l'image (ex: `C:\Windows\Web\Wallpaper\Windows\img0.jpg`) et le style
|
||||
|
||||
### Approche PowerShell
|
||||
|
||||
Cmdlets clés : `New-GPO`, `New-GPLink`, `Set-GPRegistryValue`.
|
||||
|
||||
```
|
||||
New-GPO -Name "GPO_Etudiants_FondEcran"
|
||||
|
||||
Set-GPRegistryValue -Name "GPO_Etudiants_FondEcran" `
|
||||
-Key "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System" `
|
||||
-ValueName "Wallpaper" -Type String -Value "C:\Windows\Web\Wallpaper\Windows\img0.jpg"
|
||||
|
||||
New-GPLink -Name "GPO_Etudiants_FondEcran" `
|
||||
-Target "OU=Etudiants,OU=Utilisateurs,OU=CORP,DC=corp,DC=lab"
|
||||
```
|
||||
|
||||
## GPO "restriction du Panneau de configuration"
|
||||
|
||||
### Approche graphique
|
||||
|
||||
Même démarche que ci-dessus, paramètre :
|
||||
|
||||
`Configuration utilisateur > Stratégies > Modèles d'administration > Panneau de configuration > Interdire l'accès au Panneau de configuration et aux paramètres du PC > Activé`
|
||||
|
||||
### Approche PowerShell
|
||||
|
||||
```
|
||||
New-GPO -Name "GPO_Etudiants_RestrictionsPC"
|
||||
|
||||
Set-GPRegistryValue -Name "GPO_Etudiants_RestrictionsPC" `
|
||||
-Key "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" `
|
||||
-ValueName "NoControlPanel" -Type DWord -Value 1
|
||||
|
||||
New-GPLink -Name "GPO_Etudiants_RestrictionsPC" `
|
||||
-Target "OU=Etudiants,OU=Utilisateurs,OU=CORP,DC=corp,DC=lab"
|
||||
```
|
||||
|
||||
## Tester l'application
|
||||
|
||||
Sur un poste client où un étudiant est connecté :
|
||||
|
||||
```
|
||||
gpupdate /force
|
||||
gpresult /r
|
||||
```
|
||||
|
||||
`gpresult` liste les GPO effectivement appliquées. Si ta GPO n'apparaît pas,
|
||||
vérifie :
|
||||
|
||||
- l'utilisateur est bien dans la bonne OU ?
|
||||
- la GPO est liée à la bonne OU ?
|
||||
- l'utilisateur a `ApplyGroupPolicy` comme droit (filtrage de sécurité) ?
|
||||
- la GPO n'est pas filtrée par WMI ?
|
||||
|
||||
## Points d'attention
|
||||
|
||||
- Évite de modifier la `Default Domain Policy` au-delà de la politique de mot
|
||||
de passe. Pour le reste, crée toujours une GPO dédiée.
|
||||
- L'ordre d'application des GPO est : Local > Site > Domaine > OU
|
||||
(la plus proche l'emporte en cas de conflit).
|
||||
- Le blocage d'héritage (`Block Inheritance`) sur une OU fille casse la chaîne.
|
||||
Utilise-le avec parcimonie.
|
||||
|
||||
## Étape suivante
|
||||
|
||||
`05-partages-ntfs.md` pour les partages SMB et les permissions NTFS.
|
||||
120
docs/etudiant/fr/05-partages-ntfs.md
Normal file
120
docs/etudiant/fr/05-partages-ntfs.md
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
# Partages SMB et permissions NTFS
|
||||
|
||||
Objectif : exposer trois partages réseau sur `DC01`, les sécuriser avec les
|
||||
groupes AD créés précédemment, et vérifier que les permissions s'appliquent
|
||||
bien selon l'utilisateur connecté.
|
||||
|
||||
Note : dans un environnement de production on héberge les partages sur un
|
||||
serveur de fichiers dédié, pas sur un DC. Dans ce lab on simplifie.
|
||||
|
||||
## Partages à créer
|
||||
|
||||
| Partage | Chemin | Accès |
|
||||
|---|---|---|
|
||||
| `Commun` | `C:\Partages\Commun` | lecture pour tout le monde, écriture pour Direction/Pédago/Admin |
|
||||
| `Pedago` | `C:\Partages\Pedago` | accès restreint à GG_Pedagogie |
|
||||
| `Direction` | `C:\Partages\Direction` | accès restreint à GG_Direction |
|
||||
|
||||
## Rappel AGDLP
|
||||
|
||||
Les permissions ne sont **jamais** posées sur des groupes globaux ou sur des
|
||||
utilisateurs directement. Elles sont attribuées à un **groupe de domaine
|
||||
local**, dans lequel on ajoute les groupes globaux concernés.
|
||||
|
||||
Exemple pour le partage `Commun` :
|
||||
|
||||
- Groupes globaux : `GG_Pedagogie`, `GG_Etudiants`, ...
|
||||
- Groupes DL : `DL_Partage_Commun_R` (lecture), `DL_Partage_Commun_RW` (écriture)
|
||||
- Permissions NTFS : posées sur `DL_Partage_Commun_R` et `DL_Partage_Commun_RW`
|
||||
- Imbrication :
|
||||
- `GG_Etudiants` membre de `DL_Partage_Commun_R`
|
||||
- `GG_Pedagogie` membre de `DL_Partage_Commun_RW`
|
||||
|
||||
## Création des dossiers et partages
|
||||
|
||||
### Approche graphique
|
||||
|
||||
1. Dans l'Explorateur, crée `C:\Partages\Commun`
|
||||
2. Clic droit > `Propriétés > Partage > Partage avancé`
|
||||
3. Coche `Partager ce dossier`, nomme le partage, clique `Autorisations`
|
||||
4. Par défaut, retire `Tout le monde`
|
||||
5. Ajoute les groupes AD souhaités avec les droits (Lecture, Modifier, Contrôle total)
|
||||
6. Onglet `Sécurité` > `Modifier` : définis les ACL NTFS
|
||||
7. Décoche l'héritage si tu veux une ACL explicite
|
||||
|
||||
### Approche PowerShell
|
||||
|
||||
Cmdlets clés : `New-SmbShare`, `Get-Acl`, `Set-Acl`, `FileSystemAccessRule`.
|
||||
|
||||
```
|
||||
# Dossiers
|
||||
New-Item -Path C:\Partages\Commun -ItemType Directory -Force
|
||||
|
||||
# Partage SMB avec droits de partage
|
||||
New-SmbShare -Name "Commun" -Path "C:\Partages\Commun" `
|
||||
-FullAccess "CORP\Domain Admins" `
|
||||
-ReadAccess "CORP\DL_Partage_Commun_R" `
|
||||
-ChangeAccess "CORP\DL_Partage_Commun_RW"
|
||||
```
|
||||
|
||||
Permissions NTFS :
|
||||
|
||||
```
|
||||
$acl = Get-Acl "C:\Partages\Commun"
|
||||
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
|
||||
"CORP\DL_Partage_Commun_R", "ReadAndExecute", "ContainerInherit,ObjectInherit", "None", "Allow")
|
||||
$acl.AddAccessRule($rule)
|
||||
Set-Acl "C:\Partages\Commun" $acl
|
||||
```
|
||||
|
||||
Reproduis pour chaque couple (DL, droits).
|
||||
|
||||
## Tester depuis un client Windows
|
||||
|
||||
Sur `PC01`, connecté en tant qu'utilisateur AD :
|
||||
|
||||
```
|
||||
\\DC01\Commun
|
||||
```
|
||||
|
||||
via `Exécuter` (`Win + R`) ou la barre d'adresse de l'Explorateur.
|
||||
|
||||
Tests à faire :
|
||||
|
||||
- avec un membre de `GG_Etudiants` : lecture OK, écriture refusée
|
||||
- avec un membre de `GG_Pedagogie` : lecture et écriture OK
|
||||
- tentative d'accès à `\\DC01\Pedago` depuis un étudiant : refus attendu
|
||||
|
||||
## Tester depuis le client Linux
|
||||
|
||||
Si `linux01` est joint au domaine (voir `07-jonction-poste-linux.md`) :
|
||||
|
||||
```
|
||||
smbclient //DC01/Commun -U pmartin%<mot_de_passe>
|
||||
# une fois connecté :
|
||||
ls
|
||||
put /etc/hostname
|
||||
```
|
||||
|
||||
ou via `cifs-utils` pour un montage :
|
||||
|
||||
```
|
||||
mkdir /mnt/commun
|
||||
mount -t cifs //DC01/Commun /mnt/commun -o username=pmartin,domain=CORP
|
||||
```
|
||||
|
||||
## Points d'attention
|
||||
|
||||
- Les **deux** couches de permissions (Partage et NTFS) s'appliquent. L'accès
|
||||
effectif est l'intersection (la plus restrictive l'emporte). Bonne pratique :
|
||||
mettre `Contrôle total` au niveau du partage, puis affiner via NTFS.
|
||||
- Un utilisateur déjà connecté ne "voit" pas immédiatement une modification
|
||||
d'appartenance à un groupe AD. Il doit se déconnecter / reconnecter (ou
|
||||
relancer `klist purge`).
|
||||
- Ne pose jamais d'ACL directement sur un utilisateur. Si la personne quitte,
|
||||
les ACL deviennent du ménage à faire à la main.
|
||||
|
||||
## Étape suivante
|
||||
|
||||
`06-jonction-poste-windows.md` pour joindre `PC01` au domaine et tester ces
|
||||
partages depuis un poste client.
|
||||
166
docs/etudiant/fr/06-jonction-poste-windows.md
Normal file
166
docs/etudiant/fr/06-jonction-poste-windows.md
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
# Joindre le poste Windows au domaine
|
||||
|
||||
Objectif : démarrer le conteneur `pc01`, installer Windows 11, puis joindre la
|
||||
machine au domaine `corp.lab`.
|
||||
|
||||
## Démarrer le conteneur
|
||||
|
||||
```
|
||||
docker compose up -d pc01
|
||||
```
|
||||
|
||||
L'installation Windows 11 se déroule en automatique, même principe que pour
|
||||
`DC01`. Compte 20 à 40 minutes. Suis la progression via :
|
||||
|
||||
- [http://localhost:8009](http://localhost:8009) (port web de `pc01`)
|
||||
- `docker compose logs -f pc01`
|
||||
|
||||
Une fois le bureau accessible, utilise RDP pour la suite :
|
||||
|
||||
```
|
||||
./scripts/rdp-client.sh
|
||||
```
|
||||
|
||||
Identifiants locaux : `LocalAdmin` / `AD_ADMIN_PASSWORD` (même valeur que pour
|
||||
DC01 dans ce lab).
|
||||
|
||||
## Étape 1 : préparer le client
|
||||
|
||||
### Renommer la machine
|
||||
|
||||
Les installs dockurr partent avec un hostname généré (`WIN-xxxxxxx`). On le
|
||||
change avant de joindre. Approche graphique via `Paramètres > Système > À
|
||||
propos > Renommer ce PC`, ou PowerShell :
|
||||
|
||||
```
|
||||
Rename-Computer -NewName "PC01" -Restart
|
||||
```
|
||||
|
||||
### Pointer le DNS vers le DC
|
||||
|
||||
Sans DNS correct, la jonction échoue. PC01 doit interroger `DC01` pour
|
||||
résoudre `corp.lab` et les enregistrements SRV d'AD.
|
||||
|
||||
Approche graphique : `Paramètres > Réseau > Propriétés de la carte réseau >
|
||||
Modifier les paramètres DNS`.
|
||||
|
||||
Approche PowerShell :
|
||||
|
||||
```
|
||||
Get-NetAdapter | Format-Table Name, Status
|
||||
# Remplace "Ethernet" par le nom de ta carte
|
||||
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses <IP_du_DC>
|
||||
```
|
||||
|
||||
Pour déterminer l'IP à utiliser, voir le bloc "Spécificité du lab Docker"
|
||||
ci-dessous.
|
||||
|
||||
### Spécificité du lab Docker
|
||||
|
||||
`dockurr/windows` fait tourner Windows dans une VM avec NAT interne. L'IP que
|
||||
le DC annonce dans son DNS est son IP interne VM (non routable depuis
|
||||
`PC01`). Mais le conteneur DC dispose d'une règle DNAT qui forwarde tous les
|
||||
ports vers la VM.
|
||||
|
||||
Solution : utilise l'IP du **conteneur** `DC01` (celle visible via
|
||||
`docker inspect lab-dc01`) et ajoute une entrée `hosts` pour que la résolution
|
||||
retombe dessus.
|
||||
|
||||
Dans PowerShell (PC01) :
|
||||
|
||||
```
|
||||
# Remplacer <IP_CONTAINER_DC> par celle retournée côté hôte par :
|
||||
# docker inspect lab-dc01 --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
|
||||
Add-Content C:\Windows\System32\drivers\etc\hosts "`n<IP_CONTAINER_DC> corp.lab dc01.corp.lab dc01"
|
||||
ipconfig /flushdns
|
||||
```
|
||||
|
||||
Test :
|
||||
|
||||
```
|
||||
Test-NetConnection -ComputerName corp.lab -Port 389
|
||||
nslookup corp.lab
|
||||
```
|
||||
|
||||
## Étape 2 : joindre au domaine
|
||||
|
||||
### Approche graphique
|
||||
|
||||
1. `Paramètres > Système > À propos > Joindre un domaine`
|
||||
2. Ou via `sysdm.cpl > Modifier`
|
||||
3. Saisir `corp.lab`, valider
|
||||
4. Entrer les identifiants `CORP\Administrator`
|
||||
5. Redémarrer quand demandé
|
||||
|
||||
### Approche PowerShell
|
||||
|
||||
Cmdlet clé : `Add-Computer`.
|
||||
|
||||
```
|
||||
$pass = ConvertTo-SecureString "AdminP@ss!2026" -AsPlainText -Force
|
||||
$cred = New-Object System.Management.Automation.PSCredential("CORP\Administrator", $pass)
|
||||
|
||||
Add-Computer -DomainName corp.lab -Credential $cred -Restart
|
||||
```
|
||||
|
||||
## Étape 3 : autoriser un utilisateur AD à se connecter en RDP
|
||||
|
||||
Par défaut, seuls les membres du groupe local `Administrateurs` peuvent
|
||||
ouvrir une session RDP. Après jonction au domaine, le groupe local
|
||||
`Administrateurs` contient `CORP\Domain Admins`, donc un admin de domaine
|
||||
peut RDP. Mais les utilisateurs standards doivent être ajoutés explicitement.
|
||||
|
||||
### Approche graphique
|
||||
|
||||
1. Clic droit sur `Ce PC > Propriétés > Paramètres d'utilisation à distance`
|
||||
2. `Sélectionner les utilisateurs` > Ajouter `CORP\pmartin` (ou un groupe AD)
|
||||
|
||||
### Approche PowerShell
|
||||
|
||||
```
|
||||
Add-LocalGroupMember -Group "Utilisateurs du Bureau à distance" -Member "CORP\pmartin"
|
||||
```
|
||||
|
||||
En pratique, crée un groupe AD dédié (par exemple `GG_UtilisateursRDP`) et
|
||||
ajoute-le via GPO au groupe local de toutes les machines.
|
||||
|
||||
## Étape 4 : tester la connexion en utilisateur AD
|
||||
|
||||
Depuis l'hôte Linux/macOS :
|
||||
|
||||
```
|
||||
xfreerdp3 /v:127.0.0.1:3391 /u:pmartin /d:CORP /p:'<mdp>' /cert:ignore +clipboard /size:1600x900 /dynamic-resolution
|
||||
```
|
||||
|
||||
Sous Windows, utilise `mstsc` et saisis `CORP\pmartin`.
|
||||
|
||||
Une fois connecté, valide :
|
||||
|
||||
```
|
||||
whoami
|
||||
whoami /groups
|
||||
Get-ComputerInfo | Select CsDomain, CsDomainRole
|
||||
```
|
||||
|
||||
Tu dois voir :
|
||||
|
||||
- `CORP\pmartin`
|
||||
- les groupes AD de l'utilisateur
|
||||
- `CsDomainRole : MemberWorkstation`
|
||||
|
||||
## Points d'attention
|
||||
|
||||
- Un compte avec l'option "changement de mot de passe au prochain login" ne
|
||||
peut pas se connecter via RDP avec NLA. Soit tu désactives l'option côté DC
|
||||
(`Set-ADUser -ChangePasswordAtLogon $false`), soit tu forces un premier
|
||||
login via `/sec:rdp` pour afficher la page de changement.
|
||||
- Si tu rencontres `Le mappage entre les noms de compte et les ID de sécurité
|
||||
n'a pas été effectué` lors d'un `Add-Computer`, le PC a un état AD corrompu.
|
||||
Repasse en workgroup via `Add-Computer -WorkgroupName "WORKGROUP" -Force`
|
||||
puis recommence.
|
||||
- Ne laisse pas traîner des comptes d'ordinateur orphelins : quand tu
|
||||
recrées `PC01`, pense à supprimer l'entrée dans `CN=Computers`.
|
||||
|
||||
## Étape suivante
|
||||
|
||||
`07-jonction-poste-linux.md` pour faire la même chose côté Linux.
|
||||
144
docs/etudiant/fr/07-jonction-poste-linux.md
Normal file
144
docs/etudiant/fr/07-jonction-poste-linux.md
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
# Joindre le poste Linux au domaine
|
||||
|
||||
Objectif : configurer le client Debian `linux01` pour qu'il s'authentifie
|
||||
auprès de l'AD, et valider la résolution des utilisateurs et groupes AD.
|
||||
|
||||
La stack utilisée est la stack standard sur Debian/Ubuntu/RHEL :
|
||||
|
||||
- `realmd` : outil de découverte et d'adhésion à un domaine
|
||||
- `sssd` : démon qui gère l'intégration (cache, Kerberos, NSS, PAM)
|
||||
- `adcli` : client de bas niveau pour AD
|
||||
- `krb5` : couche Kerberos
|
||||
|
||||
Tous ces paquets sont déjà présents dans l'image (voir
|
||||
`linux-client/Dockerfile`).
|
||||
|
||||
## Démarrer le conteneur
|
||||
|
||||
```
|
||||
docker compose up -d linux01
|
||||
docker exec -it lab-linux01 bash
|
||||
```
|
||||
|
||||
Le point d'entrée configure automatiquement `/etc/resolv.conf` pour pointer
|
||||
vers l'IP du conteneur `DC01` et ajoute des entrées `hosts` pour les noms AD.
|
||||
|
||||
Vérifie :
|
||||
|
||||
```
|
||||
cat /etc/resolv.conf
|
||||
cat /etc/hosts | tail
|
||||
ping -c 2 corp.lab
|
||||
```
|
||||
|
||||
## Découverte du domaine
|
||||
|
||||
Cmdlet clé : `realm discover`.
|
||||
|
||||
```
|
||||
realm discover corp.lab
|
||||
```
|
||||
|
||||
Tu dois voir une réponse structurée indiquant `type: kerberos` et
|
||||
`server-software: active-directory`.
|
||||
|
||||
Si tu n'as rien, vérifie la résolution DNS : le DC doit répondre au port 53
|
||||
sur l'IP utilisée.
|
||||
|
||||
## Jonction au domaine
|
||||
|
||||
Cmdlet clé : `realm join`.
|
||||
|
||||
```
|
||||
realm join -U Administrator corp.lab
|
||||
# Saisir le mot de passe de CORP\Administrator quand demandé
|
||||
```
|
||||
|
||||
Sous le capot, `realmd` :
|
||||
|
||||
1. Crée un compte ordinateur `LINUX01` dans `CN=Computers`
|
||||
2. Génère un keytab Kerberos dans `/etc/krb5.keytab`
|
||||
3. Configure `/etc/sssd/sssd.conf`
|
||||
4. Active `sssd` pour les bases NSS (passwd, group) et PAM
|
||||
|
||||
## Démarrer sssd
|
||||
|
||||
Dans un conteneur, systemd n'est pas toujours disponible. On lance sssd
|
||||
directement :
|
||||
|
||||
```
|
||||
sssd --daemon
|
||||
```
|
||||
|
||||
## Validation
|
||||
|
||||
Résolution NSS :
|
||||
|
||||
```
|
||||
id pmartin@corp.lab
|
||||
getent passwd pmartin@corp.lab
|
||||
getent group 'GG_Pedagogie@corp.lab'
|
||||
```
|
||||
|
||||
Tu dois voir :
|
||||
|
||||
- un UID attribué par sssd (grosse valeur, dérivée du SID)
|
||||
- la liste des groupes AD de l'utilisateur, incluant l'imbrication AGDLP
|
||||
|
||||
Authentification Kerberos :
|
||||
|
||||
```
|
||||
kinit pmartin@CORP.LAB
|
||||
klist
|
||||
```
|
||||
|
||||
`klist` doit afficher un TGT (Ticket Granting Ticket) valide.
|
||||
|
||||
## Se connecter en SSH avec un compte AD
|
||||
|
||||
Si tu as activé SSH dans le conteneur (c'est le cas par défaut avec le
|
||||
Dockerfile fourni), depuis l'hôte :
|
||||
|
||||
```
|
||||
ssh pmartin@lab-linux01
|
||||
# ou l'IP du conteneur
|
||||
```
|
||||
|
||||
Le home directory est créé automatiquement au premier login grâce au module
|
||||
`pam_mkhomedir` configuré dans l'entrypoint.
|
||||
|
||||
## Limiter l'accès à certains groupes AD
|
||||
|
||||
Par défaut, tous les utilisateurs AD peuvent se connecter. Pour restreindre :
|
||||
|
||||
```
|
||||
realm permit -g "GG_Pedagogie@corp.lab"
|
||||
```
|
||||
|
||||
ou l'inverse (tout interdire sauf exception) via le fichier
|
||||
`/etc/sssd/sssd.conf`.
|
||||
|
||||
## Points d'attention
|
||||
|
||||
- `realm join` échoue si la résolution DNS est mauvaise ou si l'heure du
|
||||
client dérive de plus de 5 minutes par rapport au DC. Sur un conteneur
|
||||
fraîchement démarré, l'heure est celle de l'hôte, ça suffit.
|
||||
- Dans ce lab, la résolution DNS est rusée : le DC annonce une IP interne
|
||||
non routable. On contourne via `/etc/hosts`. En production, tu aurais le DC
|
||||
directement joignable sur le réseau.
|
||||
- `sssd` cache les utilisateurs pendant 6h par défaut. Si tu modifies un
|
||||
groupe côté AD et que l'effet ne se voit pas, lance `sss_cache -E` ou
|
||||
redémarre `sssd`.
|
||||
|
||||
## Quitter le domaine
|
||||
|
||||
```
|
||||
realm leave corp.lab
|
||||
```
|
||||
|
||||
Le compte ordinateur est supprimé côté DC, le keytab retiré, sssd désactivé.
|
||||
|
||||
## Étape suivante
|
||||
|
||||
Le lab est complètement opérationnel. Consulte `troubleshooting.md` en cas de
|
||||
souci.
|
||||
156
docs/etudiant/fr/troubleshooting.md
Normal file
156
docs/etudiant/fr/troubleshooting.md
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
# Résolution des problèmes courants
|
||||
|
||||
Ce document recense les pièges rencontrés lors de la mise en place du lab.
|
||||
|
||||
## Installation Windows bloquée
|
||||
|
||||
Symptôme : l'interface http://localhost:8006 reste sur l'écran de
|
||||
téléchargement de l'ISO.
|
||||
|
||||
Causes possibles :
|
||||
|
||||
- Connexion internet lente ou coupée (l'ISO pèse plusieurs Go)
|
||||
- Stockage insuffisant sur le disque hôte
|
||||
- Filesystem `btrfs` sur le volume `/storage` (dockurr le signale, rarement
|
||||
bloquant en lab)
|
||||
|
||||
Vérifie `docker compose logs -f dc01` et relance si besoin.
|
||||
|
||||
## /dev/kvm inaccessible
|
||||
|
||||
Symptôme : `KVM acceleration not available` dans les logs dockurr.
|
||||
|
||||
Causes :
|
||||
|
||||
- Virtualisation désactivée dans le BIOS
|
||||
- Ton utilisateur pas dans le groupe `kvm`
|
||||
- WSL2 sans virtualisation imbriquée (Windows)
|
||||
|
||||
Solutions :
|
||||
|
||||
- Linux : `sudo usermod -aG kvm $USER` puis reconnexion
|
||||
- Windows : éditer `%USERPROFILE%\.wslconfig` avec `nestedVirtualization=true`
|
||||
- macOS Apple Silicon : non supporté, utilise UTM
|
||||
|
||||
## Rename-Computer refuse l'auth
|
||||
|
||||
Symptôme : `Rename-Computer : ... Le nom d'utilisateur ou le mot de passe est incorrect.`
|
||||
|
||||
Ça arrive sur une installation fraîche, avant même toute jonction domaine. Le
|
||||
cmdlet tente une authentification locale qui échoue pour une raison obscure.
|
||||
|
||||
Solutions :
|
||||
|
||||
- Utiliser la GUI : `sysdm.cpl > Modifier`
|
||||
- Passer par le registre :
|
||||
```
|
||||
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "Hostname" -Value "NOUVEAU"
|
||||
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "NV Hostname" -Value "NOUVEAU"
|
||||
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName" -Name "ComputerName" -Value "NOUVEAU"
|
||||
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName" -Name "ComputerName" -Value "NOUVEAU"
|
||||
Restart-Computer -Force
|
||||
```
|
||||
|
||||
## Add-Computer : "l'ordinateur se trouve déjà dans ce domaine"
|
||||
|
||||
Le PC a un état domaine partiel (suffixe DNS, workgroup portant le même nom
|
||||
que le NetBIOS du domaine, jonction antérieure). Sort d'abord proprement :
|
||||
|
||||
```
|
||||
Add-Computer -WorkgroupName "WORKGROUP" -Force
|
||||
Restart-Computer -Force
|
||||
```
|
||||
|
||||
Si `Remove-Computer` échoue avec `Le mappage entre les noms de compte et les
|
||||
ID de sécurité n'a pas été effectué`, force via WMI :
|
||||
|
||||
```
|
||||
$cs = Get-WmiObject Win32_ComputerSystem
|
||||
$cs.UnjoinDomainOrWorkgroup($null, $null, 0)
|
||||
Restart-Computer -Force
|
||||
```
|
||||
|
||||
## RDP refuse l'utilisateur AD
|
||||
|
||||
Symptôme : `ERRCONNECT_CONNECT_TRANSPORT_FAILED` après NLA côté freerdp, ou
|
||||
"accès refusé" côté mstsc.
|
||||
|
||||
Cause : par défaut, seul le groupe local `Administrateurs` a le droit RDP.
|
||||
Les utilisateurs du domaine ne l'ont pas.
|
||||
|
||||
Solution sur le poste :
|
||||
|
||||
```
|
||||
Add-LocalGroupMember -Group "Utilisateurs du Bureau à distance" -Member "CORP\pmartin"
|
||||
```
|
||||
|
||||
En production, on le pousse via GPO sur toutes les machines.
|
||||
|
||||
## "Le mot de passe doit être changé" via freerdp
|
||||
|
||||
Symptôme : `ERRCONNECT_PASSWORD_MUST_CHANGE`.
|
||||
|
||||
freerdp avec NLA ne sait pas afficher l'écran de changement. Deux options :
|
||||
|
||||
- Désactiver la mention côté DC :
|
||||
```
|
||||
Set-ADAccountPassword -Identity pmartin -Reset -NewPassword (ConvertTo-SecureString "NewP@ss!2026" -AsPlainText -Force)
|
||||
Set-ADUser -Identity pmartin -ChangePasswordAtLogon $false
|
||||
```
|
||||
- Ou bypass NLA :
|
||||
```
|
||||
xfreerdp3 /sec:rdp ...
|
||||
```
|
||||
|
||||
## realm discover ne répond rien
|
||||
|
||||
Causes :
|
||||
|
||||
- Le conteneur `linux01` n'a pas le bon DNS (vérifier `/etc/resolv.conf`)
|
||||
- Le DC ne répond pas sur le port 53
|
||||
- `dbus` n'est pas démarré dans le conteneur :
|
||||
```
|
||||
dbus-daemon --system --fork
|
||||
```
|
||||
|
||||
## sssd ne démarre pas
|
||||
|
||||
Symptôme : `Invalid option -f: unknown option` quand `realm join` lance
|
||||
`service sssd restart`.
|
||||
|
||||
Contexte : les images docker sans init complet (pas de systemd). Lance sssd
|
||||
manuellement :
|
||||
|
||||
```
|
||||
/usr/sbin/sssd --daemon
|
||||
```
|
||||
|
||||
## L'utilisateur AD n'est pas résolu côté Linux
|
||||
|
||||
```
|
||||
id pmartin@corp.lab
|
||||
# "no such user"
|
||||
```
|
||||
|
||||
Causes fréquentes :
|
||||
|
||||
- sssd pas démarré (voir ci-dessus)
|
||||
- Cache sssd désynchronisé : `sss_cache -E`
|
||||
- Le domaine n'apparaît pas dans `realm list` : la jonction a échoué
|
||||
silencieusement, relance `realm join -v`
|
||||
|
||||
## Partage inaccessible depuis un client
|
||||
|
||||
- L'utilisateur n'est pas membre du groupe DL : `Get-ADGroupMember DL_Partage_Commun_R`
|
||||
- Le token Kerberos n'a pas été rafraîchi : déconnexion / reconnexion
|
||||
- ACL NTFS restrictive : vérifier via `Get-Acl` ou onglet Sécurité
|
||||
|
||||
## Reset complet du lab
|
||||
|
||||
Pour repartir de zéro sans toucher au reste de ton système :
|
||||
|
||||
```
|
||||
docker compose down -v
|
||||
rm -rf ./storage-dc01 ./storage-pc01
|
||||
docker compose up -d dc01
|
||||
```
|
||||
71
docs/formateur/corriges/01-Setup-AD.ps1
Normal file
71
docs/formateur/corriges/01-Setup-AD.ps1
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
# Corrigé - création de l'arborescence AD (OU, utilisateurs, groupes, AGDLP)
|
||||
# Usage formateur uniquement. A executer sur DC01 apres promotion.
|
||||
# Fait par AcadéNice - https://acadenice.fr/
|
||||
|
||||
$Domain = "corp.lab"
|
||||
$DomainDN = "DC=corp,DC=lab"
|
||||
$DefaultPw = ConvertTo-SecureString "UserP@ss!2026" -AsPlainText -Force
|
||||
|
||||
Import-Module ActiveDirectory
|
||||
|
||||
# Racine
|
||||
New-ADOrganizationalUnit -Name "CORP" -Path $DomainDN -ProtectedFromAccidentalDeletion $false -ErrorAction SilentlyContinue
|
||||
$Root = "OU=CORP,$DomainDN"
|
||||
|
||||
foreach ($sub in @("Utilisateurs","Groupes","Ordinateurs","Services")) {
|
||||
New-ADOrganizationalUnit -Name $sub -Path $Root -ProtectedFromAccidentalDeletion $false -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
$Departements = @("Direction","Pedagogie","Informatique","Administration","Etudiants")
|
||||
foreach ($d in $Departements) {
|
||||
New-ADOrganizationalUnit -Name $d -Path "OU=Utilisateurs,$Root" -ProtectedFromAccidentalDeletion $false -ErrorAction SilentlyContinue
|
||||
New-ADOrganizationalUnit -Name $d -Path "OU=Ordinateurs,$Root" -ProtectedFromAccidentalDeletion $false -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
# Groupes
|
||||
$Groupes = @(
|
||||
@{Name="GG_Direction"; Scope="Global"; Desc="Direction"}
|
||||
@{Name="GG_Pedagogie"; Scope="Global"; Desc="Pédagogie"}
|
||||
@{Name="GG_Informatique"; Scope="Global"; Desc="Informatique"}
|
||||
@{Name="GG_Administration"; Scope="Global"; Desc="Administration"}
|
||||
@{Name="GG_Etudiants"; Scope="Global"; Desc="Étudiants"}
|
||||
@{Name="DL_Partage_Commun_R"; Scope="DomainLocal"; Desc="Lecture partage commun"}
|
||||
@{Name="DL_Partage_Commun_RW"; Scope="DomainLocal"; Desc="Ecriture partage commun"}
|
||||
@{Name="DL_Partage_Pedago_RW"; Scope="DomainLocal"; Desc="Ecriture partage pédago"}
|
||||
@{Name="DL_Partage_Direction"; Scope="DomainLocal"; Desc="Accès partage direction"}
|
||||
)
|
||||
foreach ($g in $Groupes) {
|
||||
New-ADGroup -Name $g.Name -GroupScope $g.Scope -GroupCategory Security `
|
||||
-Path "OU=Groupes,$Root" -Description $g.Desc -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
# Utilisateurs
|
||||
$Users = @(
|
||||
@{First="Marie"; Last="Durand"; Dept="Direction"; Title="Directrice"}
|
||||
@{First="Paul"; Last="Martin"; Dept="Pedagogie"; Title="Responsable pédagogique"}
|
||||
@{First="Julie"; Last="Leroy"; Dept="Pedagogie"; Title="Formatrice"}
|
||||
@{First="Admin"; Last="Sys"; Dept="Informatique"; Title="Admin systèmes"}
|
||||
@{First="Sophie"; Last="Bernard"; Dept="Administration"; Title="Secrétaire"}
|
||||
@{First="Lucas"; Last="Petit"; Dept="Etudiants"; Title="Étudiant"}
|
||||
@{First="Emma"; Last="Moreau"; Dept="Etudiants"; Title="Étudiante"}
|
||||
@{First="Thomas"; Last="Dubois"; Dept="Etudiants"; Title="Étudiant"}
|
||||
)
|
||||
foreach ($u in $Users) {
|
||||
$sam = ($u.First.Substring(0,1) + $u.Last).ToLower()
|
||||
New-ADUser -Name "$($u.First) $($u.Last)" `
|
||||
-GivenName $u.First -Surname $u.Last `
|
||||
-SamAccountName $sam -UserPrincipalName "$sam@$Domain" `
|
||||
-Title $u.Title -Department $u.Dept `
|
||||
-Path "OU=$($u.Dept),OU=Utilisateurs,$Root" `
|
||||
-AccountPassword $DefaultPw -Enabled $true `
|
||||
-ChangePasswordAtLogon $true -ErrorAction SilentlyContinue
|
||||
Add-ADGroupMember -Identity "GG_$($u.Dept)" -Members $sam -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
# Imbrications AGDLP
|
||||
Add-ADGroupMember -Identity "DL_Partage_Commun_R" -Members "GG_Etudiants","GG_Pedagogie","GG_Administration","GG_Direction" -ErrorAction SilentlyContinue
|
||||
Add-ADGroupMember -Identity "DL_Partage_Commun_RW" -Members "GG_Pedagogie","GG_Administration","GG_Direction" -ErrorAction SilentlyContinue
|
||||
Add-ADGroupMember -Identity "DL_Partage_Pedago_RW" -Members "GG_Pedagogie" -ErrorAction SilentlyContinue
|
||||
Add-ADGroupMember -Identity "DL_Partage_Direction" -Members "GG_Direction" -ErrorAction SilentlyContinue
|
||||
|
||||
Write-Host "Peuplement AD termine."
|
||||
43
docs/formateur/corriges/02-Setup-GPO.ps1
Normal file
43
docs/formateur/corriges/02-Setup-GPO.ps1
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
# Corrigé - création des GPO du lab.
|
||||
# Usage formateur uniquement.
|
||||
# Fait par AcadéNice - https://acadenice.fr/
|
||||
|
||||
Import-Module GroupPolicy
|
||||
Import-Module ActiveDirectory
|
||||
|
||||
$DomainDN = (Get-ADDomain).DistinguishedName
|
||||
$Root = "OU=CORP,$DomainDN"
|
||||
$Domain = (Get-ADDomain).DNSRoot
|
||||
|
||||
# Politique de mot de passe (Default Domain Policy)
|
||||
Set-ADDefaultDomainPasswordPolicy -Identity $Domain `
|
||||
-MinPasswordLength 10 `
|
||||
-PasswordHistoryCount 5 `
|
||||
-ComplexityEnabled $true `
|
||||
-MaxPasswordAge (New-TimeSpan -Days 90) `
|
||||
-MinPasswordAge (New-TimeSpan -Days 1) `
|
||||
-LockoutThreshold 5 `
|
||||
-LockoutDuration (New-TimeSpan -Minutes 15) `
|
||||
-LockoutObservationWindow (New-TimeSpan -Minutes 15)
|
||||
|
||||
# Fond d'ecran etudiants
|
||||
$gpo1 = New-GPO -Name "GPO_Etudiants_FondEcran" -Comment "Fond d'écran imposé aux étudiants" -ErrorAction SilentlyContinue
|
||||
Set-GPRegistryValue -Name "GPO_Etudiants_FondEcran" `
|
||||
-Key "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System" `
|
||||
-ValueName "Wallpaper" -Type String -Value "C:\Windows\Web\Wallpaper\Windows\img0.jpg"
|
||||
Set-GPRegistryValue -Name "GPO_Etudiants_FondEcran" `
|
||||
-Key "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System" `
|
||||
-ValueName "WallpaperStyle" -Type String -Value "2"
|
||||
New-GPLink -Name "GPO_Etudiants_FondEcran" -Target "OU=Etudiants,OU=Utilisateurs,$Root" -LinkEnabled Yes -ErrorAction SilentlyContinue
|
||||
|
||||
# Restriction Panneau de configuration
|
||||
$gpo2 = New-GPO -Name "GPO_Etudiants_RestrictionsPC" -ErrorAction SilentlyContinue
|
||||
Set-GPRegistryValue -Name "GPO_Etudiants_RestrictionsPC" `
|
||||
-Key "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" `
|
||||
-ValueName "NoControlPanel" -Type DWord -Value 1
|
||||
Set-GPRegistryValue -Name "GPO_Etudiants_RestrictionsPC" `
|
||||
-Key "HKCU\Software\Policies\Microsoft\Windows\System" `
|
||||
-ValueName "DisableCMD" -Type DWord -Value 2
|
||||
New-GPLink -Name "GPO_Etudiants_RestrictionsPC" -Target "OU=Etudiants,OU=Utilisateurs,$Root" -LinkEnabled Yes -ErrorAction SilentlyContinue
|
||||
|
||||
Write-Host "GPO créées. Relance gpupdate /force sur les clients pour appliquer."
|
||||
40
docs/formateur/corriges/03-Setup-Partages.ps1
Normal file
40
docs/formateur/corriges/03-Setup-Partages.ps1
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
# Corrigé - creation des partages SMB et NTFS.
|
||||
# Usage formateur uniquement.
|
||||
# Fait par AcadéNice - https://acadenice.fr/
|
||||
|
||||
Import-Module SmbShare
|
||||
|
||||
$Base = "C:\Partages"
|
||||
foreach ($p in @("$Base","$Base\Commun","$Base\Pedago","$Base\Direction")) {
|
||||
New-Item -Path $p -ItemType Directory -Force | Out-Null
|
||||
}
|
||||
|
||||
$Nb = (Get-ADDomain).NetBIOSName
|
||||
|
||||
New-SmbShare -Name "Commun" -Path "$Base\Commun" `
|
||||
-FullAccess "$Nb\Domain Admins" `
|
||||
-ReadAccess "$Nb\DL_Partage_Commun_R" `
|
||||
-ChangeAccess "$Nb\DL_Partage_Commun_RW" -ErrorAction SilentlyContinue
|
||||
|
||||
New-SmbShare -Name "Pedago" -Path "$Base\Pedago" `
|
||||
-FullAccess "$Nb\Domain Admins" `
|
||||
-ChangeAccess "$Nb\DL_Partage_Pedago_RW" -ErrorAction SilentlyContinue
|
||||
|
||||
New-SmbShare -Name "Direction" -Path "$Base\Direction" `
|
||||
-FullAccess "$Nb\Domain Admins","$Nb\DL_Partage_Direction" -ErrorAction SilentlyContinue
|
||||
|
||||
function Set-FolderAcl {
|
||||
param($Path, $Group, $Rights)
|
||||
$acl = Get-Acl $Path
|
||||
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
|
||||
"$Nb\$Group", $Rights, "ContainerInherit,ObjectInherit", "None", "Allow")
|
||||
$acl.AddAccessRule($rule)
|
||||
Set-Acl -Path $Path -AclObject $acl
|
||||
}
|
||||
|
||||
Set-FolderAcl "$Base\Commun" "DL_Partage_Commun_R" "ReadAndExecute"
|
||||
Set-FolderAcl "$Base\Commun" "DL_Partage_Commun_RW" "Modify"
|
||||
Set-FolderAcl "$Base\Pedago" "DL_Partage_Pedago_RW" "Modify"
|
||||
Set-FolderAcl "$Base\Direction" "DL_Partage_Direction" "Modify"
|
||||
|
||||
Write-Host "Partages et ACL appliques."
|
||||
22
docs/formateur/corriges/README.md
Normal file
22
docs/formateur/corriges/README.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# Corrigés formateur
|
||||
|
||||
Scripts PowerShell complets pour peupler le lab. Utilise-les pour :
|
||||
|
||||
- vérifier un TP rendu par un apprenant
|
||||
- reconstruire rapidement l'état "fin de TP" sur ta propre instance
|
||||
- démontrer la solution en fin de séance
|
||||
|
||||
Ordre d'exécution :
|
||||
|
||||
1. `01-Setup-AD.ps1` : OU, utilisateurs, groupes, imbrication AGDLP
|
||||
2. `02-Setup-GPO.ps1` : politique de mot de passe, GPO étudiants
|
||||
3. `03-Setup-Partages.ps1` : partages SMB et ACL NTFS
|
||||
|
||||
Les scripts utilisent les valeurs par défaut du lab (`corp.lab`, `CORP`,
|
||||
`UserP@ss!2026`). Si tu as personnalisé `.env`, adapte les variables en début
|
||||
de chaque script.
|
||||
|
||||
Ne pas distribuer aux apprenants : le référentiel attend qu'ils construisent
|
||||
l'annuaire eux-mêmes.
|
||||
|
||||
Fait par [AcadéNice](https://acadenice.fr/).
|
||||
87
docs/formateur/en/course-plan.md
Normal file
87
docs/formateur/en/course-plan.md
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
# Course plan
|
||||
|
||||
Instructor-facing document. Provides a session outline based on the lab,
|
||||
alternating theory, demo, and student practice.
|
||||
|
||||
## Audience and prerequisites
|
||||
|
||||
- Sysadmin-track students, reskilling learners
|
||||
- Networking fundamentals required (TCP/IP, DNS, DHCP)
|
||||
- One workstation per learner, 16 GB RAM minimum, VT-x enabled
|
||||
|
||||
## Duration
|
||||
|
||||
- Intensive: 2 days (14h)
|
||||
- Spread: six 3h half-days
|
||||
|
||||
## Structure
|
||||
|
||||
### Session 1 — Intro and setup (3h)
|
||||
|
||||
Goals:
|
||||
|
||||
- Understand what a directory is, what AD solves
|
||||
- Start the lab, install Windows Server
|
||||
|
||||
Plan:
|
||||
|
||||
1. (45 min) Theory: AD history, vocabulary (forest, domain, DC, OU, GPO)
|
||||
2. (15 min) Lab presentation (diagram, 3 VMs)
|
||||
3. (1h30) Hands-on: lab install, start DC01, first login
|
||||
|
||||
Student material: `docs/etudiant/en/00-prerequisites.md` and `01-lab-startup.md`.
|
||||
|
||||
### Session 2 — Promotion and population (3h)
|
||||
|
||||
1. (45 min) Theory: FSMO roles, integrated DNS, functional levels
|
||||
2. (2h) Hands-on: DC promotion, OUs, users, groups
|
||||
3. (15 min) AGDLP debrief
|
||||
|
||||
Material: `02-dc-promotion.md`, `03-ou-users-groups.md`.
|
||||
|
||||
### Session 3 — GPOs (3h)
|
||||
|
||||
1. (1h) Theory: GPOs, inheritance, filtering, LSDOU order
|
||||
2. (1h45) Hands-on: create three GPOs, verify on a client
|
||||
3. (15 min) Best practices: don't overload Default Domain Policy
|
||||
|
||||
Material: `04-gpo.md`.
|
||||
|
||||
### Session 4 — Shared resources (3h)
|
||||
|
||||
1. (45 min) Theory: SMB, NTFS, share vs NTFS permissions
|
||||
2. (2h) Hands-on: create shares, ACLs, cross-user tests
|
||||
3. (15 min) AGDLP in practice
|
||||
|
||||
Material: `05-shares-ntfs.md`.
|
||||
|
||||
### Session 5 — Joining Windows clients (3h)
|
||||
|
||||
1. (45 min) Theory: Kerberos, secure channel, DNS constraints
|
||||
2. (2h) Hands-on: join PC01, log in as AD user, test shares
|
||||
3. (15 min) RDP group via GPO
|
||||
|
||||
Material: `06-join-windows-client.md`.
|
||||
|
||||
### Session 6 — Cross-OS integration (3h)
|
||||
|
||||
1. (30 min) Theory: realmd, sssd, Kerberos beyond Windows
|
||||
2. (2h) Hands-on: join linux01, authentication tests
|
||||
3. (30 min) Outlook: enterprise use cases (Linux servers joined to AD,
|
||||
AD-backed ssh/sudo)
|
||||
|
||||
Material: `07-join-linux-client.md`.
|
||||
|
||||
## Assessment
|
||||
|
||||
Three possible formats:
|
||||
|
||||
1. Multiple-choice: vocabulary and concepts (30 min, 20 questions)
|
||||
2. Graded lab: give an OU/group structure to set up, shares with specific
|
||||
ACLs, grade via login tests
|
||||
3. Mini-project: add a scenario (new department, new GPO) to the existing lab
|
||||
|
||||
## Solutions
|
||||
|
||||
Full PowerShell scripts live in `docs/formateur/corriges/`. **Do not
|
||||
distribute** to learners.
|
||||
101
docs/formateur/fr/deroule-cours.md
Normal file
101
docs/formateur/fr/deroule-cours.md
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
# Déroulé de cours
|
||||
|
||||
Document à usage formateur. Propose une trame de session qui s'appuie sur le
|
||||
lab, en alternant théorie, démonstration, et pratique apprenant.
|
||||
|
||||
## Public et pré-requis
|
||||
|
||||
- Apprenants de type BTS SIO, titres pro administrateur systèmes, ou
|
||||
reconversion
|
||||
- Socle réseau indispensable (TCP/IP, DNS, DHCP)
|
||||
- Une machine par apprenant avec au moins 16 Go de RAM et VT-x activé
|
||||
|
||||
## Durée indicative
|
||||
|
||||
- Format intensif : 2 jours (14h)
|
||||
- Format étalé : 6 demi-journées de 3h
|
||||
|
||||
## Structure pédagogique
|
||||
|
||||
### Séance 1 — Introduction et mise en place (3h)
|
||||
|
||||
Objectifs :
|
||||
|
||||
- Comprendre ce qu'est un annuaire et ce que résout AD
|
||||
- Démarrer le lab, installer Windows Server
|
||||
|
||||
Plan :
|
||||
|
||||
1. (45 min) Théorie : historique AD, vocabulaire (forêt, domaine, DC, OU, GPO)
|
||||
2. (15 min) Présentation du lab (schéma, explication des 3 VMs)
|
||||
3. (1h30) TP : installation du lab, démarrage de DC01, premier login
|
||||
|
||||
Support apprenant : `docs/etudiant/fr/00-prerequis.md` et `01-installation-lab.md`.
|
||||
|
||||
### Séance 2 — Promotion et peuplement (3h)
|
||||
|
||||
1. (45 min) Théorie : rôles FSMO, DNS intégré, niveaux fonctionnels
|
||||
2. (2h) TP : promotion du DC, création d'OU, d'utilisateurs, de groupes
|
||||
3. (15 min) Debrief AGDLP
|
||||
|
||||
Support : `02-promotion-dc.md`, `03-ou-utilisateurs-groupes.md`.
|
||||
|
||||
### Séance 3 — GPO et stratégies (3h)
|
||||
|
||||
1. (1h) Théorie : GPO, héritage, filtrage, ordre LSDOU
|
||||
2. (1h45) TP : création des 3 GPO proposées, vérification sur un poste
|
||||
3. (15 min) Bonnes pratiques : ne pas surcharger la Default Domain Policy
|
||||
|
||||
Support : `04-gpo.md`.
|
||||
|
||||
### Séance 4 — Ressources partagées (3h)
|
||||
|
||||
1. (45 min) Théorie : SMB, NTFS, différence entre autorisations partage et NTFS
|
||||
2. (2h) TP : création des partages, ACL, tests croisés par type d'utilisateur
|
||||
3. (15 min) Debrief sur l'intérêt de AGDLP dans la pratique
|
||||
|
||||
Support : `05-partages-ntfs.md`.
|
||||
|
||||
### Séance 5 — Jonction de postes (3h)
|
||||
|
||||
1. (45 min) Théorie : Kerberos, secure channel, contraintes DNS
|
||||
2. (2h) TP : jonction de PC01, connexion d'un utilisateur AD, tests partages
|
||||
3. (15 min) Ajout du groupe RDP (GPO conseillée)
|
||||
|
||||
Support : `06-jonction-poste-windows.md`.
|
||||
|
||||
### Séance 6 — Intégration multi-OS (3h)
|
||||
|
||||
1. (30 min) Théorie : realmd, sssd, Kerberos hors Windows
|
||||
2. (2h) TP : jonction de linux01, tests d'authentification
|
||||
3. (30 min) Ouverture : cas d'usage en entreprise (serveurs Linux joints au domaine, ssh AD, sudo AD)
|
||||
|
||||
Support : `07-jonction-poste-linux.md`.
|
||||
|
||||
## Évaluation suggérée
|
||||
|
||||
Trois modalités possibles :
|
||||
|
||||
1. QCM sur vocabulaire et concepts (30 min, 20 questions)
|
||||
2. TP évalué : donner une structure OU/groupes à mettre en place, des
|
||||
partages à créer avec ACL ciblées, évaluer par tests de connexion
|
||||
3. Mini-projet : ajouter un scénario (nouveau département, nouvelle GPO) au
|
||||
lab existant
|
||||
|
||||
## Matériel
|
||||
|
||||
Chaque apprenant doit pouvoir :
|
||||
|
||||
- cloner le dépôt
|
||||
- exécuter `docker compose up -d dc01`
|
||||
- accéder en RDP à ses VMs
|
||||
|
||||
Un second DC pour la démonstration de réplication est hors scope du lab de
|
||||
base (le lab utilise du NAT Docker qui ne permet pas la réplication directe).
|
||||
Tu peux le compléter à part en macvlan ou libvirt.
|
||||
|
||||
## Corrigés
|
||||
|
||||
Les scripts PowerShell complets se trouvent dans
|
||||
`docs/formateur/corriges/`. **Ne pas distribuer aux apprenants**, ils doivent
|
||||
construire eux-mêmes.
|
||||
24
linux-client/Dockerfile
Normal file
24
linux-client/Dockerfile
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# Image cliente Linux pré-équipée pour rejoindre un domaine AD
|
||||
# (realmd + SSSD + Kerberos). La jonction reste manuelle, côté apprenant.
|
||||
# Fait par AcadéNice - https://acadenice.fr/
|
||||
|
||||
FROM debian:12-slim
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get update -qq \
|
||||
&& apt-get install -y -qq --no-install-recommends \
|
||||
realmd sssd sssd-tools libnss-sss libpam-sss \
|
||||
adcli samba-common-bin oddjob oddjob-mkhomedir packagekit \
|
||||
krb5-user dnsutils iputils-ping netcat-openbsd \
|
||||
dbus openssh-server sudo vim less ca-certificates \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Evite le prompt interactif de krb5-config pendant les installs ulterieures.
|
||||
RUN echo "krb5-config krb5-config/default_realm string CORP.LAB" | debconf-set-selections
|
||||
|
||||
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||
RUN chmod +x /usr/local/bin/entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||
43
linux-client/entrypoint.sh
Executable file
43
linux-client/entrypoint.sh
Executable file
|
|
@ -0,0 +1,43 @@
|
|||
#!/usr/bin/env bash
|
||||
# Prépare linux01 sans rejoindre le domaine (geste laissé à l'apprenant).
|
||||
# Fait par AcadéNice - https://acadenice.fr/
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
AD_DOMAIN="${AD_DOMAIN:-corp.lab}"
|
||||
DC_HOST="${DC_CONTAINER_IP:-lab-dc01}"
|
||||
|
||||
DC_IP="$(getent hosts "$DC_HOST" | awk '{print $1}' || true)"
|
||||
|
||||
if [ -n "$DC_IP" ]; then
|
||||
cat > /etc/resolv.conf <<EOF
|
||||
nameserver $DC_IP
|
||||
search $AD_DOMAIN
|
||||
EOF
|
||||
# Override nécessaire : dockurr/windows NAT la VM, l'IP annoncée par DNS
|
||||
# (ex 172.30.0.2) n'est pas routable depuis ce conteneur. On redirige donc
|
||||
# les noms clés vers l'IP du conteneur DC, que dockurr DNAT vers la VM.
|
||||
if ! grep -q "$AD_DOMAIN" /etc/hosts; then
|
||||
echo "$DC_IP $AD_DOMAIN dc01.$AD_DOMAIN dc01" >> /etc/hosts
|
||||
fi
|
||||
fi
|
||||
|
||||
mkdir -p /run/dbus
|
||||
[ -S /run/dbus/system_bus_socket ] || dbus-daemon --system --fork
|
||||
|
||||
if [ -x /usr/sbin/sshd ]; then
|
||||
ssh-keygen -A >/dev/null 2>&1 || true
|
||||
grep -q pam_mkhomedir /etc/pam.d/common-session || \
|
||||
echo "session optional pam_mkhomedir.so skel=/etc/skel umask=077" >> /etc/pam.d/common-session
|
||||
/usr/sbin/sshd -D &
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
linux01 prêt. Prochaine étape (côté apprenant) :
|
||||
|
||||
docker exec -it lab-linux01 bash
|
||||
realm discover $AD_DOMAIN
|
||||
|
||||
EOF
|
||||
|
||||
exec sleep infinity
|
||||
44
scripts/check-prereqs.ps1
Normal file
44
scripts/check-prereqs.ps1
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# Vérifie les prérequis locaux avant de lancer le lab (Windows).
|
||||
# Fait par AcadéNice - https://acadenice.fr/
|
||||
|
||||
$ErrorActionPreference = "Continue"
|
||||
$fail = 0
|
||||
|
||||
function OK ($m) { Write-Host "[ OK ] $m" }
|
||||
function KO ($m) { Write-Host "[FAIL] $m"; $script:fail = 1 }
|
||||
function WARN ($m) { Write-Host "[WARN] $m" }
|
||||
|
||||
Write-Host "Vérification des prérequis"
|
||||
Write-Host ""
|
||||
|
||||
try { $v = docker --version; OK "docker : $v" } catch { KO "docker absent" }
|
||||
try { docker compose version | Out-Null; OK "docker compose v2 présent" } catch { KO "docker compose v2 absent" }
|
||||
try { docker info | Out-Null; OK "daemon docker joignable" } catch { KO "daemon docker inaccessible" }
|
||||
|
||||
try { wsl --version | Out-Null; OK "WSL2 présent" } catch { WARN "WSL2 non détecté" }
|
||||
|
||||
$wslConfig = "$env:USERPROFILE\.wslconfig"
|
||||
if (Test-Path $wslConfig) {
|
||||
if ((Get-Content $wslConfig -Raw) -match "nestedVirtualization\s*=\s*true") {
|
||||
OK ".wslconfig : virtualisation imbriquée activée"
|
||||
} else {
|
||||
WARN ".wslconfig : ajouter 'nestedVirtualization=true' sous [wsl2]"
|
||||
}
|
||||
} else {
|
||||
WARN "$wslConfig absent - créez-le avec [wsl2] / nestedVirtualization=true"
|
||||
}
|
||||
|
||||
$ram = [math]::Round((Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory / 1GB)
|
||||
if ($ram -ge 16) { OK "RAM $ram Go" }
|
||||
elseif ($ram -ge 12) { WARN "RAM $ram Go (minimum)" }
|
||||
else { KO "RAM $ram Go insuffisante" }
|
||||
|
||||
$freeGB = [math]::Round((Get-Item $PSScriptRoot).PSDrive.Free / 1GB)
|
||||
if ($freeGB -ge 150) { OK "Disque libre $freeGB Go" }
|
||||
elseif ($freeGB -ge 80) { WARN "Disque libre $freeGB Go (juste le minimum)" }
|
||||
else { KO "Disque libre $freeGB Go insuffisant" }
|
||||
|
||||
Write-Host ""
|
||||
if ($fail -eq 0) { Write-Host "Prérequis critiques : OK." ; exit 0 }
|
||||
Write-Host "Prérequis manquants. Voir docs\etudiant\fr\00-prerequis.md"
|
||||
exit 1
|
||||
78
scripts/check-prereqs.sh
Executable file
78
scripts/check-prereqs.sh
Executable file
|
|
@ -0,0 +1,78 @@
|
|||
#!/usr/bin/env bash
|
||||
# Vérifie les prérequis locaux avant de lancer le lab.
|
||||
# Fait par AcadéNice - https://acadenice.fr/
|
||||
|
||||
set -u
|
||||
|
||||
ok() { echo "[ OK ] $*"; }
|
||||
ko() { echo "[FAIL] $*"; fail=1; }
|
||||
warn() { echo "[WARN] $*"; }
|
||||
|
||||
fail=0
|
||||
OS="$(uname -s)"
|
||||
|
||||
echo "Vérification des prérequis (OS détecté : $OS)"
|
||||
echo
|
||||
|
||||
command -v docker >/dev/null 2>&1 \
|
||||
&& ok "docker : $(docker --version 2>/dev/null | awk '{print $3}' | tr -d ',')" \
|
||||
|| ko "docker absent"
|
||||
|
||||
docker compose version >/dev/null 2>&1 \
|
||||
&& ok "docker compose v2 : $(docker compose version --short 2>/dev/null)" \
|
||||
|| ko "docker compose v2 absent (plugin docker-compose-plugin requis)"
|
||||
|
||||
docker info >/dev/null 2>&1 \
|
||||
&& ok "daemon docker joignable" \
|
||||
|| ko "daemon docker inaccessible (user dans le groupe docker ?)"
|
||||
|
||||
case "$OS" in
|
||||
Linux)
|
||||
if [ -e /dev/kvm ] && [ -r /dev/kvm ] && [ -w /dev/kvm ]; then
|
||||
ok "/dev/kvm accessible"
|
||||
elif [ -e /dev/kvm ]; then
|
||||
ko "/dev/kvm existe mais pas lisible (groupe kvm ?)"
|
||||
else
|
||||
ko "/dev/kvm absent (VT-x / AMD-V désactivé dans le BIOS ?)"
|
||||
fi
|
||||
lsmod 2>/dev/null | grep -q "^kvm " && ok "module kvm chargé" || warn "module kvm non chargé"
|
||||
;;
|
||||
Darwin)
|
||||
if [ "$(uname -m)" = "arm64" ]; then
|
||||
ko "Mac Apple Silicon : dockurr/windows non supporté (voir docs/etudiant/fr/00-prerequis.md)"
|
||||
else
|
||||
warn "Mac Intel : Docker Desktop avec virtualisation imbriquée requis"
|
||||
fi
|
||||
;;
|
||||
MINGW*|CYGWIN*|MSYS*)
|
||||
warn "Sous Windows, utilisez plutôt check-prereqs.ps1"
|
||||
;;
|
||||
esac
|
||||
|
||||
if command -v free >/dev/null 2>&1; then
|
||||
MEM_GB=$(free -g | awk '/^Mem:/ {print $2}')
|
||||
if [ "$MEM_GB" -ge 16 ]; then ok "RAM ${MEM_GB} Go"
|
||||
elif [ "$MEM_GB" -ge 12 ]; then warn "RAM ${MEM_GB} Go (minimum — fermez les autres applis)"
|
||||
else ko "RAM ${MEM_GB} Go insuffisante"
|
||||
fi
|
||||
fi
|
||||
|
||||
FREE_GB=$(df -BG "$PWD" 2>/dev/null | awk 'NR==2 {gsub("G",""); print $4}')
|
||||
if [ -n "${FREE_GB:-}" ]; then
|
||||
if [ "$FREE_GB" -ge 150 ]; then ok "Disque libre ${FREE_GB} Go"
|
||||
elif [ "$FREE_GB" -ge 80 ]; then warn "Disque libre ${FREE_GB} Go (juste le minimum)"
|
||||
else ko "Disque libre ${FREE_GB} Go insuffisant"
|
||||
fi
|
||||
fi
|
||||
|
||||
command -v xfreerdp3 >/dev/null 2>&1 || command -v xfreerdp >/dev/null 2>&1 \
|
||||
&& ok "xfreerdp disponible" \
|
||||
|| warn "xfreerdp absent (recommandé pour RDP fluide)"
|
||||
|
||||
echo
|
||||
if [ $fail -eq 0 ]; then
|
||||
echo "Prérequis critiques : OK."
|
||||
exit 0
|
||||
fi
|
||||
echo "Prérequis manquants. Voir docs/etudiant/fr/00-prerequis.md"
|
||||
exit 1
|
||||
24
scripts/rdp-client.sh
Executable file
24
scripts/rdp-client.sh
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
#!/usr/bin/env bash
|
||||
# Ouvre une session RDP sur le poste client Windows (PC01).
|
||||
# Fait par AcadéNice - https://acadenice.fr/
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
PROJECT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
[ -f "$PROJECT_DIR/.env" ] && set -a && . "$PROJECT_DIR/.env" && set +a
|
||||
|
||||
HOST="127.0.0.1"
|
||||
PORT="${CLIENT_RDP_PORT:-3391}"
|
||||
USER="${RDP_CLIENT_USER:-LocalAdmin}"
|
||||
PASSWORD="${RDP_CLIENT_PASSWORD:-${AD_ADMIN_PASSWORD:-AdminP@ss!2026}}"
|
||||
SIZE="${RDP_SIZE:-1600x900}"
|
||||
|
||||
if command -v xfreerdp3 >/dev/null; then RDP=xfreerdp3
|
||||
elif command -v xfreerdp >/dev/null; then RDP=xfreerdp
|
||||
else echo "xfreerdp non installé" >&2; exit 1
|
||||
fi
|
||||
|
||||
exec "$RDP" \
|
||||
/v:"$HOST:$PORT" /u:"$USER" /p:"$PASSWORD" \
|
||||
/cert:ignore +clipboard \
|
||||
/size:"$SIZE" /dynamic-resolution
|
||||
43
scripts/rdp-dc.ps1
Normal file
43
scripts/rdp-dc.ps1
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
# Ouvre une session RDP sur le contrôleur de domaine (DC01).
|
||||
# Fait par AcadéNice - https://acadenice.fr/
|
||||
|
||||
param(
|
||||
[string]$RdpHost = "127.0.0.1",
|
||||
[int]$Port = 3389,
|
||||
[string]$User = "Administrator",
|
||||
[string]$Domain = "CORP",
|
||||
[string]$Password = "AdminP@ss!2026"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$envFile = Join-Path $PSScriptRoot "..\.env"
|
||||
if (Test-Path $envFile) {
|
||||
Get-Content $envFile | Where-Object { $_ -match '^([A-Z_]+)=(.*)$' } | ForEach-Object {
|
||||
$k = $Matches[1]; $v = $Matches[2].Trim('"').Trim("'")
|
||||
switch ($k) {
|
||||
"DC_RDP_PORT" { $Port = [int]$v }
|
||||
"AD_DOMAIN_NETBIOS" { $Domain = $v }
|
||||
"AD_ADMIN_PASSWORD" { $Password = $v }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmdkey /generic:"TERMSRV/$RdpHost" /user:"$Domain\$User" /pass:"$Password" | Out-Null
|
||||
|
||||
$sharedPath = (Resolve-Path "$PSScriptRoot\..\shared").Path
|
||||
$rdpFile = Join-Path $env:TEMP "lab_ad_dc.rdp"
|
||||
|
||||
@"
|
||||
full address:s:${RdpHost}:${Port}
|
||||
username:s:${Domain}\${User}
|
||||
redirectclipboard:i:1
|
||||
redirectdrives:i:1
|
||||
drivestoredirect:s:${sharedPath}
|
||||
desktopwidth:i:1600
|
||||
desktopheight:i:900
|
||||
smart sizing:i:1
|
||||
authentication level:i:0
|
||||
"@ | Out-File -FilePath $rdpFile -Encoding ASCII -Force
|
||||
|
||||
Start-Process mstsc -ArgumentList "`"$rdpFile`""
|
||||
31
scripts/rdp-dc.sh
Executable file
31
scripts/rdp-dc.sh
Executable file
|
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/env bash
|
||||
# Ouvre une session RDP sur le contrôleur de domaine (DC01).
|
||||
# Fait par AcadéNice - https://acadenice.fr/
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
PROJECT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
[ -f "$PROJECT_DIR/.env" ] && set -a && . "$PROJECT_DIR/.env" && set +a
|
||||
|
||||
HOST="127.0.0.1"
|
||||
PORT="${DC_RDP_PORT:-3389}"
|
||||
USER="Administrator"
|
||||
DOMAIN="${AD_DOMAIN_NETBIOS:-CORP}"
|
||||
PASSWORD="${AD_ADMIN_PASSWORD:-AdminP@ss!2026}"
|
||||
SHARE_DIR="$PROJECT_DIR/shared"
|
||||
SIZE="${RDP_SIZE:-1600x900}"
|
||||
|
||||
mkdir -p "$SHARE_DIR"
|
||||
|
||||
if command -v xfreerdp3 >/dev/null; then RDP=xfreerdp3
|
||||
elif command -v xfreerdp >/dev/null; then RDP=xfreerdp
|
||||
else
|
||||
echo "xfreerdp non installé (apt install freerdp3-x11 / pacman -S freerdp / brew install freerdp)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exec "$RDP" \
|
||||
/v:"$HOST:$PORT" /u:"$USER" /d:"$DOMAIN" /p:"$PASSWORD" \
|
||||
/cert:ignore +clipboard \
|
||||
/size:"$SIZE" /dynamic-resolution \
|
||||
/drive:shared,"$SHARE_DIR"
|
||||
0
shared/.gitkeep
Normal file
0
shared/.gitkeep
Normal file
Loading…
Add table
Reference in a new issue