Funk-lab/admin/infra/wireguard.md
ALI YESILKAYA bc0e1dd53e
feat(wireguard): accès distant au lab via VPN (Freebox 51820/udp → s01) (#80)
- rôle wireguard : serveur wg0 (10.99.0.0/24) sur storage-01, profils
  clients générés dans /etc/wireguard/clients/ (fichier .conf / QR code)
- gateway : filtrage nftables par pair — full (tout le lab) / portal
  (uniquement Traefik :80 = portail Guacamole), masquerade VPN→cluster
- dnsmasq : bind-dynamic + écoute wg0 → *.lab.local résolu dans le tunnel
- pairs initiaux : alkatrazz (full), invite-01 (portal)
- vault : clés WireGuard + reprise de l'archive Authentik (remplace #78)
- doc : admin/infra/wireguard.md (onboarding pair, pièges, exploitation)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 11:11:43 +02:00

82 lines
3.7 KiB
Markdown

# WireGuard — accès distant au lab
VPN **WireGuard** sur storage-01 (rôle Ansible `wireguard`) : permet d'accéder au
portail Guacamole (et au lab entier pour les admins) **depuis Internet**, sans exposer
la moindre page web en clair. Un seul port ouvert : **`51820/udp`**.
```
Client (WireGuard app) ──kaya.freeboxos.fr:51820/udp──▶ Freebox ──▶ s01 (wg0 10.99.0.1)
│ nftables filtre par pair
portail.lab.local (invités)
ou tout le LAN cluster (admins)
```
## Réseau
- Tunnel : `10.99.0.0/24` (s01 = `10.99.0.1`)
- **Split tunnel** : seuls `192.168.10.0/24` + `10.99.0.0/24` passent dans le VPN —
le reste du trafic du client sort par sa connexion normale
- DNS du tunnel : dnsmasq s01 (`10.99.0.1`) → `*.lab.local` résolu comme à la maison
- **Redirection Freebox requise** : `51820/udp``funk-s01` (ports début/fin identiques)
## Classes d'accès (filtrage nftables, rôle `gateway`)
| `access` | Droits | Usage |
|---|---|---|
| `full` | Tout le LAN cluster + SSH s01 | Admin (toi) |
| `portal` | **Uniquement** `portail.lab.local` (Traefik :80) + DNS | Invités |
Pairs actuels : `alkatrazz` (full, `10.99.0.10`), `invite-01` (portal, `10.99.0.50`).
## Distribuer un profil client
Les profils sont générés dans **`/etc/wireguard/clients/<name>.conf`** sur s01 :
```bash
# fichier à envoyer (contient la clé privée du client — canal privé !)
scp root@192.168.1.200:/etc/wireguard/clients/invite-01.conf .
# ou QR code à scanner avec l'app mobile WireGuard
ssh root@192.168.1.200 "dnf install -y qrencode && qrencode -t ansiutf8 < /etc/wireguard/clients/invite-01.conf"
```
Côté client : app WireGuard (Windows/macOS/Android/iOS) → importer le `.conf` ou
scanner le QR → activer → ouvrir `http://portail.lab.local`.
## Ajouter un pair
1. Générer une paire de clés (poste admin, `wg` non requis) :
```bash
openssl genpkey -algorithm X25519 -out /tmp/peer.pem
openssl pkey -in /tmp/peer.pem -outform DER | tail -c 32 | base64 # clé PRIVÉE
openssl pkey -in /tmp/peer.pem -pubout -outform DER | tail -c 32 | base64 # clé publique
rm /tmp/peer.pem
```
2. Clé privée → vault (`make vault-edit`) dans `vault_wireguard_peer_private_keys`
3. Entrée dans `wireguard_peers` (`ansible/host_vars/storage-01/vars.yml`) : name, ip
libre dans `10.99.0.0/24`, public_key, access
4. `ansible-playbook -i inventory.yml playbooks/storage-01.yml --tags wireguard,gateway`
5. Distribuer `/etc/wireguard/clients/<name>.conf`
**Retirer un pair** : supprimer des deux endroits (host_vars + vault) → re-apply idem.
## Exploitation / debug
```bash
ssh root@192.168.1.200 wg show # handshakes, transfert par pair
systemctl status wg-quick@wg0 # état du service
journalctl -u wg-quick@wg0 -n 20
```
## Pièges
1. **Pas de handshake** (`wg show` vide côté serveur) : vérifier la redirection Freebox
`51820/udp → funk-s01` et que le client utilise bien `kaya.freeboxos.fr:51820`.
2. **Connecté mais `portail.lab.local` ne résout pas** : le DNS du tunnel doit être
`10.99.0.1` (champ DNS du profil). dnsmasq doit être en `bind-dynamic` avec
`interface=wg0` (fait par le rôle `dnsmasq`) — sinon il ignore wg0.
3. **Invité qui « voit » d'autres services** : impossible par design — le filtrage est
dans nftables (forward), pas dans Guacamole. Vérifier `access: portal` dans host_vars.
4. Les clés privées clients sont dans le **vault** ET dans `/etc/wireguard/clients/`
sur s01 — ne jamais les committer en clair, ni les envoyer par un canal public.