Créer une DMZ complète sous linux
Bon, la ça ne rigole plus, maintenant que t'as les bases pour créer un routeur avec un vieux grille pain, nous allons voir comment créer une DMZ avec plusieurs zones et ainsi ne plus risquer se faire pwned par tes nouvelles toilettes connectés dont l'app est reliée à un cloud chinois piraté depuis 2002.
Cet article est assez technique et il faut avoir au moins connaissance de comment fonctionnent les réseaux IP et du principe des masques de sous-réseau pour pouvoir tout comprendre. Contrairement aux articles qu'on trouve souvent sur les DMZ, nous allons en créer une en dual stack IPv4/IPv6 avec des outils plus modernes et faciles à maintenir que les classique iptables, bind9, etc.
Une DMZ ?
DMZ veut dire DeMilitarized Zone ou encore Zone démilitarisée en français. A la base, cela consiste à créer une zone dans notre réseau contenant des machines accessibles par internet mais distincte de notre réseau local (domestique ou d'entreprise). Le tout est géré par un pare-feu qui va s'occuper du routage et de la segmentation les différentes zones réseaux en permettant seulement aux flux légitimes de passer d'une zone à l'autre.
Aujourd'hui c'est aussi le seul moyen d'héberger chez soi des sites en IPv6 sans avoir tout son réseau accessible depuis internet. La plupart des fournisseurs d'accès à internet (FAI) ne proposent pas d'interface de configuration du pare-feu en IPv6. C'est tout ouvert ou tout fermé.
Une DMZ ok mais avec quoi ?
Depuis le temps, tu dois commencer à me connaître et tu sais qu'on va la faire avec presque rien. Parce que presque rien c'est bien, comme ça tu choisis ton système d'exploitation et tu peux recycler du vieux materiel. C'est donc pas cher à l'achat et il n'y a pas de licence à payer régulièrement.
Le materiel
En terme de matériel, on utilisera le même type que pour faire un routeur statique décrit dans mon précédent article. En résumé, un vieux PC avec des cartes réseaux additionnelles, un minipc noname vendu sous l’appellation firewall, un banana pi ou encore un odroid h4 avec une carte d'extension réseau si tu veux le top du top en terme de rapport coût/performance/efficience énergétique. C'est comme tu préfères.
Le système d'exploitation
Perso j'aime bien Archlinux mais pour commencer simple on va faire ça sous Debian 13 (Trixie) avec uniquement une configuration du kernel qui va bien et quelques outils. Nous ne verrons pas ici l'installation de Debian 13 car il y a de très bon tutos pour ça sur internet ainsi que le manuel officiel.
Les pré-requis
Pour qu'une dmz fonctionne bien et pour ne pas multiplier les machines, on va installer ou activer sur notre machine pare-feu/routeur les fonctionnalités suivantes :
- Le transfert de paquets d'une interface réseaux à une autre (forwarding).
- Un firewall avec nftables (la base).
- Un service de DHCP pour que les machines en IPv4 puissent acquérir une adresse IPv4 automatiquement.
- Un service de Router Advertisement pour que les machines en IPv6 puisse acquérir une adresse IPv6 automatiquement.
- un service de DNS pour pouvoir accéder à nos autres machines via un nom de domaine local (optionnel).
Après avoir installé Debian 13, installons les paquets nécessaires pour pouvoir commencer (en root).
apt update
apt install systemd-resolved kea nftables
systemctl enable systemd-networkd
Le réseau
Définir le plan d'adressage
Il va falloir choisir quels sous-réseaux vont être utilisés pour les différentes zone. Pour l'IPv4, vu qu'on est sur des adresses privées, on peut donc choisir ce qu'on veut dans la classe C. Pour l'IPv6, il va falloir voir quels sont les réseaux mis à disposition par ton FAI. En général les FAI en donnent 5 ou 6 et ils sont en masque sur 64 bits (ou encore en /64 en notation CIDR).
Pour pouvoir les connaître il faut se connecter à l'interface de gestion de sa box.
Exemple avec mon interface de gestion chez Free
Ensuite il va falloir définir les IP des différentes interfaces de la machine qui va être notre routeur/firewall. Tout doit être définit en statique. On ne veut pas que ses IP changent à chaque redémarrage et que ça ne perturbe toute la config.
On partira du principe que j'ai les sous-réseaux IPv6 suivants donnés par mon FAI (comme sur l'image d'exemple ci-dessus). On va les utiliser de la manière suivante :
- 2001:db8:1:10::/64 sera le réseau d'interconnexion entre la box et le routeur, nommé "wan".
- 2001:db8:1:11::/64 sera le réseau nommé "lan" sur lequel on aura les PC standarts de connecté.
- 2001:db8:1:12::/64 sera le réseau nomé "dmz" sur lequel sera raccordé les machines qui devront être accessible depuis internet.
Pour ce tuto je vais choisir les IPs définies ci-dessous.
Pour l'interface wan :
- IPv6 publique : 2001:db8:1:10::1ce:face/64
- IPv6 locale : fe80::1ce:face/64
- IPv4 : 192.168.0.100/24
Pour l'interface lan :
- IPv6 publique : 2001:db8:1:11::1ce:cafe/64
- IPv6 locale : fe80::1ce:cafe/64
- IPv4 : 192.168.1.1/24
Pour l'interface dmz :
- IPv6 publique : 2001:db8:1:12::1ce:beef/64
- IPv6 locale : fe80::1ce:beef/64
- IPv4 : 192.168.2.1/24
Nommage des interfaces réseau
Première étape si on ne veux pas s'emmêler les pinceaux : nommer ses interfaces réseau. Il va falloir activer systemd-networkd et configurer au moins trois interfaces : wan, lan et dmz. Pour cela il va te falloir faire un petit tour sur mon article sur le nommage des interfaces.
Une fois le service systemd-networkd activé, les fichiers .link créés et la machine redémarrée, on va pouvoir passer à la suite.
Configuration des interfaces réseau
Ci dessous, les fichiers des configuration des 3 interfaces à placer dans /etc/systemd/network/.
Pour le fichier 10-wan.network :
[Match]
Name=wan
[Network]
DHCP=no
IPv6AcceptRA=false
LinkLocalAddressing=no
KeepConfiguration=yes
[Route]
# IPv6 du lien local de la box internet
Gateway=fe80::aa:bb:cc:dd
GatewayOnLink=yes
[Route]
# IPv4 de la box internet
Gateway=192.168.0.254
GatewayOnLink=yes
[Address]
Address=192.168.0.100/24
[Address]
Address=2001:db8:1:10::1ce:face/64
[Address]
Address=fe80::1ce:face/64
Pour le fichier 11-lan.network :
[Match]
Name=lan
[Network]
DHCP=no
IPv6AcceptRA=false
LinkLocalAddressing=no
[Address]
Address=192.168.1.1/24
[Address]
Address=2001:db8:1:11::1ce:cafe/64
[Address]
Address=fe80::1ce:cafe/64
Pour le fichier 12-dmz.network :
[Match]
Name=dmz
[Network]
DHCP=no
IPv6AcceptRA=false
LinkLocalAddressing=no
[Address]
Address=192.168.2.1/24
[Address]
Address=2001:db8:1:12::1ce:beef/64
[Address]
Address=fe80::1ce:beef/64
Activation du transfert de paquets
Pour permettre à une machine linux de transférer les paquets d'une interface à l'autre il faut activer l'option de forwarding dans la config du systeme.
Ca se fait via le fichier /etc/sysctl.d/sysctl.conf. Il va falloir dé-commenter (ou ajouter) les lignes suivant:
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
Le DHCP
Le DHCP est un protocole permettant l'attribution automatique d'une IPv4 à une machine qui se connecte sur un réseau. Pour que ça fonctionne on doit avoir un serveur DHCP qui répond aux sollicitations des machines. On va utiliser Kea DHCP qui est le remplaçant du vénérable ISC DHCP.
On n'utilisera pas le DHCPv6 car il y a encore (trop) de machines qui ne respectent pas ce standard voir même qui, comme les smartphones android, n'implémentent même pas de quoi communiquer avec le serveur.
Le fichier de configuration de Kea /etc/kea/kea-dhcp4.conf est assez verbeux et contient pas mal d'indications. Les sections qui vont nous intéresser sont les suivantes.
Au début du fichier, on déclare sur quelles interfaces on sert le service DHCPv4 :
"Dhcp4": {
// Add names of your network interfaces to listen on.
"interfaces-config": {
// See section 8.2.4 for more details. You probably want to add just
// interface name (e.g. "eth0" or specific IPv4 address on that
// interface name (e.g. "eth0/192.0.2.1").
"interfaces": ["lan", "dmz"] // <--- Modifier ICI
// Kea DHCPv4 server by default listens using raw sockets. This ensures
// all packets, including those sent by directly connected clients
// that don't have IPv4 address yet, are received. However, if your
// traffic is always relayed, it is often better to use regular
// UDP sockets. If you want to do that, uncomment this line:
// "dhcp-socket-type": "udp"
},
//....... Reste du fichier
}
Puis on declare la config des sous réseaux lan et dmz dans la section subnet4:
"Dhcp4": {
//....... Début du fichier
"subnet4": [
{
"id": 1,
"subnet": "192.168.1.0/24",
"interface": "lan",
// Plage d'adresse dynamique à alouer.
"pools": [ { "pool": "192.168.1.2 - 192.168.1.200" } ],
"option-data": [
{
"name": "routers",
"data": "192.168.1.1" // <--- ICI mettre l'IP de l'interface lan.
},
{
"name": "domain-name-servers", // <--- ICI mettre votre DNS.
// Si vous faites la partie optionnelle de ce tuto mettre l'IP de l'interface lan
// Sinon mettre l'IP de votre box (ex 192.168.0.254) ou du DNS de votre choix (ex : DNS4EU en 86.54.11.1)
"data": "192.168.1.1"
}
],
// Si vous voulez que certaines machines aient toujours la même ip c'est dans cette section qu'on le déclare
"reservations": [
//exemple avec une machine
{
"hw-address": "11:22:33:44:55:66", // L'adresse MAC de la machine
"ip-address": "192.168.1.201", // L'adresse IP souhaitées. Doit être en dehors de la plage dynamique.
"hostname": "PC_bureau"
},
// exemple avec une seconde machine. N'oubliez pas la virgule entre les deux.
{
"hw-address": "11:22:33:44:dd:ff",// L'adresse MAC de la machine
"ip-address": "192.168.69.202",
"hostname": "PC_portable_2"
}
]
},
{
"id": 2,
"subnet": "192.168.2.0/24",
"interface": "dmz",
// Ici on définit un pool plus restreint. La plupart des IP seront configurées en fixe directement sur les machines.
"pools": [ { "pool": "192.168.2.2 - 192.168.2.100" } ],
"option-data": [
{
"name": "routers",
"data": "192.168.2.1" // <--- ICI mettre l'IP de l'interface dmz.
},
{
"name": "domain-name-servers",
"data": "192.168.2.1"// <--- ICI mettre votre DNS.
// Si vous faites la partie optionnelle de ce tuto mettre l'IP de l'interface wan
// Sinon mettre l'IP de votre box (ex 192.168.0.254) ou du DNS de votre choix (ex : DNS4EU en 86.54.11.1)
}
],
"reservations": [
//exemple avec une machine
{
"hw-address": "aa:bb:cc:44:55:66", // L'adresse MAC de la machine
"ip-address": "192.168.2.101", // L'adresse IP souhaitées. Doit être en dehors de la plage dynamique.
"hostname": "server_mail"
}
]
}
],
//....... Reste du fichier
}
Puis on n'oublie pas de recharger la config de Kea.
systemctl restart kea-dhcp4-server.service
Le routing advertisement
C'est un peu le même principe que pour le DCHP. En prefix on met le réseau correspondant à l'interface et en RDNSS l'adress IPv6 du DNS. Si tu fais la partie du tuto optionnelle sur le DNS, il faut mettre l'IP de l'interface elle même. Sinon tu peux utiliser un résolveur public (ex : DNS4EU en 2a13:1001::86:54:11:1)
interface lan_bridge {
AdvSendAdvert on;
prefix 2001:db8:1:11::/64
{
AdvOnLink on;
AdvAutonomous on;
AdvRouterAddr on;
};
RDNSS 2001:db8:1:11::1ce:cafe {};
};
interface dmz {
AdvSendAdvert on;
prefix 2001:db8:1:12::/64
{
AdvOnLink on;
AdvAutonomous on;
AdvRouterAddr on;
};
RDNSS 2001:db8:1:12::1ce:beef {};
};
Puis on n'oublie pas de recharger la config.
systemctl reload radvd.service
Le pare-feu
Là on attaque la partie la plus complexe.
Pour schématiser, le pare-feu applique les règles en fonction du sens des paquets IP :
- Inbound : les paquets qui arrivent par une interface réseau et à destination d'une des IP de cette machine.
- Output : Les paquets emis par cette machine et qui sortent par une interface.
- Forward : les paquetes qui arrive par une interface réseau et qui ne sont pas à destination d'une IP de cette machine. Ils doivent la traverser pour en atteindre une autre.
En plus des fonctionnalités de filtrage il va falloir utiliser du NAT. En effet, notre DMZ est capable de router le trafic vers la Box internet en IPv4 et IPv6, mais les box des FAIs n'ont presque jamais la possibilité de configurer des routes statiques en IPv4. Il faut donc ruser avec du NAT.
Un schéma récapitulatif du comportement de nftable est dispo sur le site officiel :
© nft hooks par Pablo Neira Ayuso
La config
On va configurer nftable via le fichier /etc/nftables.conf. L'avantage de nftable sur iptables (à part qu'il est son successeur et que iptables est censé ne plus être utilisé hein), c'est qu'on peut définir des variables et des tableaux. C'est donc bien plus facile à maintenir et à comprendre. On verra dans la section suivante comment se servir des compteurs.
Pour l'exemple on va dire qu'on a deux serveurs dans la zone DMZ, un serveur web et un serveur de mail. Les explications sont dans les commentaires du fichier. Le fichier étant un peu larges, tu peux utiliser shift+molette de souris pour déplacer le texte latéralement dans le bloc ci-dessous.
#!/usr/sbin/nft -f
# On nettoie tout avant d’appliquer la config
flush ruleset
# ---- Variables du réseau ----
# Nom de l'interface lan.
define DEV_LAN = "lan"
# Nom de l'interface wan
define DEV_WAN = "wan"
# Nom de l'interface dmz
define DEV_DMZ = "dmz"
# Declaration des subnets locaux
define NET_DMZ = 192.168.2.0/24
define NET_LAN = 192.168.1.0/24
define NET_IPV6_LAN = 2001:db8:1:11::/64
# Déclaration des IP spécifiques
define INT_WAN_IP = 192.168.0.100
define IPV6_SERVEUR_mail = 2001:db8:1:12::dad:c0de
define IPV4_SERVEUR_mail = 192.168.2.101
define IPV6_SERVEUR_web = 2001:db8:1:12::dad:cafe
define IPV4_SERVEUR_web = 192.168.2.102
table inet global {
# --------------------- Chaines d'aiguillage -----------------------
# Point d'entrée principal pour tout le traffic (non source-naté) IPv4 et ipv6 à destination de cette machine
# Cette règle va aiguiller les décisions vers les blocs (chains) inbound correspondants.
chain inbound {
type filter hook input priority 0; policy drop;
# Allow traffic from established and related packets, drop invalid
ct state vmap { established : accept, related : accept, invalid : drop }
# allow loopback traffic, anything else jump to chain for further evaluation
iif vmap { lo : accept, $DEV_WAN : jump inbound_wan, $DEV_DMZ : jump inbound_dmz, $DEV_LAN_BRIDGE : jump inbound_lan}
# On revient ici après les aiguillages (jump) si le paquet n'a pas été accepté.
# Et si on arrive ici, le paquet est detruit par la policy drop en debut de bloc.
}
# point d'entrée principale pour tout le traffic ipv4 et ipv6 qui est routé au travers de cette machine
# Cette règle va aiguiller les décisions vers les blocs (chains) forward correspondants.
chain forward {
type filter hook forward priority 0; policy drop;
# accepte de forward depuis la loopback
iif lo counter accept
# Allow traffic from established and related packets, drop invalid
ct state invalid counter drop
ct state { established, related } counter accept
# Accepte de transferer le trafic depuis le LAN
iif $DEV_LAN_BRIDGE counter accept
# Le traffic venant du WAN va être évalué.
iif $DEV_WAN counter jump forward_from_wan
# Le traffic venant de la DMZ va être évalué.
iif $DEV_DMZ counter jump forward_from_dmz
# On revient ici après les aiguillages (jump) si le paquet n'a pas été accepté.
# Et si on arrive ici, le paquet est detruit par la policy drop en debut de bloc
# On met un petit compteur au besoin pour voir ce qui est drop.
counter
}
# Sortie. Pas de filtre. Cette machine est considéré de confiance.
chain output {
type filter hook output priority 0;
}
# --------------------- fin : Chaines d'aiguillage ----------------
# --------------------- Chaines de décision -----------------------
# Ici c'est la chaîne de décision pour les paquets qui viennent du WAN (d'internet) à destination de cette machine
# On bloque tout sauf l'ICMPv6 nécessaire au routage.
chain inbound_wan {
# On accepte les paquets IPv6 permettant à notre routeur de communiquer avec les autres.
# On limite cependant a 10 requêtes par seconde pour eviter de se faire flooder la machine
# par une machine malveillante depuis internet
icmpv6 type {echo-request,nd-neighbor-solicit,nd-neighbor-advert,nd-router-solicit,nd-router-advert,mld-listener-query,destination-unreachable,packet-too-big,time-exceeded,parameter-problem} limit rate 10/second accept
# Ce qui est bloqué est noté dans un compteur nommé.
counter name dropped_from_wan
}
# Ici c'est la chaîne décision pour les paquets qui viennent du LAN a destination de cette machine
# Les utilisateurs du LAN sont considérés de confiance. On permet l'accès a cette machine (pour le SSH, le DHCP,
# les requêtes DNS si vous faites la partie optionnel du tuto, etc).
chain inbound_lan {
ip6 saddr $NET_IPV6_LAN accept
ip saddr $NET_LAN accept
}
# Ici c'est la chaîne de décision pour les paquets qui viennent de la zone DMZ a destination de cette machine
# Les machines de la DMZ sont considérées comme potentiellement compromises. On permet l'accès
# à cette machine pour certains services légitimes, mais on bloque tout le reste.
chain inbound_dmz {
# Comme pour la chaine inbound_wan au dessus, on accepte l'ICMPv6 mais en limitant pour éviter le flooding.
icmpv6 type {echo-request,nd-neighbor-solicit,nd-neighbor-advert,nd-router-solicit,nd-router-advert,mld-listener-query,destination-unreachable,packet-too-big,time-exceeded,parameter-problem} limit rate 10/second counter accept
# On accepte également le ping ipv4 de manière limité afin de permettre le bon fonctionnement (ex : packet too big) et l'éventuel debugging des serveurs.
icmp type echo-request limit rate 10/second counter accept
# Communication entrante avec le routeur (cette machine)
# On accepte le DHCP
udp dport 67 accept
# On accepte le DNS
udp dport 53 accept
tcp dport 53 accept
# On accepte le mdns (tu sais le truc avec avahi-daemon et les requêtes en .local)
udp dport 5353 accept
# Ce qui est bloqué est noté dans un compteur nommé.
counter name dropped_from_dmz
}
# Décisions pour le trafic qui vient du WAN et traverse cette machine
chain forward_from_wan {
# Comme pour la chaine inbound_wan au dessus, on accepte l'ICMPv6 mais en limitant pour éviter le flooding.
icmpv6 type {echo-request,nd-neighbor-solicit,nd-neighbor-advert,nd-router-solicit,nd-router-advert,mld-listener-query,destination-unreachable,packet-too-big,time-exceeded,parameter-problem} limit rate 10/second counter accept
# Pareil pour l'ICMPv4
icmp type echo-request limit rate 10/second counter accept
# Accepte HTTP/s vers le serveur web.
ip6 daddr $IPV6_SERVEUR_web tcp dport { http, https} counter accept
ip daddr $IPV4_SERVEUR_web tcp dport { http, https} counter accept
# Accepte les Mails vers le serveur mail (SMTP, IMAPS et submission).
ip6 daddr $IPV6_SERVEUR_mail tcp dport { 25, 587, 993} counter accept
ip daddr $IPV4_SERVEUR_mail tcp dport { 25, 587, 993} counter accept
# Ce qui est bloqué est noté dans un compteur nommé.
counter name dropped_from_wan
}
# Décisions pour le trafic qui vient de la zone DMZ et traverse cette machine
chain forward_from_dmz {
# Comme pour la chaine inbound_wan au dessus, on accepte l'ICMPv6 mais en limitant pour éviter le flooding.
icmpv6 type {echo-request,nd-neighbor-solicit,nd-neighbor-advert,nd-router-solicit,nd-router-advert,mld-listener-query,destination-unreachable,packet-too-big,time-exceeded,parameter-problem} limit rate 10/second counter accept
# Pareil pour l'ICMPv4
icmp type echo-request limit rate 10/second counter accept
# Vers le wan
# Http(s) utilisé pour mise a jours debian.
# Port 25 utilisé pour envoyer des mail depuis le serveur mail
oif $DEV_WAN tcp dport {25, http, https} counter accept
# On accepte les requetes ntp vers le wan
oif $DEV_WAN tcp dport 123 accept
oif $DEV_WAN udp dport 123 accept
# Ce qui est bloqué est noté dans un compteur local.
counter
}
# --------------------- fin : Chaines de décision -----------------
# --------------------- Chaines de NAT ----------------------------
# Nat de l'IPv4 en sortie (masquarade)
chain postrouting {
type nat hook postrouting priority 100; policy accept;
# masquerade private IP addresses
ip saddr $NET_LAN oif $DEV_WAN masquerade
ip saddr $NET_DMZ oif $DEV_WAN masquerade
}
# Nat de l'IPv4 en entrée. Obligatoire car pas de routage possible sur la box internet
chain prerouting {
type nat hook prerouting priority -100;
iif $DEV_WAN ip daddr $INT_WAN_IP tcp dport { 25, 143, 587, 993} counter dnat ip to $IPV4_SERVEUR_mail
iif $DEV_WAN ip daddr $INT_WAN_IP tcp dport { http, https} counter dnat ip to $IPV4_SERVEUR_web
}
# --------------------- fin : Chaines de NAT ----------------------
# --------------------- Compteurs nommés --------------------------
counter dropped_from_wan{
comment "paquets bloqués en entrée wan en direction du parefeu ou du réseau local"
}
counter dropped_from_dmz{
comment "paquets bloqués en entrée dmz en direction du parefeu, du réseau local ou du wan"
}
# --------------------- fin : Compteurs nommés --------------------
}
Une fois la configuration écrite, on la recharge :
systemctl reload nftables.service
Les commandes utiles
Nftables permet de consulter les différents compteurs. C'est utile pour comprendre où sont bloqués les paquets en cas d'erreur de configuration. Ça permet aussi de vérifier que les blocages volontaires fonctionnent correctement.
Pour voir les compteurs nommés :
nft list counters
Pour voir les compteurs locaux d'une chaine. Exemple avec la chaine forward_from_wan :
nft list chain inet global forward_from_wan
Il aussi est possible de réinitialiser les compteurs sans redémarrer nftables :
nft reset counters
(Optionnel) le DNS
Cette partie optionnelle permet que toutes les requêtes DNS du LAN et de la DMZ passent par le routeur. Il se chargera ensuite d'envoyer les requêtes vers un résolveur de confiance en TLS, ce qui assurera un minimum de confidentialité.
Avoir un résolveur local permet aussi d'ajouter des noms d'hôte à ses propres machines, ce qui est plutôt pratique pour ne pas taper des IPv6 à rallonge pour se connecter aux serveurs de mail, nas, etc.
Commençons par installer le daemon qui va bien :
apt install unbound
Il suffit ensuite de créer un fichier de configuration de zone dans /etc/unbound/unbound.conf.d/ma_zone.conf
Puis de l'éditer de la manière suivante (les explications sont dans les commentaires) :
## Simple recursive caching DNS
## unbound.conf -- https://DNSwatch.COM
#
server:
# verbosity number, 0 is least verbose. 1 is default.
verbosity: 1
# number of threads to create. 1 disables threading.
# num-threads: 1
# the amount of memory to use for the RRset cache.
# plain value in bytes or you can append k, m or G. default is "4Mb".
rrset-cache-size: 128m
# the amount of memory to use for the message cache.
# plain value in bytes or you can append k, m or G. default is "4Mb".
msg-cache-size: 64m
# Enforce privacy of these addresses. Strips them away from answers.
# It may cause DNSSEC validation to additionally mark it as bogus.
# Protects against 'DNS Rebinding' (uses browser as network proxy).
# Only 'private-domain' and 'local-data' names are allowed to have
# these private addresses. No default.
private-address: 10.0.0.0/8
private-address: 172.16.0.0/12
private-address: 192.168.0.0/16
private-address: 169.254.0.0/16
private-address: fd00::/8
private-address: fe80::/10
private-address: ::ffff:0:0/96
# ---vvvvvv--- ICI on ajoute les réseaux IPv6 sur lesquels on veut définir des noms d'hôtes. ---vvvvvvvvvv---
private-address: 2001:db8:1:12::/64 # <---- ICI exemple avec réseau DMZ dans lequel on va déclarer un nas
# Allow the domain (and its subdomains) to contain private addresses.
# local-data statements are allowed to contain private addresses too.
private-domain: "maison" # <---- ICI le domaine de premier niveau qu'on veut déclarer
# a number of locally served zones can be configured.
# local-zone: <zone> <type>
# local-data: "<resource record string>"
# o deny serves local data (if any), else, drops queries.
# o refuse serves local data (if any), else, replies with error.
# o static serves local data, else, nxdomain or nodata answer.
# o transparent gives local data, but resolves normally for other names
# o redirect serves the zone data for any subdomain in the zone.
# o nodefault can be used to normally resolve AS112 zones.
# o typetransparent resolves normally for other types and other names
# o inform acts like transparent, but logs client IP address
# o inform_deny drops queries and logs client IP address
# o inform_redirect redirects queries and logs client IP address
# o always_transparent, always_refuse, always_nxdomain, always_nodata,
# always_deny resolve in that way but ignore local data for
# that name
# o always_null returns 0.0.0.0 or ::0 for any name in the zone.
# o noview breaks out of that view towards global local-zones.
#
# defaults are localhost address, reverse for 127.0.0.1 and ::1
# and nxdomain for AS112 zones. If you configure one of these zones
# the default content is omitted, or you can omit it with 'nodefault'.
#
# If you configure local-data without specifying local-zone, by
# default a transparent local-zone is created for the data.
#
# You can add locally served data with
# local-zone: "local." static
# local-data: "mycomputer.local. IN A 192.0.2.51"
# local-data: 'mytext.local TXT "content of text record"'
#
# note : les CNAMEs ne fonctionnent pas en local-data et local-zone
local-zone: "maison." static
local-data: "nas.maison. IN A 192.168.2.250" # <---- ICI l'IPv4 de la machine d'exemple
local-data: "nas.maison. IN AAAA 2001:db8:1:12::250" # <---- ICI l'IPv6 de la machine d'exemple
# specify the interfaces to answer queries from by ip-address.
# The default is to listen to localhost (127.0.0.1 and ::1).
# specify 0.0.0.0 and ::0 to bind to all available interfaces.
# specify every interface[@port] on a new 'interface:' labelled line.
# The listen interfaces are not changed on reload, only on restart.
# interface: 192.0.2.153
interface: 127.0.0.1
interface: ::1
interface: 192.168.1.1 # <------- ICI on ajoute l'IPv4 de l'interface LAN
interface: 2001:db8:1:11::1ce:cafe # <------- ICI on ajoute l'IPv6 de l'interface LAN
interface: 192.168.2.1 # <------- ICI on ajoute l'IPv4 de l'interface DMZ
interface: 2001:db8:1:12::1ce:beef # <------- ICI on ajoute l'IPv6 de l'interface DMZ
# specify the interfaces to send outgoing queries to authoritative
# server from by ip-address. If none, the default (all) interface
# is used. Specify every interface on a 'outgoing-interface:' line.
ip-freebind: yes
outgoing-interface: 192.168.0.100 # <------- ICI on ajoute l'IPv4 de l'interface WAN
outgoing-interface: 2001:db8:1:10::1ce:face # <------- ICI on ajoute l'IPv6 de l'interface WAN
#prefer-ip6: yes
# control which clients are allowed to make (recursive) queries
# to this server. Specify classless netblocks with /size and action.
# By default everything is refused, except for localhost.
# Choose deny (drop message), refuse (polite error reply),
# allow (recursive ok), allow_setrd (recursive ok, rd bit is forced on),
# allow_snoop (recursive and nonrecursive ok)
# deny_non_local (drop queries unless can be answered from local-data)
# refuse_non_local (like deny_non_local but polite error reply).
access-control: 127.0.0.0/8 allow
access-control: ::1 allow
access-control: 192.168.1.0/24 allow # <------- ICI on ajoute la zone LAN en IPv4
access-control: 2001:db8:1:11::::/64 allow # <------- ICI on ajoute la zone LAN en IPv6
access-control: 192.168.2.0/24 allow # <------- ICI on ajoute la zone DMZ en IPv4
access-control: 2001:db8:1:12::/64 allow # <------- ICI on ajoute la zone DMZ en IPv6
# enable to not answer id.server and hostname.bind queries.
hide-identity: yes
# enable to not answer version.server and version.bind queries.
hide-version: yes
# request upstream over TLS (with plain DNS inside the TLS stream).
# Default is no. Can be turned on and off with unbound-control.
tls-upstream: no
# Forward zones
# Create entries like below, to make all queries for 'example.com' and
# 'example.org' go to the given list of servers. These servers have to handle
# recursion to other nameservers. List zero or more nameservers by hostname
# or by ipaddress. Use an entry with name "." to forward all queries.
# If you enable forward-first, it attempts without the forward if it fails.
forward-zone:
name: "."
forward-tls-upstream: yes # <------- ICI on indique que les requêtes sortantes sont en TLS.
# Résolveurs DNS4EU
forward-addr: 2a13:1001::86:54:11:1@853 # <------- ICI on ajoute le résolveur de notre choix
forward-addr: 2a13:1001::86:54:11:201@853 # <------- ICI on peut en mettre un autre
forward-first: no
Une fois la configuration terminée, il faut la recharger.
systemctl reload unbound.service
Avec cet exemple un "ping nas.maison" fonctionnera depuis une machine connecté dans les zone DMZ et/ou LAN. Et par la magie du domaine privé, le raccourcis "ping nas" devrait fonctionner aussi.
La box internet
A partir d'ici, tu vas pouvoir déplacer tout ce qui est branché à la box vers les bonnes interfaces du routeur. S'il y a plus d'une machine sur une zone il faudra utiliser un Switch.
Selon ton FAI tu vas pouvoir :
- Désactiver la fonction firewall IPv6.
- Activer la fonction DMZ IPV4 en indiquant en destination l'adresse IPv4 de l'interface WAN (optionnel, ici 192.168.0.100).
- Changer les éventuelles règles de NAT qu'il y avait déjà, en direction de l'IPv4 de l'interface WAN (toujours 192.168.0.100 dans ce tuto) si tu n'as pas activé la fonction DMZ.
Conclusion
Nous avons vu comment créer une bulle isolée dans ton réseau qui a accès à internet mais seulement vers les ports autorisés et qui ne peut pas initier de connections vers ton LAN. Cette bulle qu'on a nommé DMZ permet d'y déployer des serveurs qu'on peut rendre accessibles avec les règles appropriées depuis l’extérieur.
Tu peux également ajouter autant de zones du même type tant que tu disposes d'interfaces réseaux supplémentaires. Il peut être intéressant justement de créer une bulle spéciale pour les objets connecté pour lesquels tu ne peux avoir aucune certitude sur ce qu'ils font sur ton réseau.
Nous verrons dans de prochains articles comment ajouter une liste noire d'IP malveillantes dans notre pare-feu et aussi comment intégrer une antenne wifi, dans une des zones, directement sur le routeur.