36147fb1e0ea256a2552532b7afd36d86d74011b
NetAdmin — Console DNS & Mail
Interface d'administration DNS et Mail pour serveurs BIND9 + Postfix/Dovecot.
Architecture
┌─────────────────────────────────────────────────────────┐
│ Frontend React (Vite) :3000 │
│ Backend FastAPI :8000 │
│ MariaDB (base: netadmin) — données NetAdmin │
│ MariaDB (base: netadmin_mail) — données Postfix │
│ Redis mTLS broker :6380 │
│ │ │
│ dns_agent.py ←→ dns.commands/acks → BIND9 │
│ mail_agent.py ←→ mail.commands/acks → Postfix │
└─────────────────────────────────────────────────────────┘
Installation
Prérequis
- Python 3.11+
- Node.js 18+
- MariaDB 10.6+
- Redis 7+
- BIND9 9.20+
- Postfix + Dovecot
- Rspamd (optionnel, pour DKIM)
Backend
cd backend/
python3 -m venv ../venv
source ../venv/bin/activate
pip install -r requirements.txt
cp config.yaml /etc/netadmin/config.yaml # adapter les valeurs
uvicorn main:app --host 0.0.0.0 --port 8000
Frontend
cd frontend/
npm install
npm run build # production
# ou
npm run dev # développement :3000
Agents
# Agent DNS (sur le serveur BIND9)
cd agents/
pip install -r requirements.txt
cp ../backend/config.yaml /etc/netadmin/config.yaml # section dns_agent
python3 dns_agent.py
# Agent Mail (sur le serveur Postfix)
python3 mail_agent.py
Services systemd
cp agents/netadmin-dns-agent.service /etc/systemd/system/
cp agents/netadmin-mail-agent.service /etc/systemd/system/
systemctl enable --now netadmin-dns-agent netadmin-mail-agent
Configuration
backend/config.yaml
dns:
default_ns:
- "ns1.example.fr."
- "ns2.example.fr."
default_soa_admin: "hostmaster.example.fr"
dnssec_enabled: true
key_dir: "/etc/bind/keys"
mail_default_aliases:
abuse: "postmaster@example.fr"
hostmaster: "postmaster@example.fr"
postmaster: "admin@example.fr"
webmaster: "admin@example.fr"
dns_agent:
zones_dir: "/etc/bind/zones"
named_conf_local: "/etc/bind/named.conf.local"
rndc_cmd: "rndc"
key_dir: "/etc/bind/keys"
dnssec_policy: "default"
mail_agent:
dkim_dir: "/var/lib/rspamd/dkim"
dkim_selector: "mail"
Postfix main.cf
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_mailbox_domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
smtpd_sender_login_maps = mysql:/etc/postfix/mysql_sender_login_maps.cf
smtpd_sender_restrictions = reject_sender_login_mismatch, permit
Fichiers .cf Postfix (pointent sur netadmin_mail)
# mysql_virtual_mailbox_domains.cf
query = SELECT domain FROM domain WHERE domain='%s' AND active=1
# mysql_virtual_mailbox_maps.cf
query = SELECT CONCAT(domain,'/',SUBSTRING_INDEX(username,'@',1),'/')
FROM mailbox WHERE username='%s' AND active=1
# mysql_virtual_alias_maps.cf
query = SELECT goto FROM alias WHERE address='%s' AND active=1
# mysql_sender_login_maps.cf
query = SELECT authorized FROM sender_login_maps WHERE sender='%s'
Migration depuis PostfixAdmin
# Aperçu sans modification
python3 migrate_postfixadmin.py --dry-run \
--user root --password xxx \
--source-db postfix --target-db netadmin_mail
# Migration réelle
python3 migrate_postfixadmin.py \
--user root --password xxx \
--source-db postfix --target-db netadmin_mail
Le script migre : domaines, boîtes aux lettres (SHA512-CRYPT conservé), alias.
Les mots de passe $1$ (MD5) ou $2$ (bcrypt) sont marqués {MIGRATION_REQUIRED}
et le compte est désactivé — reset admin requis.
Scripts SQL de correction
# Corriger les alias avec source en partie locale seulement
mysql netadmin -e "UPDATE aliases SET source = CONCAT(source, '@', domain) WHERE source NOT LIKE '%@%';"
# Corriger les double domaines dans mailbox (si migration partielle)
mysql netadmin_mail -e "
UPDATE mailbox
SET username = CONCAT(SUBSTRING_INDEX(username,'@',1),'@',SUBSTRING_INDEX(username,'@',-1))
WHERE username LIKE '%@%@%';"
Fonctionnalités
DNS
- Gestion des zones BIND9 (création via Domaines uniquement)
- Enregistrements : A, AAAA, CNAME, MX, TXT, NS, PTR, SRV, CAA, TLSA, DS
- DNSSEC par zone (activation/désactivation, récupération des clés DS)
- NS par défaut configurables, email SOA admin par défaut
- Archivage automatique des clés DNSSEC dans
key_dir/old/
- Gestion des domaines mail avec quotas (global + par BAL)
- Boîtes aux lettres avec quota individuel et nom affiché
- Alias avec activation/désactivation
- DKIM via Rspamd (
rspamadm dkim_keygen) - Alias RFC obligatoires créés automatiquement (abuse, postmaster, hostmaster, webmaster)
- Sender login maps (prochainement)
- Mots de passe hashés en
{SHA512-CRYPT}viapasslib
Administration
- Authentification locale + OpenID Connect (Keycloak)
- TOTP (2FA) par compte, obligatoire ou optionnel
- RBAC : global_admin, dns_admin, mail_admin, domain_admin, dns_zone_admin
- Préférences utilisateur (thème clair/sombre) persistées en BDD
- Audit log complet
- Notifications email à la connexion
Interface
- Thème sombre / clair
- Création de domaine unifiée (DNS + Mail)
- Validation des enregistrements DNS (FQDN, IPv4, IPv6)
- Affichage des enregistrements DS détaillés (Key Tag, Algorithme, Digest)
- Interface entièrement en français
Sécurité
Certificats mTLS Redis
cd agents/
bash gen_certs.sh # génère CA + certificats agents
Copier les certificats dans /etc/netadmin/certs/.
Premier compte admin
Au premier démarrage, NetAdmin crée automatiquement :
- Utilisateur :
admin - Mot de passe :
admin - Changer immédiatement après connexion.
Structure des fichiers
netadmin/
├── backend/
│ ├── main.py # FastAPI app
│ ├── config.py # Dataclasses de configuration
│ ├── config.yaml # Configuration principale
│ ├── db.py # Connexion MariaDB (netadmin)
│ ├── broker.py # File Redis + pending_actions
│ ├── audit.py # Audit log
│ ├── notify.py # Notifications email
│ ├── requirements.txt
│ └── routers/
│ ├── auth.py # Auth locale + OIDC + TOTP + RBAC
│ ├── dns.py # Zones + enregistrements + DNSSEC
│ └── mail.py # Domaines + comptes + alias + DKIM
├── agents/
│ ├── dns_agent.py # Agent BIND9
│ ├── mail_agent.py # Agent Postfix/Dovecot/Rspamd
│ ├── requirements.txt
│ ├── gen_certs.sh # Génération certificats mTLS
│ ├── netadmin-dns-agent.service
│ └── netadmin-mail-agent.service
├── frontend/
│ ├── src/
│ │ ├── App.jsx # Routing + sidebar + auth
│ │ ├── App.css # Thème sombre/clair
│ │ ├── main.jsx # Point d'entrée + polices
│ │ └── components/
│ │ ├── LoginPage.jsx
│ │ ├── DomainsManager.jsx # DNS + Mail par domaine
│ │ ├── DNSManager.jsx # Enregistrements + DNSSEC
│ │ ├── MailManager.jsx # Comptes + alias
│ │ ├── UsersManager.jsx # Utilisateurs + rôles
│ │ ├── UserProfile.jsx # Mon compte + 2FA + thème
│ │ ├── AuditLog.jsx
│ │ ├── SyncDashboard.jsx
│ │ └── SyncToast.jsx
│ ├── package.json
│ └── vite.config.js
├── migrate_postfixadmin.py # Migration depuis PostfixAdmin
├── fix_alias_source.sql # Correction alias partiels
├── fix_double_domain.sql # Correction double domaine
└── README.md
Bases de données
netadmin (gestion NetAdmin)
users,user_roles,sessions,user_preferenceszones,records(DNS)domains,accounts,aliases(Mail NetAdmin)pending_actions,audit_log,sync_history
netadmin_mail (lue par Postfix/Dovecot)
domain— domaines hébergésmailbox— boîtes aux lettres (username = email complet)alias— alias et redirections (inclut self-aliases pour virtual_alias_maps)sender_login_maps— autorisations d'envoi
Languages
Python
48%
JavaScript
44.5%
Shell
4.2%
CSS
3.2%