Knot DNS
Présentation
Knot est un serveur DNS pensé comme une alternative à bind9, plus simple à utiliser et plus efficient en terme de ressources. Il est particulièrement adapté lorsque l'on a besoin d'héberger beaucoup de zones (pour un hébergeur, par exemple). Il ne fait qu'autorité, pas de récursif.
Il utilise trois commandes (2 en vrai):
- knotd : c'est le daemojn en lui-même, appellé par systemd
- knotc : la commande de contrôle de knot
- keymgr : la commande de gestion des clefs.
Une fois en place, il utilise une base de données à lui : on ne modifie pas les zone via des fichiers comme avec bind. Tout se passera par knotc, y compris la création de nouvelles zones.
Mise en place (migration depuis bind9)
Ma mise en place se fait sous Debian 11; knot est en version 3.0.5. J'ai un master et un slave.
Il suffit d'installer le paquet knot sur les deux machines (et d'enable le service).
Ensuite, je crée les confs suivantes dans /etc/knot/knot.conf (Lire les commentaires ajoutés pour l'occasion):
Master:
#Paramètres serveur, dont les adresses d'écoute #Knot dispose de son propre utilisateur système "knot" server: identity: dns1.squi.fr rundir: "/run/knot" user: knot:knot listen: [ 127.0.0.1@53, 163.172.172.222@53, 10.69.86.129@53 ] #J'utilise du rate limiting contre les attaques par réflexion #Mes valeurs sont ici plutôt basses mod-rrl: - id: default rate-limit: 40 slip: 2 #Clef générée avec la commande keymgr -t master_key #La clef tsig sert à sécuriser les transferts de zone vers le slave key: - id: master_key algorithm: hmac-sha256 secret: Arlxblablabla= log: - target: syslog any: info database: storage: "/var/lib/knot" #On identifie le slave remote: - id: secondary address: 51.158.187.166@53 key: master_key #...et on lui créée son acl acl: - id: acl_secondary address: 51.158.187.166 action: transfer key: master_key #Où seront mes templates de zone ? Mes zone utilisent-elles le rate limit ? template: - id: default storage: "/var/lib/knot" file: "%s.zone" global-module: mod-rrl/default #DNSSEC policy: - id: rsa algorithm: RSASHA256 ksk-size: 2048 zsk-size: 1024 #Zones #Les options sont assez claires, le fait d'ajouter dnssec-signing fait que dnssec est automatiquement déployé sur les zones zone: - domain: squi.fr notify: secondary acl: acl_secondary semantic-checks: on disable-any: on serial-policy: increment dnssec-signing: on dnssec-policy: rsa - domain: cptrthgs.fr notify: secondary acl: acl_secondary semantic-checks: on disable-any: on serial-policy: increment dnssec-signing: on dnssec-policy: rsa
Et sur le slave, c'est la même en plus simple:
server: identity: dns2.squi.fr rundir: "/run/knot" user: knot:knot listen: [ 127.0.0.1@53, ::1@53, 10.18.4.65@53 ] mod-rrl: - id: default rate-limit: 40 slip: 2 key: - id: master_key algorithm: hmac-sha256 secret: Arlxblablabla= log: - target: syslog any: info database: storage: "/var/lib/knot" remote: - id: primary address: 163.172.172.222@53 key: master_key acl: - id: acl_primary address: 163.172.172.222 action: notify key: master_key template: - id: default storage: "/var/lib/knot" file: "%s.zone" global-module: mod-rrl/default zone: - domain: squi.fr master: primary acl: acl_primary - domain: cptrthgs.fr master: primary acl: acl_primary
Après ça, sur le master, je dépose mes fichiers de zone issus de bind9 dans /var/lib/knot/ en tant que squi.fr.zone et cptrthgs.fr.zone, puis je restart knot.
Afficher les clefs (keymgr)
Keymgr est le gestionnaire de clefs de knot, et sa documentation est merdique, alors voici quelques commandes:
Si j'ai besoin de mes clefs KSK pour le DNSSEC:
- Lister les clefs d'une zone avec leur tag:
keymgr mazone.tld list
- Je peux voir la clef d'une zone:
keymgr mazone.tld dnskey
- Algorithme : en faisant un keymgr mazone.tld list, j'ai pas mal de détail. Si je veux savoir l'algorithme de la clef, je n'ai qu'un numéro; il faut alors se référer à ce tableau de l'IANA
Stats
Knot peut donner des stats. Je rajoute le bloc suivant dans ma conf
mod-stats: - id: "default" edns-presence: true flag-presence: true request-edns-option: true response-edns-option: true reply-nodata: true query-type: true
Et dans ma section template, je rajoute:
global-module: "mod-stats/default"
Après un reload (et un peu d'attente, je peux avoir des stats:
127 root@dns|knot > knotc stats server.zone-count = 2 mod-stats.request-protocol[udp4] = 5 mod-stats.server-operation[query] = 5 mod-stats.request-bytes[query] = 257 mod-stats.response-bytes[reply] = 527 mod-stats.edns-presence[request] = 5 mod-stats.edns-presence[response] = 5 mod-stats.flag-presence[DO] = 5 mod-stats.response-code[NOERROR] = 1 mod-stats.response-code[NXDOMAIN] = 4 mod-stats.reply-nodata[AAAA] = 1 mod-stats.query-type[A] = 2 mod-stats.query-type[AAAA] = 3
Commandes utiles
Contenu d'une zone
knotc zone-read squi.fr
Editer ma/mes zones
L'ajout d'un record dans une zone suit le principe suivant:
#Travailler sur la zone squi.fr knotc zone-begin squi.fr #Créer monhost.squi.fr avec un TTL à 3600 et l'adresse 1.2.3.4 knotc zone-set squi.fr monhost 3600 A 1.2.3.4 #Supprimer machin.squi.fr knotc zone-unset squi.fr machin #Commit des changements knotc zone-commit example.com #Ou bien, si je veux annuler knotc zone-abort squi.fr
Enregistrement à la racine
Si je veux faire pointer l'adresse squi.fr de mon domaine squi.fr vers 1.2.3.4, il faut utiliser @:
knotc zone-set @ 3600 A 1.2.3.4
Créer une zone et lui ajouter des records
Il faut mettre les enregistrements dans le bon ordre, sinon il déconne:
- Les A pour nos DNS
- Le SOA
- Les NS
En cas de pépin, on peut effacer toutes les données de la zone avec un
knotc -f zone-purge mazone.tld
sur les 2 dns
Exemple après avoir ajouté la zone dans le fichier de conf
$ knotc zone-begin example.com $ knotc zone-set example.com ns1 7200 A 1.2.3.4 $ knotc zone-set example.com ns2 7200 A 5.6.7.8 $ knotc zone-set example.com @ 7200 SOA ns1 1 86400 900 691200 3600 $ knotc zone-set example.com @ 3600 NS ns1 $ knotc zone-set example.com @ 3600 NS ns2 $ knotc zone-set example.com www 3600 A 5.8.9.1 $ knotc zone-commit example.com
Ajouter un TXT
$ knotc zone-begin squi.fr OK $ knotc zone-set squi.fr @ 3600 TXT blablabla #Si besoin de quotes, les échapper $ knotc zone-set squi.fr @ 3600 TXT \"blablabla\" $ knotc zone-commit squi.fr
Ajouter un MX
Mettre la priorité juste après la mention MX
knotc zone-set squi.fr @ 3600 MX mail.protonmail.ch 10
Backup de ma zone
Pour effectuer un backup complet de ma zone squi.fr dans le dossier (non-existant au départ pour éviter les problèmes de droits) /var/lib/knot/bkps:
knotc zone-backup +backupdir /var/lib/knot/bkps +journal squi.fr
Faisable à chaud.
Restaurer une zone depuis un backup
knotc zone-restore +backupdir /path/of/backup
Forcer un retransfert depuis le slave
Utile si le slave se retrouve en avance (par je ne sais quel miracle...). Depuis le slave :
knotc zone-retransfer squi.fr
Résumé commandes knotc
https://www.knot-dns.cz/docs/2.6/html/man_knotc.html
Créer une nouvelle zone
Il suffit de rajouter son bloc dans /etc/knot/knot.conf. Ensuite, pour pouvoir lui rajouter des recorrs du commit) : voir au-dessus (créer une nouvelle zone et lui ajouter des enregistrements).
Les signification des chiffres pour le SOA est plus claire quand on fait un dig multiline:
dig SOA +multiline squi.fr @dns1.squi.fr ; <<>> DiG 9.18.4 <<>> SOA +multiline squi.fr @dns1.squi.fr ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 44181 ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; WARNING: recursion requested but not available ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 1232 ;; QUESTION SECTION: ;squi.fr. IN SOA ;; ANSWER SECTION: squi.fr. 10800 IN SOA dns1.squi.fr. admin.squi.fr. ( 1652344716 ; serial 604800 ; refresh (1 week) 86400 ; retry (1 day) 2419200 ; expire (4 weeks) 10800 ; minimum (3 hours) ) ;; Query time: 10 msec ;; SERVER: 163.172.172.222#53(dns1.squi.fr) (UDP) ;; WHEN: Fri Jul 08 17:28:14 CEST 2022 ;; MSG SIZE rcvd: 83
Migrer d'un serveur knot à un autre
Pas la peine d'essayer les backups : ça marche pas.
- Porter /etc/knot/knot.conf depuis l'ancien serveur vers le nouveau
- Arrêter le service knot.
- Sur le nouveau serveur, supprimer /var/lib/knot
- Ramener le dossier /var/lib/knot de l'ancien vers le nouveau
- Restart du service knot.
Modifier une zone depuis un fichier
- https://knot.readthedocs.io/en/latest/operation.html#reading-and-editing-the-zone-file-safely
- https://knot.readthedocs.io/en/latest/reference.html#zone-zonefile-load
La ligne de commande est bien, mais un peu fastidieuse. En cas de besoin, on peut modifier directement les fichiers.
La conf par zone demande les deux lignes suivantes:
zonefile-load: difference-no-serial journal-content: all
Ainsi, on a pas besoin de modifier le serial de la zone : le serveur gère tout seul.
Ensuite, les commandes officielles sont:
- Freeze de la zone
knotc zone-freeze machin.truc
- Modification du fichier : /var/lib/knot/machin.truc.zone
- Reload
knotc zone-reload machin.truc
- Décongélation (lol) de la zone
knotc zone-thaw machin.truc
Mais on peut aussi modifier le fichier et restart knot, si jamais.