NetAdmin — Console DNS & Mail
Interface d'administration centralisée pour la gestion des zones DNS (BIND9) et des comptes mail (PostfixAdmin/MariaDB), avec authentification locale et SSO (Keycloak/OIDC), double authentification TOTP, audit complet et file d'attente des synchronisations vers les agents distants.
Architecture
┌─────────────────────────────────────────────┐
│ Frontend (React/Vite) :3000 │
│ LoginPage · DNSManager · MailManager │
│ UsersManager · AuditLog · SyncDashboard │
└───────────────┬─────────────────────────────┘
│ HTTP/JSON
┌───────────────▼─────────────────────────────┐
│ Backend FastAPI :8000 │
│ routers/auth · dns · mail │
│ audit · broker · notify │
└──────┬──────────────────────┬───────────────┘
│ PyMySQL │ Redis (mTLS)
┌──────▼──────┐ ┌───────────▼──────────────┐
│ MariaDB │ │ Redis │
│ netadmin │ │ dns.commands/acks │
└─────────────┘ │ mail.commands/acks │
│ agent.ready │
└──────┬──────────────┬─────┘
┌──────────▼──┐ ┌──────▼──────────┐
│ dns_agent │ │ mail_agent │
│ (serveur │ │ (serveur mail) │
│ BIND9) │ │ │
└─────────────┘ └──────────────────┘
Composants
| Composant | Rôle |
|---|---|
| Frontend | React 18 + Vite — interface utilisateur |
| Backend | FastAPI — API REST, authentification, RBAC |
| MariaDB | Base unique netadmin — toutes les tables |
| Redis | Broker de messages mTLS entre backend et agents |
| dns_agent | Tourne sur le serveur BIND9 — écrit les fichiers de zone, exécute rndc |
| mail_agent | Tourne sur le serveur mail — gère PostfixAdmin via MariaDB |
Prérequis
Serveur principal (Backend + Frontend)
- Python 3.11+
- Node.js 18+
- MariaDB 10.6+
- Redis 7+
Serveur BIND9 (agent DNS)
- Python 3.11+
- BIND9 avec
rndcconfiguré
Serveur Mail (agent mail)
- Python 3.11+
- PostfixAdmin avec MariaDB
- Accès à la base PostfixAdmin
Installation
1. Base de données MariaDB
CREATE DATABASE netadmin CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'netadmin'@'localhost' IDENTIFIED BY 'motdepasse';
GRANT ALL PRIVILEGES ON netadmin.* TO 'netadmin'@'localhost';
FLUSH PRIVILEGES;
Les tables sont créées automatiquement au premier démarrage du backend.
2. Backend
cd backend/
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
Copier et adapter la configuration :
cp config.yaml.example config.yaml
# Éditer config.yaml (voir section Configuration)
Démarrer :
uvicorn main:app --host 0.0.0.0 --port 8000
Un compte admin / admin est créé automatiquement si la base est vide. Changer le mot de passe immédiatement.
3. Frontend
cd frontend/
npm install
npm run build # Production
# ou
npm run dev # Développement
Le build de production est dans frontend/dist/ — à servir via nginx ou autre.
4. Certificats mTLS Redis
cd agents/
bash gen_certs.sh
Cela génère :
certs/ca.crt— Autorité de certification internecerts/backend.crt/key— Certificat du backendcerts/redis-server.crt/key— Certificat Rediscerts/dns-agent.crt/key— Certificat agent DNScerts/mail-agent.crt/key— Certificat agent mail
Distribuer les certificats sur les serveurs concernés.
5. Agent DNS (sur le serveur BIND9)
# Copier dns_agent.py et requirements.txt
pip install -r requirements.txt
# Copier le fichier systemd
cp netadmin-dns-agent.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now netadmin-dns-agent
Adapter le fichier service pour pointer vers les bons chemins et la config Redis.
6. Agent Mail (sur le serveur mail)
# Copier mail_agent.py et requirements.txt
pip install -r requirements.txt
cp netadmin-mail-agent.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now netadmin-mail-agent
Configuration (config.yaml)
# ── Serveur ───────────────────────────────────────────────────────────────
server:
host: "0.0.0.0"
port: 8000
cors_origins:
- "http://localhost:3000"
- "https://netadmin.example.com"
# ── Base de données MariaDB ───────────────────────────────────────────────
database:
host: "localhost"
port: 3306
user: "netadmin"
password: "motdepasse"
name: "netadmin"
# ── Redis (broker agents) ─────────────────────────────────────────────────
redis:
host: "localhost"
port: 6380 # Port mTLS
db: 0
ack_timeout: 15
tls:
enabled: true
client_cert: "/etc/netadmin/certs/backend.crt"
client_key: "/etc/netadmin/certs/backend.key"
ca_cert: "/etc/netadmin/certs/ca.crt"
# ── Notifications email ───────────────────────────────────────────────────
smtp:
enabled: false
host: "smtp.example.com"
port: 587
username: ""
password: ""
from_addr: "netadmin@example.com"
from_name: "NetAdmin"
use_tls: true # STARTTLS
use_ssl: false # SSL direct (port 465)
notify_login: true # Email à chaque connexion
notify_role_added: true # Email lors de l'ajout d'un rôle
# ── Authentification ──────────────────────────────────────────────────────
auth:
session_secret: "" # Généré automatiquement si vide
session_ttl_hours: 8
oidc:
enabled: false
issuer: "https://keycloak.example.com/realms/netadmin"
client_id: "netadmin"
client_secret: ""
redirect_uri: "https://netadmin.example.com"
use_pkce: true
admin_group: "netadmin-admins"
# ── Synchronisation ───────────────────────────────────────────────────────
sync:
interval: 300 # Polling automatique toutes les 5 minutes (0 = désactivé)
Rôles et permissions
| Rôle | Périmètre | Accès |
|---|---|---|
global_admin |
Global | Tout |
dns_admin |
Global | Toutes les zones DNS |
mail_admin |
Global | Tous les domaines mail |
domain_admin |
Par domaine | DNS + mail d'un domaine |
dns_zone_admin |
Par zone | Enregistrements d'une zone |
mail_domain_admin |
Par domaine | Comptes et alias d'un domaine |
Fonctionnalités
DNS
- Gestion des zones BIND9 (CRUD)
- Enregistrements A, AAAA, CNAME, MX, TXT, NS, PTR, SRV, CAA, TLSA, DS
- Activation/désactivation d'enregistrements (commentés dans la zone avec
; [DISABLED]) - Rechargement de zone via
rndc reload - Éditeur de zone brute
- Indicateur ⏳ sur les enregistrements en attente de synchronisation
- Gestion des comptes (quota, activation/désactivation)
- Gestion des alias (destinations multiples)
- Générateur de mot de passe aléatoire
- Synchronisation depuis PostfixAdmin (MariaDB)
Authentification & Sécurité
- Connexion locale (login/mot de passe)
- SSO Keycloak / OpenID Connect avec PKCE
- Double authentification TOTP (Google Authenticator, Aegis, Authy…)
- TOTP obligatoire configurable par compte (par l'admin)
- Gestion des sessions avec expiration
Administration
- Gestion des utilisateurs et des rôles
- Journal d'audit complet (qui, quand, quoi, depuis quelle IP)
- File d'attente des synchronisations (avec retry automatique à la reconnexion des agents)
- Historique des synchronisations (déclencheur, durée, résultat)
- Notifications email (connexion, ajout de rôle)
Résilience
- Si un agent est indisponible : l'action est mise en file d'attente SQLite
- À la reconnexion de l'agent, la file est vidée automatiquement
- Badge ⏳ dans l'interface pour les modifications non encore appliquées
Structure du projet
netadmin/
├── backend/
│ ├── main.py # Point d'entrée FastAPI
│ ├── config.py # Dataclasses de configuration
│ ├── config.yaml # Configuration (à adapter)
│ ├── db.py # Connexion MariaDB partagée
│ ├── audit.py # Journal d'audit + historique sync
│ ├── broker.py # Broker Redis + file d'attente
│ ├── notify.py # Notifications email (SMTP)
│ ├── requirements.txt
│ └── routers/
│ ├── auth.py # Authentification, RBAC, TOTP
│ ├── dns.py # Zones et enregistrements DNS
│ └── mail.py # Comptes, alias, domaines mail
├── frontend/
│ ├── index.html
│ ├── package.json
│ ├── vite.config.js
│ └── src/
│ ├── App.jsx
│ ├── App.css
│ ├── main.jsx
│ └── components/
│ ├── LoginPage.jsx
│ ├── DNSManager.jsx
│ ├── MailManager.jsx
│ ├── DomainsManager.jsx
│ ├── UsersManager.jsx
│ ├── UserProfile.jsx
│ ├── AuditLog.jsx
│ ├── SyncDashboard.jsx
│ ├── SyncToast.jsx
│ └── MailingLists.jsx
└── agents/
├── dns_agent.py # Agent BIND9
├── mail_agent.py # Agent PostfixAdmin
├── gen_certs.sh # Génération certificats mTLS
├── requirements.txt
├── netadmin-dns-agent.service
└── netadmin-mail-agent.service
Déploiement nginx (exemple)
# Frontend
server {
listen 443 ssl;
server_name netadmin.example.com;
root /opt/netadmin/frontend/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://127.0.0.1:8000/;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
Systemd (backend)
[Unit]
Description=NetAdmin Backend
After=network.target mariadb.service redis.service
[Service]
Type=simple
User=netadmin
WorkingDirectory=/opt/netadmin/backend
ExecStart=/opt/netadmin/venv/bin/uvicorn main:app --host 127.0.0.1 --port 8000
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Licence
Usage interne — tous droits réservés.