L’utilisation d’adresses IP brutes de pairs WireGuard pour se connecter aux ressources internes de votre réseau WireGuard peut être difficile pour les utilisateurs réguliers. Heureusement, il est facile de configurer un serveur DNS interne qui permet à vos utilisateurs d’accéder aux ressources exposées via WireGuard avec des noms DNS conviviaux.
Par exemple, supposons que vous ayez un serveur de chat interne configuré avec une adresse IP de pair WireGuard de 10.0.0.11 sur votre réseau WireGuard. Au lieu d’exiger que vos utilisateurs entrent son adresse IP de 10.0.0.11 dans leur application de chat ou leur navigateur Web pour y accéder, vous pouvez configurer votre serveur DNS interne pour qu’il utilise un nom DNS convivial comme chat.wg.corp.
Cet article vous montrera comment configurer un serveur CoreDNS sur le hub d’un réseau hub-and-spoke WireGuard, permettant aux noms DNS internes résolus par le serveur CoreDNS d’être utilisés pour accéder aux ressources réseau via le hub. Nous suivrons ces étapes :
Nous utiliserons le réseau WireGuard suivant comme exemple, configuré comme la passerelle de site en tant que scénario Spoke de l’article WireGuard multi-sauts :
Le hub WireGuard central (configuré comme l’hôte C à partir du scénario “Site Gateway as a Spoke”) permet à un client WireGuard (configuré comme Endpoint A à partir du scénario “Site Gateway as a Spoke”) de se connecter au réseau du bureau de NY via le NY Gateway (configuré comme Host β du scénario « Site Gateway as a Spoke ») ; et également au réseau Engineering Cloud via la passerelle Eng, et à d’autres pairs sur le réseau WireGuard comme le serveur de chat.
Nous allons configurer un serveur CoreDNS sur le Hub afin qu’un utilisateur utilisant le Client puisse accéder au Chat Server via un nom DNS convivial de chat.wg.corp, au lieu de son adresse IP WireGuard de 10.0.0.11 ; et accéder à l’imprimante du bureau de New York via un nom DNS convivial de printer.ny.corp, au lieu de son adresse IP LAN de 192.168.200.22 ; et accéder au serveur de fichiers d’ingénierie via un nom DNS convivial de files.eng.corp, au lieu de son adresse IP de réseau Engineering Cloud de 10.10.10.43.
Pour le serveur de fichiers, nous aurons le serveur CoreDNS sur le délégué WireGuard Hub à un serveur DNS privé fonctionnant sur le réseau cloud à 10.0.0.44 qui est déjà configuré pour résoudre les noms DNS pour le domaine eng.corp. Pour le serveur de chat et l’imprimante, nous configurerons notre serveur CoreDNS lui-même pour résoudre les noms DNS des domaines wg.corp et ny.corp.
Désactiver le DNS Stub resolver
définition
Qu’est-ce qu’un stub resolver ?
Le terme stub resolver peut sembler étrange. Le mot stub fait référence à quelque chose de partiel ou à un sous-ensemble de quelque chose de plus grand.
Un stub resolver est un résolveur DNS partiel. Il s’appuie sur les services d’un résolveur DNS récursif. Les résolveurs de stub ont été formellement définis pour la première fois en 1989 dans la section 6 de la RFC 1123.
Un stub resolver convertit les requêtes de résolution de noms provenant d’applications telles que les navigateurs Web en messages de requête DNS. Le résolveur de stub envoie les messages de requête DNS à un résolveur récursif DNS et renvoie le résultat à l’application.
Les stub resolvers n’effectuent pas eux-mêmes la récursivité. Au lieu de cela, ils parlent à un résolveur DNS récursif qui effectue la récursivité en leur nom. Cela permet à de nombreux stub resolvers de partager collectivement le cache du résolveur DNS récursif. Cela accélère la résolution de noms pour tous les stub resolvers et réduit la charge globale sur le DNS.
La première étape pour exécuter CoreDNS sur le Hub consiste à désactiver tout serveur DNS existant sur le Hub (pour libérer le port 53).
Si vous exécutez systemd sur le Hub, vous devrez désactiver le stub resolver de systemd. Modifiez le fichier /etc/systemd/resolved.conf et définissez son champ DNSStubListener sur no :
DNSStubListener=no
Appliquez ensuite vos modifications en exécutant la commande suivante :
$ sudo systemctl restart systemd-resolved
Tip
Si vous souhaitez que le Hub lui-même utilise CoreDNS pour ses propres recherches DNS, modifiez également les paramètres DNS et Domaines du fichier /etc/systemd/resolved.conf comme suit :
DNS=127.0.0.1
Domaines=~.
Mais assurez-vous de ne modifier ces deux paramètres qu’après avoir terminé l’installation et la configuration de CoreDNS et vérifié qu’il résout correctement les noms de domaine externes.
Installer COREDNS
CoreDNS s’exécute en tant qu’exécutable unique. Vous pouvez simplement télécharger l’archive de la dernière version à partir de la page des versions de CoreDNS sur GitHub, extraire l’archive (qui contient un seul fichier exécutable), définir des autorisations sur l’exécutable et l’exécuter. Vous pouvez également extraire la dernière image CoreDNS Docker pour exécuter CoreDNS en tant que conteneur Docker ; ou vous pouvez créer un fichier deb ou RPM pour installer CoreDNS en tant que service systemd sur les distributions Linux basées sur Debian ou Fedora.
VIA DOCKER
Vous pouvez lancer CoreDNS via Docker Compose en utilisant le fichier docker-compose.yml suivant :
Par exemple, créez un répertoire /srv/coredns/ sur le Hub et placez-y le fichier docker-compose.yml ci-dessus. Créez ensuite un sous-répertoire conf/ de /srv/coredns/ et placez-y le Corefile suivant :
# /srv/coredns/conf/Corefile. { whoami
log
}
Démarrez Docker Compose à partir du répertoire /srv/coredns :
$ cd /srv/coredns
$ sudo docker-compose up
Pulling coredns (coredns/coredns:)...
latest: Pulling from coredns/coredns
9731739b2823: Pull complete4dfb45b72a09: Pull completeDigest: sha256:017727efcfeb7d053af68e51436ce8e65edbc6ca573720afb4f79c8594036955
Status: Downloaded newer image for coredns/coredns:latest
Creating coredns_coredns_1 ... doneAttaching to coredns_coredns_1
coredns_1 | .:53
coredns_1 | CoreDNS-1.10.0
coredns_1 | linux/arm64, go1.19.1, 596a9f9
Testez-le en exécutant la commande suivante sur le Hub :
$ dig @127.0.0.1 example.com
; <<>> DiG 9.18.1-1ubuntu1.2-Ubuntu <<>> @127.0.0.1 example.com
;(1 server found);; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 22048;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 3;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232; COOKIE: 9b3888d9496d270e (echoed);; QUESTION SECTION:
;example.com. IN A
;; ADDITIONAL SECTION:
example.com. 0 IN A 172.17.0.1
_udp.example.com. 0 IN SRV 0041596 .
;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)(UDP);; WHEN: Thu Jan 19 20:13:03 UTC 2023;; MSG SIZE rcvd: 114
Parce que nous avons configuré CoreDNS avec le plugin whoami (à des fins de test), la réponse dans la “section supplémentaire” affichera l’adresse IP (172.17.0.1) et le port UDP (41596) à partir desquels vous avez interrogé CoreDNS — pas le DNS réel informations de example.com.
Vous verrez une entrée de journal correspondante pour la requête dans la sortie de CoreDNS :
Sur Debian (ou une distribution Linux basée sur Debian comme Ubuntu), vous pouvez installer CoreDNS via un paquet deb. Cela mettra en place un service systemd pratique pour vous.
Tout d’abord, clonez le dépôt CoreDNS Deployment :
Une fois la commande build réussie, naviguez vers le haut d’un répertoire et vous devriez avoir un tout nouveau package deb CoreDNS :
$ cd ..
ls -1
coredns_0-0_arm64.buildinfo
coredns_0-0_arm64.changes
coredns_1.10.0-0~22.040_arm64.deb
deployment
Installez le deb avec la commande suivante :
$ sudo dpkg -i coredns*.deb
Selecting previously unselected package coredns.
(Reading database ... 71988 files and directories currently installed.)Preparing to unpack coredns_1.10.0-0~22.040_arm64.deb ...
Unpacking coredns (1.10.0-0~22.040) ...
Setting up coredns (1.10.0-0~22.040) ...
Created symlink /etc/systemd/system/multi-user.target.wants/coredns.service → /lib/systemd/system/coredns.service.
Processing triggers for man-db (2.10.2-1) ...
Cela installera CoreDNS en tant que service systemd, écoutant sur les ports UDP et TCP 53. Par défaut, il sera configuré avec un Corefile de test similaire à celui que nous avons utilisé pour le conteneur Docker ci-dessus :
$ cat /etc/coredns/Corefile
# Default Corefile, see https://coredns.io for more information.# Answer every below the root, with the whoami plugin. Log all queries# and errors on standard output.. { whoami # coredns.io/plugins/whoami log # coredns.io/plugins/log errors # coredns.io/plugins/errors}
Et nous verrons un résultat similaire à celui du conteneur Docker ci-dessus si nous exécutons une requête test dessus :
$ dig @127.0.0.1 example.com
...
;; ADDITIONAL SECTION:
example.com. 0 IN A 127.0.0.1
_udp.example.com. 0 IN SRV 0039581 .
...
Et nous verrons une sortie de journal similaire de journald pour cela :
$ journalctl -u coredns.service
Jan 19 20:33:57 hub systemd[1]: Started CoreDNS DNS server.
Jan 19 20:33:57 hub coredns[42762]: .:53
Jan 19 20:33:57 hub coredns[42762]: CoreDNS-1.10.0
Jan 19 20:33:57 hub coredns[42762]: linux/arm64, go1.19.1, 596a9f9
Jan 19 20:37:01 hub coredns[42762]: [INFO] 127.0.0.1:39581 - 58758"A IN example.com. udp 52 false 1232" NOERROR qr,aa,rd 91 0.024847392s
Configurer COREDNS
Nous pouvons maintenant mettre à jour le Corefile de test (dans /srv/coredns/conf/Corefile si vous avez installé Via Docker, ou /etc/coredns/Corefile si vous avez installé Via Deb) avec une configuration utile pour nos domaines internes.
VIA HÔTES EN LIGNE
Le moyen le plus simple pour que CoreDNS résolve nos noms DNS internes est de les répertorier avec le format de fichier traditionnel /etc/hosts à l’intérieur du Corefile lui-même. Par exemple, nous pouvons lister les trois noms DNS que nous voulons résoudre (chat.wg.corp, printer.ny.corp et files.eng.corp) et leurs adresses IP respectives directement dans notre Corefile :
Si nous mettons à jour notre Corefile avec ce qui précède et redémarrons CoreDNS, CoreDNS peut maintenant résoudre ces trois noms DNS — mais seulement ces trois noms DNS :
Ce que nous voulons vraiment faire pour tous les domaines non répertoriés dans notre Corefile est de transmettre toutes les requêtes eng.corp au serveur DNS Eng à 10.10.10.44, et de transmettre toutes les autres requêtes à un serveur DNS public comme Quad9. Nous pouvons le faire en ajustant notre Corefile pour ajouter un paramètre de secours au plugin hosts, plus ajouter deux plugins de transfert — un pour notre résolveur DNS Eng et l’autre pour les résolveurs Quad9 :
Redémarrez CoreDNS, et maintenant nous pouvons résoudre à la fois les noms DNS codés en dur de notre plugin hôtes, ainsi que tout nom DNS de notre serveur DNS privé Eng (comme repo.eng.corp) — et tous les domaines publics (comme example.com), aussi:
Vous pouvez “écraser” de manière sélective les entrées DNS publiques avec les fichiers hôtes CoreDNS — comme vous le pouvez avec le fichier /etc/hosts sur votre ordinateur local. Par exemple, avec le Corefile suivant, nous pourrions faire en sorte que www.example.com soit résolu en 10.0.0.11 :
Avec la configuration ci-dessus, lors de l’utilisation de CoreDNS comme notre résolveur DNS (comme ce sera le cas lorsque l’interface WireGuard d’un client est active), www.example.com sera résolu en une adresse IP WireGuard interne de 10.0.0.11 ; et lorsqu'il n'utilise pas CoreDNS (comme ce sera le cas lorsque l'interface WireGuard du même client est fermée), www.example.com` se résoudra à son adresse IP publique normale :
Au lieu de définir des noms DNS personnalisés directement dans notre Corefile, nous pouvons les extraire dans un fichier séparé. L’avantage de ceci est a) nous pourrions utiliser le propre fichier /etc/hosts du Hub directement si nous le voulions, et b) nous pouvons configurer CoreDNS pour vérifier périodiquement ce fichier pour les mises à jour (au lieu d’avoir à redémarrer CoreDNS chaque fois que nous faisons un changer en un nom DNS).
Par exemple, nous pourrions extraire nos noms DNS personnalisés dans un fichier appelé /etc/coredns/hosts :
Nous pouvons également extraire des domaines distincts dans des fichiers hôtes distincts, pour notre propre commodité administrative. Par exemple, nous pourrions répertorier nos entrées DNS wg.corp dans un fichier /etc/coredns/hosts/wg.corp et nos entrées DNS ny.corp dans un fichier /etc/coredns/hosts/ny.corp :
Cependant, le plugin hosts ne peut être utilisé qu’une seule fois par bloc de niveau supérieur dans un Corefile, nous devons donc maintenant structurer notre Corefile avec des blocs de niveau supérieur séparés pour nos domaines wg.corp et ny.corp (et si nous le faisons, nous pourrait aussi bien tirer notre domaine eng.corp dans son propre bloc de niveau supérieur séparé):
Nous pouvons également utiliser des fichiers de zone de style RFC 1035 traditionnels pour définir nos entrées DNS personnalisées. Cela nous permet de tirer pleinement parti des fonctionnalités DNS, comme l’utilisation d’enregistrements CNAME ou SRV, ou l’application de différentes valeurs TTL (Time To Live) à différentes entrées DNS.
Par exemple, nous pourrions créer le fichier de zone suivant pour le domaine wg.corp :
; /etc/coredns/zones/db.wg.corp
$ORIGIN wg.corp.
$TTL 1h
@ IN SOA ( ns ; primary nameserver
. ; zone-admin email
1; serial number
24h ; refresh interval
2h ; retry interval
1000h ; expire interval
10m ; negative TTL
) IN NS ns
chat IN A 10.0.0.11
hub IN A 10.0.0.3
ns 5m IN A 10.0.0.3
_irc._tcp IN SRV 10106667 chat.wg.corp.
Et le fichier de zone suivant pour le domaine ny.corp :
; /etc/coredns/zones/db.ny.corp
$ORIGIN ny.corp.
$TTL 1h
@ IN SOA ( ns.wg.corp. ; primary nameserver
. ; zone-admin email
1; serial number
24h ; refresh interval
2h ; retry interval
1000h ; expire interval
10m ; negative TTL
) IN NS ns.wg.corp.
canon650i IN A 192.168.200.22
printer IN CNAME canon650i
Tip
Quelques éléments importants à retenir lors de la modification des fichiers de zone :
CoreDNS exige que chaque zone ait un enregistrement SOA valide (même si les seuls champs SOA qui comptent vraiment pour notre cas d’utilisation sont le numéro de série et le TTL négatif).
Incrémentez le numéro de série de chaque fichier de zone chaque fois que vous le mettez à jour.
Inclure une fin. lors de la spécification de noms de domaine complets.
Gardez vos TTL bas jusqu’à ce que vous ayez tout testé.
Si nous avons placé les deux fichiers ci-dessus dans le répertoire /etc/coredns/zones en tant que db.wg.corp et db.ny.corp, nous pouvons les appliquer via le plugin automatique de CoreDNS :
Le plugin automatique de CoreDNS exige par défaut que les fichiers de zone soient nommés avec un modèle comme db.{origin}, où {origin} est le nom de domaine de la zone — comme db.wg.corp pour un fichier de zone où wg.corp est le nom de domaine. Si vous souhaitez nommer vos fichiers de zone différemment, consultez la documentation du plug-in automatique pour plus de détails sur la configuration d’un modèle de fichier personnalisé ; ou utilisez le plugin de fichier au lieu du plugin automatique pour spécifier chaque fichier de zone individuellement.
Après le redémarrage, nous devrions être en mesure de rechercher notre enregistrement SRV IRC (Internet Relay Chat) :
$ dig @127.0.0.1 SRV _irc._tcp.wg.corp
; <<>> DiG 9.18.1-1ubuntu1.2-Ubuntu <<>> @127.0.0.1 SRV _irc._tcp.wg.corp
;(1 server found);; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60358;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232; COOKIE: 50115fc0e15cc095 (echoed);; QUESTION SECTION:
;_irc._tcp.wg.corp. IN SRV
;; ANSWER SECTION:
_irc._tcp.wg.corp. 3600 IN SRV 10106667 chat.wg.corp.
;; AUTHORITY SECTION:
wg.corp. 3600 IN NS ns.wg.corp.
;; ADDITIONAL SECTION:
chat.wg.corp. 3600 IN A 10.0.0.11
;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)(UDP);; WHEN: Thu Jan 19 20:20:38 UTC 2023;; MSG SIZE rcvd: 166
En plus de l’enregistrement CNAME pour l’imprimante du bureau de New York :
$ dig @127.0.0.1 printer.ny.corp
; <<>> DiG 9.18.1-1ubuntu1.2-Ubuntu <<>> @127.0.0.1 printer.ny.corp
;(1 server found);; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29728;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 1, ADDITIONAL: 1;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232; COOKIE: 71a27f43c8748c85 (echoed);; QUESTION SECTION:
;printer.ny.corp. IN A
;; ANSWER SECTION:
printer.ny.corp. 3600 IN CNAME canon650i.ny.corp.
canon650i.ny.corp. 3600 IN A 192.168.200.22
;; AUTHORITY SECTION:
ny.corp. 3600 IN NS ns.wg.corp.
;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)(UDP);; WHEN: Thu Jan 19 20:20:49 UTC 2023;; MSG SIZE rcvd: 166
Configurer le client WIREGUARD
Maintenant que notre serveur CoreDNS est opérationnel, il ne reste plus qu’à configurer chaque client WireGuard pour qu’il l’utilise comme serveur DNS au démarrage de l’interface WireGuard.
Étant donné que le serveur CoreDNS s’exécute sur notre Hub WireGuard, nous utiliserons l’adresse IP WireGuard du Hub (10.0.0.3) pour l’identifier. Nous devons simplement ajouter cette adresse IP comme paramètre DNS à la section [Interface] de la configuration de chaque client WireGuard :
# /etc/wireguard/wg0.conf# local settings for the WireGuard Client[Interface]PrivateKey=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=Address= 10.0.0.1/32
ListenPort=51821DNS= 10.0.0.3
# remote settings for the WireGuard Hub[Peer]PublicKey= jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=Endpoint= 192.0.2.3:51823
AllowedIPs= 10.0.0.0/24, 10.10.10.10/24, 192.168.200.0/24
Important
Assurez-vous que le client dispose d’un paramètre AllowedIPs qui inclut l’adresse IP du serveur DNS. Par exemple, dans le fichier de configuration ci-dessus, l’adresse IP du serveur DNS 10.0.0.3 est incluse dans le bloc 10.0.0.0/24 d’adresses IP autorisées pour l’homologue Hub du client.
Tip
Si le client utilise Linux avec systemd, utilisez le script PostUp suivant au lieu du paramètre DNS :
PostUp= resolvectl dns %i 10.0.0.3; resolvectl domain %i ~corp