Dans la vie d'un adminsys, chaque service / brique logicielle a son niveau de criticité et son importance. Parmi eux, l'un des plus cruciaux n'est autre que le DNS. Ici, je vais donc vous décrire comment je gère mes différentes zones DNS et quelle configuration est actuellement en place, notamment pour Automario.
Les configurations présentes dans cet article ont été testées avec succès sur OpenBSD 6.8/6.9/7.0/7.1 et sur CentOS 8.
Principes de base
DNS
Le DNS (Domain Name System ou système de nom de domaine) est un service distribué qui sert à traduire les noms de domaine en adresses IP, afin de faciliter les connexions entre machines avec une série de caractères facilement mémorisables. Concrètement, il s'agit d'un système combinant plusieurs "annuaires" et les distribuant partout sur Internet, ce qui permet à n'importe qui d'aller sur une des machines hébergeant le site de Wikipedia en tapant www.wikipedia.org
.
DNSSEC
DNSSEC est un protocole standardisé qui est utilisé pour protéger une zone DNS et régler certains problèmes de sécurité au niveau du DNS. Le principe est de signer la zone DNS et de publier cette signature dans la zone, afin de récupérer celle-ci et donc de valider son origine.
Ce protocole permet notamment de lutter contre le DNS cache poisoning, un type d'attaque qui consiste à faire passer comme légitime une requête DNS contenant une autre adresse IP que celle qui est réellement utilisée, pour renvoyer le visiteur sur une autre machine, notamment pour faire de l'hameçonnage et récupérer des mots de passe ou des informations personnelles.
Serveur d'autorité principal
Un serveur d'autorité principal est un serveur DNS qui sert de référence pour une zone précise : c'est lui qui fournit toutes les informations concernant un nom de domaine et ses sous-domaines. Le serveur principal est également en charge des modifications : c'est sur lui qu'on effectue les modifications qui affecteront toute la zone (ajout, suppression ou modification d'entrées).
Serveur d'autorité secondaire
Un serveur d'autorité secondaire remplit la même mission qu'un serveur d'autorité principal, à un détail près : il ne gère pas les modifications, mais sert de serveur de secours. Si le serveur principal n'est pas joignable, c'est lui qui prend la suite des requêtes DNS. Cela permet ainsi de garder la zone synchronisée avec le reste d'Internet.
Une zone peut avoir plusieurs serveurs secondaires, multipliant ainsi les solutions de repli en cas de panne. Par exemple, Automario en a deux dans deux AS (Autonomous System) différents.
Description de ma configuration
Mes noms de domaines sont gérés selon le principe suivant :
- Un de mes deux serveurs principaux est hébergé chez moi, dans une machine virtuelle dédiée et équipée d'un VPN pour avoir une IP propre (vu qu'il y a aussi mon serveur mail dessus)
- Le deuxième serveur principal est situé sur une machine OpenBSD chez obsda.ms. Il sert aussi de serveur secondaire pour certains de mes domaines.
- Mon serveur DNS secondaire est hébergé chez ARN, sur un VPS sous OpenBSD
- Deux amis hébergent gentiment plusieurs de mes zones DNS sur leur machine, ils font aussi office de serveurs secondaires
Si on compile ça dans un schéma, on obtient ceci :
+--------------+ +--------------+
| | +----------->+ |
| VPN @ home +<--------+ v | obsda.ms |
| | v xxxx xxxxxx | |
+--------------+ xxx xxxx xx +--------------+
xxx xxx
xx xxx
xx Internet xx
x xx
xxx xxxx
+--------------+ xxxx xx x ^ +--------------+
| | ^ xxxxx xxx | | |
| ARN FAI +<---------+ xxxxxxxx | | ledzep / NS1 |
| | +------>+ |
+--------------+ +--------------+
Mise en place d'un serveur DNS principal
Avec NSD
NSD est un serveur DNS plus jeune que BIND et qui a l'avantage d'être léger et plus simple à utiliser que ce dernier. Il est très bien pour faire office de serveur d'autorité et pour gérer des noms de domaine, mais il ne peut pas servir de résolveur comme BIND ou Unbound.
Dans cet exemple, je vais mettre en place un serveur principal (ou master) pour deux zones DNS distinctes. Il communiquera avec deux autres serveurs DNS qui seront utilisés comme serveur secondaire (ou slave), à l'aide d'une clé TSIG pour l'authentification. Cela permet d'identifier les serveurs et surtout de bloquer les autres machines qui chercheraient à contrôler la zone DNS. Le serveur écoutera en IPv4 et en IPv6.
## Config file for NSD
# Master DNS
server:
server-count: 2
hide-version: yes
ip-address: x.x.x.x
ip-address: 2a00:xxxx:yyyy:zzz::10
debug-mode: no
verbosity: 2
zonesdir: "/etc/nsd/zones/"
remote-control:
control-enable: yes
control-interface: /var/run/nsd.sock
key:
name: "clesecrete"
algorithm: hmac-sha256
secret: "masuperchainedecarac="
zone:
name: "vinishor.xyz"
zonefile: "vinishor.xyz"
notify: y.y.y.y clesecrete
provide-xfr: y.y.y.y clesecrete
notify: z.z.z.z clesecrete
provide-xfr: z.z.z.z clesecrete
notify: 2100:xxxx:yyyy:zzz::20 clesecrete
provide-xfr: 2100:xxxx:yyyy:zzz::20 clesecrete
notify: 2100:xxxx:yyyy:zzz::30 clesecrete
provide-xfr: 2100:xxxx:yyyy:zzz::30 clesecrete
zone:
name: "automario.eu"
zonefile: "automario.eu"
notify: y.y.y.y clesecrete
provide-xfr: y.y.y.y clesecrete
notify: z.z.z.z clesecrete
provide-xfr: z.z.z.z clesecrete
notify: 2100:xxxx:yyyy:zzz::20 clesecrete
provide-xfr: 2100:xxxx:yyyy:zzz::20 clesecrete
notify: 2100:xxxx:yyyy:zzz::30 clesecrete
provide-xfr: 2100:xxxx:yyyy:zzz::30 clesecrete
La variable server-count
sert ici à lancer plusieurs instances de NSD, notamment pour assurer son bon fonctionnement. hide-version
est quant à lui un moyen de masquer la version de NSD, ce qui permet de ne pas divulguer cette information sur Internet et de ralentir les petits malins qui voudraient exploiter une potentielle faille (technique de la sécurité par l'obscurité). Les adresses IPv4 et IPv6 sont spécifiés séparément.
Les options notify
et provide-xfr
servent enfin à envoyer les informations de la zone aux serveurs secondaires et à initier la connexion entre les machines.
Avec Knot
Knot fonctionne de la même manière que NSD, mais il a l'avantage d'utiliser YAML pour sa syntaxe et de gérer tout seul DNSSEC, ce qui est un gros plus par rapport à NSD et BIND. Dans le cas de la zone pour openbsd.fr.eu.org, vu que DNSSEC avait été mis en place auparavant, cela me semblait être un gros plus. Comme avec NSD, l'exemple montre la configuration d'un serveur principal qui utilise une clé TSIG pour l'authentification avec les serveurs secondaires et des listes d'accès (ACL) :
# This is the main configuration for Knot DNS
# See knot.conf(5) or refer to the server documentation.
server:
version: ""
rundir: "/var/run/knot"
user: _knot:_knot
listen: [ x.x.x.x@53, 2a00:xxxx:yyyy:zzz::10@53 ]
log:
- target: syslog
any: info
database:
storage: "/var/db/knot"
key:
- id: clesecrete
algorithm: hmac-sha256
secret: masupercledecarac=
remote:
- id: arn
address: [y.y.y.y@53, 2100:xxxx:yyyy:zzz::20@53]
key: clesecrete
- id: ledzep
address: [z.z.z.z@53, 2100:xxxx:yyyy:zzz::30@53]
key: clesecrete
acl:
- id: key_rule
key: clesecrete
action: [transfer, notify, update]
template:
- id: classic
storage: "/var/db/knot/main"
file: "%s.zone"
semantic-checks: on
zonefile-load: difference
- id: secondary
storage: "/var/db/knot/secondary"
file: "%s.zone"
semantic-checks: on
zonefile-load: difference
- id: secure
storage: "/var/db/knot/secure"
file: "%s.zone"
semantic-checks: on
dnssec-signing: on
dnssec-policy: default
zonefile-load: difference
zone:
# Zone with DNSSEC
- domain: openbsd.fr.eu.org
template: secure
notify: [ledzep, arn]
acl: key_rule
Voici quelques précisions concernant cette configuration :
- Knot utilise un système de templates pour définir les différents types de zones DNS (ici, un template est dédié aux zones avec DNSSEC, aux zones sans DNSSEC et aux zones en mode serveur secondaire)
- La section ACL permet de définir les permissions sur la clé TSIG, mais il est possible de le faire sur une liste d'adresses IP à la place
- L'option
version
avec le paramètre vide permet de cacher la version de Knot, comme sur NSD. Par défaut, celle-ci est affiché.
Mise en place d'un serveur DNS secondaire
Avec NSD
Sur le serveur secondaire, la configuration de NSD ressemble beaucoup à celle présente au-dessus, tout en étant plus courte :
## Config file for NSD
# Secondary DNS
server:
server-count: 2
ip-address: y.y.y.y
ip-address: 2100:xxxx:yyyy:zzz::20
debug-mode: no
verbosity: 2
zonesdir: "/var/nsd/zones/"
remote-control:
control-enable: yes
control-interface: /var/run/nsd.sock
key:
name: "clesecrete"
algorithm: hmac-sha256
secret: "masuperchainedecarac="
# Secondaires
zone:
name: "vinishor.xyz"
zonefile: "slave/vinishor.xyz"
allow-notify: x.x.x.x clesecrete
request-xfr: x.x.x.x clesecrete
allow-notify: 2a00:xxxx:yyyy:zzz::10 clesecrete
request-xfr: 2a00:xxxx:yyyy:zzz::10 clesecrete
zone:
name: "automario.eu"
zonefile: "slave/automario.eu"
allow-notify: x.x.x.x clesecrete
request-xfr: x.x.x.x clesecrete
allow-notify: 2a00:xxxx:yyyy:zzz::10 clesecrete
request-xfr: 2a00:xxxx:yyyy:zzz::10 clesecrete
On notera ainsi que la section zone utilise l'adresse IP du serveur principal avec les instructions allow-notify
et request-xfr
. Ces deux instructions servent à envoyer les requêtes pour récupérer les zones DNS et leurs mises à jour et autoriser les flux entre les deux serveurs. La clé secrète est également identique, vu qu'elle sert d'équivalent mot de passe.
Cette configuration fonctionne aussi bien pour une zone classique que pour une zone utilisant DNSSEC. C'est pour cette raison que je n'utilise que NSD dans le cas d'un serveur secondaire.
Avec Knot
Même si mon serveur principal sous Knot sert aussi de serveur secondaire pour certaines de mes zones, voici la configuration correspondante pour obtenir un serveur secondaire :
# This is a sample of a minimal configuration file for Knot DNS.
# See knot.conf(5) or refer to the server documentation.
server:
version: ""
rundir: "/var/run/knot"
user: _knot:_knot
listen: [ y.y.y.y@53, 2100:xxxx:yyyy:zzz::20@53 ]
log:
- target: syslog
any: info
database:
storage: "/var/db/knot"
key:
- id: clesecrete
algorithm: hmac-sha256
secret: masupercledecarac=
remote:
- id: main
address: [x.x.x.x@53, 2a00:xxxx:yyyy:zzz::10@53]
key: clesecrete
acl:
- id: key_rule
key: clesecrete
action: [transfer, notify, update]
template:
- id: classic
storage: "/var/db/knot/main"
file: "%s.zone"
semantic-checks: on
- id: secondary
storage: "/var/db/knot/secondary"
file: "%s.zone"
semantic-checks: on
- id: secure
storage: "/var/db/knot/secure"
file: "%s.zone"
semantic-checks: on
dnssec-signing: on
dnssec-policy: default
zonefile-load: difference
zone:
# Secondary zone
- domain: vinishor.xyz
template: secondary
master: main
acl: key_rule
Quelques commandes pour utiliser Knot au quotidien
Afficher les clés DS pour DNSSEC
Pour terminer la configuration de DNSSEC sur une zone DNS, il convient de publier chez votre registraire ce qu'on appelle les clés DS. Ces clés sont calculées à partir des clés ZSK et KSK et permettent d'identifier et de confirmer l'origine des requêtes DNS. Pour une utilisation quotidienne, on utilise les clés DS générées sur la clé KSK.
Par défaut, au premier lancement, Knot génère tout seul le nécessaire, mais n'affiche pas les clés DS. Pour les afficher, on peut alors utiliser deux méthodes :
- utiliser deux commandes de la console de Knot :
# keymgr openbsd.fr.eu.org list
xxxxxxxxxxxxxxxxxxxxxxxxxx ksk=no zsk=yes tag=58970 algorithm=13 size=256 public-only=no pre-active=0 publish=1653669698 ready=0 active=1653669698 retire-active=0 retire=0 post-active=0 revoke=0 remove=0
yyyyyyyyyyyyyyyyyyyyyyyyyy ksk=yes zsk=no tag=45098 algorithm=13 size=256 public-only=no pre-active=0 publish=1653669698 ready=1653669698 active=0 retire-active=0 retire=0 post-active=0 revoke=0 remove=0
# keymgr openbsd.fr.eu.org ds 45098 # 45098 = id de la clé KSK
openbsd.fr.eu.org. DS 45098 13 2 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
openbsd.fr.eu.org. DS 45098 13 4 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
- utiliser
drill
pour afficher les clés :
$ drill @dns.openbsd.fr.eu.org -s openbsd.fr.eu.org DNSKEY
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 44910
;; flags: qr aa rd ; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;; openbsd.fr.eu.org. IN DNSKEY
;; ANSWER SECTION:
openbsd.fr.eu.org. 86400 IN DNSKEY 256 3 13 xxxxxxxxxxxxxxxxxxx== ;{id = 58970 (zsk), size = 256b}
openbsd.fr.eu.org. 86400 IN DNSKEY 257 3 13 yyyyyyyyyyyyyyyyyyy== ;{id = 45098 (ksk), size = 256b}
;; AUTHORITY SECTION:
;; ADDITIONAL SECTION:
;; Query time: 22 msec
;; SERVER: 46.23.94.78
;; WHEN: Sun Jun 5 18:18:07 2022
;; MSG SIZE rcvd: 195
;
; equivalent DS records for key 58970:
; sha1: openbsd.fr.eu.org. 86400 IN DS 58970 13 1 fffffffffffffffff
; sha256: openbsd.fr.eu.org. 86400 IN DS 58970 13 2 ffffffffffffffffffffffffffffffffff
;
; equivalent DS records for key 45098:
; sha1: openbsd.fr.eu.org. 86400 IN DS 45098 13 1 eeeeeeeeeeeeeeeee
; sha256: openbsd.fr.eu.org. 86400 IN DS 45098 13 2 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
Il suffit alors de copier-coller les enregistrements DS fournis par la console dans l'interface de votre registraire et d'attendre un peu le temps que le tout se synchronise. DNSSEC sera ensuite opérationnel sur votre domaine.
Gérer sa zone DNS avec Knot
Au premier lancement, Knot lit le fichier contenant votre zone DNS et le remplace par un format modifié, ce qui complique les modifications manuelles. Pour gérer les zones DNS, on peut utiliser le mode interactif de Knot : cela consiste à activer l'édition, entrer les modifications et valider le tout en commitant.
Un exemple valant mille mots, voici comment ajouter une entrée dans la zone DNS de openbsd.fr.eu.org
:
# knotc zone-begin openbsd.fr.eu.org
# knotc zone-set openbsd.fr.eu.org @ 86400 SOA dns.openbsd.fr.eu.org. linuxmario.linuxmario.net. 2022052708 10800 3600 1209600 3600
# knotc zone-set openbsd.fr.eu.org www 86400 CNAME openbsd.fr.eu.org.
# knotc zone-diff openbsd.fr.eu.org
# knotc zone-commit openbsd.fr.eu.org
On a donc l'ordre :
- l'activation des modifications sur la zone DNS de
openbsd.fr.eu.org
- la modification du serial du SOA (Start Of Autority) avec la date de la dernière modification et du nombre de modifications (1 si un seul changement, 2 si deux changements, etc) : il s'agit de la partie commençant par 2022xxx
- l'ajout d'une entrée quelconque (ici, un champ CNAME)
- la visualisation des différences pour vérifier les modifications
- la validation du tout avec publication automatique
Si vous faites beaucoup de modifications et que vous voulez éviter de tout casser sur votre zone, cette section de la documentation Knot vous permet de geler les mises à jour de zone par sécurité.
Conclusion
Avec cet article, vous avez maintenant toutes les cartes en main pour gérer proprement et simplement vos zones DNS. Après tout, pourquoi laisser son registraire s'occuper de vos DNS quand vous pouvez le faire vous-même !
Sources de l'article :
- Guide ultime du serveur DNS
- Ditching Bind9 for Unbound and Knot
- Access control list (ACL) - Knot DNS Documentation
- Gestion automatique de DNSSEC avec knot