#30 — kea-dhcp
PLANIFIÉ
Priorité: 🔴 CRITIQUE · Type: TYPE F · Conteneur: rgz-kea · Code: config/kea/kea-dhcp4.conf
Dépendances: #7 rgz-gateway
Description
Kea DHCP est le serveur DHCP de la plateforme ACCESS, basé sur ISC Kea (successeur de ISC DHCP). Il attribue les adresses IP aux CPE et aux appareils abonnés dans chaque sous-réseau VLAN. Sans Kea, aucun abonné ne peut obtenir d'adresse IP et accéder au réseau — c'est pourquoi cet outil est classifié CRITIQUE.
Kea est choisi pour sa gestion native des bases de données PostgreSQL (stockage des baux dans rgz-db), son support de l'Option 82 (relay agent information — essentielle pour transmettre le NAS-ID au serveur RADIUS), et sa configuration dynamique via API REST sans redémarrage du service. Par opposition à l'ISC DHCP classique, Kea supporte le rechargement à chaud de la configuration, ce qui est indispensable lors de l'onboarding de nouveaux revendeurs (#56) qui crée de nouveaux pools VLAN.
Le plan d'adressage est strict : chaque VLAN reçoit un sous-réseau /24 dans 10.[vlan_id].0.0/24. La passerelle est toujours .1, les AP sont .2, .3… selon le nombre de sites, et le pool DHCP démarre à .10 pour laisser de la marge aux équipements statiques. La durée de bail est fixée à 3600 secondes (1 heure) — un compromis entre performance (peu de renouvellements) et récupération rapide des IP en cas de déconnexion.
Architecture Interne
Paquet DHCP Discover (broadcast depuis abonné)
│
▼
CPE LiteBeam (relay agent DHCP)
│ → Ajoute Option 82 : NAS-Identifier = nas_id du revendeur
│
▼
rgz-kea :: port 67/udp
│
├── Lecture Option 82 → identification VLAN → sélection subnet correspondant
│
├── Vérification baux existants en PostgreSQL (rgz-db)
│ Table : kea_leases4 (ip_address, hwaddr, valid_lft, subnet_id)
│
├── Attribution IP : 10.[vlan_id].0.10 → 10.[vlan_id].0.254 (premier disponible)
│
├── Enregistrement bail en DB (durée 3600s)
│
└── DHCP Offer → DHCP Ack
Options envoyées :
Option 1 : Masque = 255.255.255.0
Option 3 : Gateway = 10.[vlan_id].0.1
Option 6 : DNS = 10.[vlan_id].0.1 → vers rgz-dns (sinkhole avant auth)
Option 51 : Lease time = 3600s
Option 82 : Relay info (retransmise au client)Configuration
Variables d'environnement
| Variable | Valeur exemple | Description |
|---|---|---|
KEA_DB_HOST | rgz-db | Hostname PostgreSQL pour baux DHCP |
KEA_DB_PORT | 5432 | Port PostgreSQL |
KEA_DB_NAME | kea | Base de données Kea (séparée de rgzdb) |
KEA_DB_USER | kea | Utilisateur PostgreSQL Kea (rôle limité) |
KEA_DB_PASS | (depuis .env) | Mot de passe PostgreSQL Kea |
KEA_CTRL_PORT | 8001 | Port API REST Kea Control Agent |
DHCP_LEASE_TIME | 3600 | Durée bail DHCP (secondes) |
VLAN_BASE | 100 | Premier VLAN (100+n) |
SUBNET_BASE_OCTET | 10 | Premier octet subnets abonnés |
kea-dhcp4.conf (extrait représentatif)
{
"Dhcp4": {
"interfaces-config": {
"interfaces": ["eth0"]
},
"lease-database": {
"type": "postgresql",
"host": "rgz-db",
"name": "kea",
"user": "kea",
"password": "$(KEA_DB_PASS)"
},
"valid-lifetime": 3600,
"renew-timer": 1800,
"rebind-timer": 2700,
"option-def": [
{
"name": "agent-circuit-id",
"code": 82,
"space": "dhcp4",
"type": "binary"
}
],
"subnet4": [
{
"id": 100,
"subnet": "10.100.0.0/24",
"pools": [{"pool": "10.100.0.10 - 10.100.0.254"}],
"option-data": [
{"name": "routers", "data": "10.100.0.1"},
{"name": "domain-name-servers", "data": "10.100.0.1"}
],
"relay": {"ip-addresses": ["10.100.0.1"]},
"user-context": {"nas-id": "access_revendeur1", "vlan-id": 100}
}
],
"control-socket": {
"socket-type": "unix",
"socket-name": "/tmp/kea4-ctrl-socket"
},
"loggers": [{"name": "kea-dhcp4", "severity": "INFO"}]
}
}Ajout dynamique d'un subnet (onboarding revendeur)
Kea permet le rechargement à chaud via API REST (kea-ctrl-agent) sans redémarrer le conteneur :
# Ajouter un nouveau subnet pour VLAN 142 (revendeur Kossou, onboarding)
curl -X POST http://rgz-kea:8001/ \
-H "Content-Type: application/json" \
-d '{
"command": "subnet4-add",
"service": ["dhcp4"],
"arguments": {
"subnet4": [{
"id": 142,
"subnet": "10.142.0.0/24",
"pools": [{"pool": "10.142.0.10 - 10.142.0.254"}],
"option-data": [
{"name": "routers", "data": "10.142.0.1"},
{"name": "domain-name-servers", "data": "10.142.0.1"}
]
}]
}
}'Commandes Utiles
# Vérifier l'état du service Kea
docker exec rgz-kea kea-ctrl-agent --version
docker ps | grep kea
# Lister les baux DHCP actifs
docker exec rgz-db psql -U kea -d kea -c \
"SELECT address, hwaddr, valid_lft, subnet_id FROM lease4 WHERE valid_lft > 0 LIMIT 20;"
# Lister les subnets configurés (via API Kea)
curl -s http://localhost:8001/ -d '{"command": "subnet4-list", "service": ["dhcp4"]}' \
| python3 -m json.tool
# Statistiques DHCP par subnet (Kea API)
curl -s http://localhost:8001/ -d '{"command": "statistic-get-all", "service": ["dhcp4"]}' \
| python3 -m json.tool | grep "assigned"
# Forcer rechargement configuration Kea (sans restart)
docker exec rgz-kea kea-ctrl-agent -c /etc/kea/kea-ctrl-agent.conf &
curl -s http://localhost:8001/ -d '{"command": "config-reload", "service": ["dhcp4"]}'
# Logs Kea
docker logs rgz-kea --tail=50
# Vérifier le healthcheck Kea
docker inspect rgz-kea | python3 -c "import sys,json; d=json.load(sys.stdin); \
print(d[0]['State']['Health']['Status'])"
# Compter les baux actifs par VLAN (subnet_id = vlan_id)
docker exec rgz-db psql -U kea -d kea -c \
"SELECT subnet_id, count(*) FROM lease4 WHERE valid_lft > 0 GROUP BY subnet_id ORDER BY subnet_id;"Sécurité
| Règle | Application |
|---|---|
| SEC-08 | rgz-db : rôle PostgreSQL kea avec accès limité à la base kea uniquement (pas de rgzdb) |
| LL#33 | restart: unless-stopped dans docker-compose.core.yml pour rgz-kea |
| LL#27 | Logs Docker rgz-kea : max-size: 10m, max-file: 3 |
| SEC-07 | Kea Control Agent accessible uniquement sur le réseau Docker interne rgz-net (jamais exposé publiquement) |
Healthcheck Docker
# docker-compose.core.yml
healthcheck:
test: ["CMD", "curl", "-sf", "http://127.0.0.1:8001/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 20sImplémentation TODO
- [ ] Ajouter service
rgz-keadansdocker-compose.core.yml(imagedocker.io/isc/kea-dhcp4) - [ ] Créer
config/kea/kea-dhcp4.confavec subnet template générique (VLAN 100-499) - [ ] Créer
config/kea/kea-ctrl-agent.conf(API REST port 8001) - [ ] Créer base de données
keadansrgz-dbavec rôlekea(rôle limité — SEC-08) - [ ] Configurer relay agent DHCP Option 82 sur les CPE LiteBeam pour transmettre le NAS-ID
- [ ] Tester ajout dynamique de subnet via API Kea (pour intégration onboarding #56)
- [ ] Vérifier que
domain-name-serverspointe versrgz-dns(sinkhole avant auth RADIUS) - [ ] Configurer
kea-dhcp4avec stockage PostgreSQL (pas fichier CSV) - [ ] Valider que le bail time 3600s convient aux sessions WiFi horaires/journalières
- [ ] Documenter la procédure de suppression de subnet en cas d'offboarding revendeur
Dernière mise à à jour: 2026-02-21