August 14, 2026
“Build a Pro-Level DHCP & DNS Server with dnsmasq + iptables on Linux”
Contexte : besoins d’une infrastructure légère mais robuste (lab, edge, IoT, PME).

By ATTE-THM
3 min read
"Build a Pro-Level DHCP & DNS Server with dnsmasq + iptables on Linux"
Pourquoi dnsmasq : léger, combo DHCP/DNS, facile à script.
Pourquoi iptables : sécurité, filtrage, NAT, isolation des clients.
Ce que vous saurez faire à la fin :
- attribuer des IP fixes et dynamiques
- résoudre des noms localement
- filtrer et rediriger le trafic des clients DHCP
- logger et surveiller
1. Architecture cible
- Schéma réseau :
- Interface LAN :
eth1(192.168.10.0/24) - Interface WAN :
eth0(connectée à Internet) - Services sur la même machine :
- dnsmasq (DHCP + DNS)
- iptables (NAT, forward, filtrage)
- Rôles :
- Serveur DHCP attribue IP de 192.168.10.100 à 192.168.10.200
- Réservation pour imprimante, serveur interne, etc.
- Redirection DNS local pour
*.lab.local
2. Installation et configuration de base
sudo apt update
sudo apt install dnsmasq -y # Debian/Ubuntu
# ou
sudo yum install dnsmasq -y # RHEL/CentOSsudo apt update
sudo apt install dnsmasq -y # Debian/Ubuntu
# ou
sudo yum install dnsmasq -y # RHEL/CentOSConfiguration minimale (/etc/dnsmasq.conf)
# Interface d'écoute
interface=eth1
# Plage DHCP
dhcp-range=192.168.10.100,192.168.10.200,255.255.255.0,24h
# Passerelle par défaut
dhcp-option=3,192.168.10.1
# DNS (le serveur lui-même)
dhcp-option=6,192.168.10.1
# Réservations statiques
dhcp-host=aa:bb:cc:dd:ee:ff,192.168.10.50,imprimante
dhcp-host=11:22:33:44:55:66,192.168.10.51,serveur-fichiers
# Résolution DNS locale
domain=lab.local
expand-hosts
local=/lab.local/# Interface d'écoute
interface=eth1
# Plage DHCP
dhcp-range=192.168.10.100,192.168.10.200,255.255.255.0,24h
# Passerelle par défaut
dhcp-option=3,192.168.10.1
# DNS (le serveur lui-même)
dhcp-option=6,192.168.10.1
# Réservations statiques
dhcp-host=aa:bb:cc:dd:ee:ff,192.168.10.50,imprimante
dhcp-host=11:22:33:44:55:66,192.168.10.51,serveur-fichiers
# Résolution DNS locale
domain=lab.local
expand-hosts
local=/lab.local/Démarrer et activer
sudo systemctl enable dnsmasq
sudo systemctl start dnsmasqsudo systemctl enable dnsmasq
sudo systemctl start dnsmasq3. Configuration avancée avec iptables
Objectifs sécurité :
- Les clients DHCP ne doivent pas accéder à l'interface d'administration de la machine (port 22, 80, etc.)
- Seul le serveur DNS (port 53) et DHCP (67/68) sont ouverts
- NAT pour l'accès Internet
- Limitation de bande passante optionnelle (TC)
Activer le forwarding IP
sudo sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.confsudo sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.confRègles iptables de base (NAT)
# NAT vers eth0
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# Forward autorisé
sudo iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT# NAT vers eth0
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# Forward autorisé
sudo iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPTFiltrage strict des clients DHCP
# Autoriser les requêtes DHCP (ports UDP 67/68)
sudo iptables -A INPUT -i eth1 -p udp --dport 67:68 -j ACCEPT
sudo iptables -A INPUT -i eth1 -p udp --sport 67:68 -j ACCEPT
# Autoriser DNS (port 53 UDP/TCP) depuis le réseau local
sudo iptables -A INPUT -i eth1 -p udp --dport 53 -j ACCEPT
sudo iptables -A INPUT -i eth1 -p tcp --dport 53 -j ACCEPT
# Bloquer tout autre accès à la machine depuis les clients DHCP
sudo iptables -A INPUT -i eth1 -j DROP# Autoriser les requêtes DHCP (ports UDP 67/68)
sudo iptables -A INPUT -i eth1 -p udp --dport 67:68 -j ACCEPT
sudo iptables -A INPUT -i eth1 -p udp --sport 67:68 -j ACCEPT
# Autoriser DNS (port 53 UDP/TCP) depuis le réseau local
sudo iptables -A INPUT -i eth1 -p udp --dport 53 -j ACCEPT
sudo iptables -A INPUT -i eth1 -p tcp --dport 53 -j ACCEPT
# Bloquer tout autre accès à la machine depuis les clients DHCP
sudo iptables -A INPUT -i eth1 -j DROPRedirection (si besoin d'un proxy ou DNS forcé)
# Rediriger tous les DNS entrants vers le serveur local
sudo iptables -t nat -A PREROUTING -i eth1 -p udp --dport 53 -j REDIRECT --to-port 53
sudo iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 53 -j REDIRECT --to-port 53# Rediriger tous les DNS entrants vers le serveur local
sudo iptables -t nat -A PREROUTING -i eth1 -p udp --dport 53 -j REDIRECT --to-port 53
sudo iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 53 -j REDIRECT --to-port 534. Gestion des logs et monitoring
Activer les logs détaillés de dnsmasq
# Dans /etc/dnsmasq.conf
log-queries
log-facility=/var/log/dnsmasq.log# Dans /etc/dnsmasq.conf
log-queries
log-facility=/var/log/dnsmasq.logSurveiller les leases DHCP
cat /var/lib/dnsmasq/dnsmasq.leasescat /var/lib/dnsmasq/dnsmasq.leasesScript d'alerte (exemple) :
# Notifier si plus de 80% des IP sont attribuées
total=100
used=$(cat /var/lib/dnsmasq/dnsmasq.leases | wc -l)
if [ $used -gt $((total * 80 / 100)) ]; then
echo "Alerte : pool DHCP saturé" | mail -s "DHCP Alert" admin@lab.local
fi# Notifier si plus de 80% des IP sont attribuées
total=100
used=$(cat /var/lib/dnsmasq/dnsmasq.leases | wc -l)
if [ $used -gt $((total * 80 / 100)) ]; then
echo "Alerte : pool DHCP saturé" | mail -s "DHCP Alert" admin@lab.local
fiIntégration avec fail2ban pour les requêtes abusives
# Filtre personnalisé pour dnsmasq dans /etc/fail2ban/filter.d/dnsmasq.conf
[Definition]
failregex = .* query\[A\].* from <HOST> .*
ignoreregex =# Filtre personnalisé pour dnsmasq dans /etc/fail2ban/filter.d/dnsmasq.conf
[Definition]
failregex = .* query\[A\].* from <HOST> .*
ignoreregex =5. Tests et validation
Tester un client DHCP
# Depuis un poste client
sudo dhclient -v eth0 # ou ipconfig /renew sous Windows# Depuis un poste client
sudo dhclient -v eth0 # ou ipconfig /renew sous WindowsVérifier la résolution DNS locale
nslookup imprimante.lab.local 192.168.10.1nslookup imprimante.lab.local 192.168.10.1Vérifier les règles iptables
sudo iptables -L -v -n
sudo iptables -t nat -L -v -nsudo iptables -L -v -n
sudo iptables -t nat -L -v -n6. Sauvegarde et persistance des règles iptables
Sur Debian/Ubuntu
sudo apt install iptables-persistent
sudo netfilter-persistent savesudo apt install iptables-persistent
sudo netfilter-persistent saveSur RHEL/CentOS
sudo service iptables savesudo service iptables save7. Optimisations et bonnes pratiques
- Séparer les interfaces (admin vs clients)
- Utiliser des VLAN si possible
- Mettre en place une politique de lease time raisonnable
- Activer DNSSEC si vous le souhaitez (dnsmasq le supporte)
- Utiliser ansible ou puppet pour déployer la configuration
- Ajouter un second serveur DHCP en failover (keepalived)
Bonus : script d'installation complet (à coller)
#!/bin/bash
# setup-dhcp-dns.sh
set -e
INTERNAL_IFACE="eth1"
EXTERNAL_IFACE="eth0"
DHCP_RANGE="192.168.10.100,192.168.10.200,255.255.255.0,24h"
apt update && apt install dnsmasq iptables-persistent -y
cat > /etc/dnsmasq.conf <<EOF
interface=$INTERNAL_IFACE
dhcp-range=$DHCP_RANGE
dhcp-option=3,192.168.10.1
dhcp-option=6,192.168.10.1
domain=lab.local
expand-hosts
local=/lab.local/
log-queries
log-facility=/var/log/dnsmasq.log
EOF
systemctl restart dnsmasq
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o $EXTERNAL_IFACE -j MASQUERADE
iptables -A FORWARD -i $INTERNAL_IFACE -o $EXTERNAL_IFACE -j ACCEPT
iptables -A FORWARD -i $EXTERNAL_IFACE -o $INTERNAL_IFACE -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i $INTERNAL_IFACE -p udp --dport 67:68 -j ACCEPT
iptables -A INPUT -i $INTERNAL_IFACE -p udp --dport 53 -j ACCEPT
iptables -A INPUT -i $INTERNAL_IFACE -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -i $INTERNAL_IFACE -j DROP
netfilter-persistent save
echo "Setup terminé."#!/bin/bash
# setup-dhcp-dns.sh
set -e
INTERNAL_IFACE="eth1"
EXTERNAL_IFACE="eth0"
DHCP_RANGE="192.168.10.100,192.168.10.200,255.255.255.0,24h"
apt update && apt install dnsmasq iptables-persistent -y
cat > /etc/dnsmasq.conf <<EOF
interface=$INTERNAL_IFACE
dhcp-range=$DHCP_RANGE
dhcp-option=3,192.168.10.1
dhcp-option=6,192.168.10.1
domain=lab.local
expand-hosts
local=/lab.local/
log-queries
log-facility=/var/log/dnsmasq.log
EOF
systemctl restart dnsmasq
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o $EXTERNAL_IFACE -j MASQUERADE
iptables -A FORWARD -i $INTERNAL_IFACE -o $EXTERNAL_IFACE -j ACCEPT
iptables -A FORWARD -i $EXTERNAL_IFACE -o $INTERNAL_IFACE -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i $INTERNAL_IFACE -p udp --dport 67:68 -j ACCEPT
iptables -A INPUT -i $INTERNAL_IFACE -p udp --dport 53 -j ACCEPT
iptables -A INPUT -i $INTERNAL_IFACE -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -i $INTERNAL_IFACE -j DROP
netfilter-persistent save
echo "Setup terminé."8. Dépannage fréquent
ProblèmeSolutionLes clients n'obtiennent pas d'IPVérifier systemctl status dnsmasq et les logs. Pas d'accès InternetVérifier le NAT et sysctl net.ipv4.ip_forward. DNS ne résout pasVérifier /etc/resolv.conf de la machine hôteIptables bloque toutAjouter -j LOG avant DROP pour tracer.
Conclusion
- Récap des forces : simplicité, performance, contrôle.
- Ce setup tient dans un script, facile à versionner.
- En production, ajouter monitoring (Prometheus + node_exporter, ou Telegraf).