Chiffrer ses requêtes DNS sur Arch Linux avec DNSCrypt

hidden_frog

Si on navigue sur internet en https, le contenu de la communication est chiffré. Par contre, l'adresse des sites que l'on visite circule en clair.

L'historique du surf est visible et conservé par le service du nom de domaine utilisé, celui du fournisseur d'accès à internet ou celui de google si on passe par ses serveurs DNS (8.8.8.8 ou 8.8.4.4).

Dans cet article, nous allons voir comment passer par des services DNS chiffrés depuis une installation Arch Linux en utilisant un cache DNS unbound pour accélérer la navigation.

Quelques explications sur les applications utilisées

 

DNSCrypt : protocole de chiffrage de la résolution de nom de domaines

DNSCrypt est un protocole qui permet de communiquer avec des résolveurs de noms de domaine de manière chiffrée et authentifiée.

Les noms de domaine permettent de traduire une adresse IP (par exemple 215.58.152.37) en adresse web (www.adresseweb.fr). Pour effectuer cette opération, lorsque l'on tape l'adresse www.adresseweb.fr dans un navigateur, notre ordinateur va interroger un serveur DNS pour pouvoir la traduire en adresse IP.

La plupart du temps, nous utilisons le serveur DNS de notre Fournisseur d'Accès Internet. Les adresses contactées sont enregistrées et conservées. Par ailleurs, cette communication circulant en clair, elle peut être facilement interceptée.

DNSCrypt va permettre de chiffrer la résolution de nom de domaine.

En contrepartie, il faudra se connecter à un serveur DNS compatible en prenant garde de choisir parmi ceux qui ne conservent pas de logs. Nous préférerons également les serveurs utilisables avec le protocole DNSSec qui permet de certifier les noms de domaine.

 

Unbound : cache DNS

C'est une application de serveur DNS.

Nous l'utiliserons ici d'abord pour mettre en cache (conserver pendant la session) les adresses résolues et gagner en rapidité de navigation.

Le deuxième objectif assigné à unbound sera de valider ces adresses grâce au protocole DNSSec.

Enfin, nous nous en servirons pour pouvoir configurer deux résolveurs de noms de domaine au cas où l'un serait défaillant.

 

Note sur la configuration de départ

Cet article est basé sur la distribution Arch Linux avec l'utilisation de Network Manager pour configurer les connexions réseau.

Je me suis appuyé sur le wiki d'Arch Linux pour la configuration.

Installation et configuration de DNSCrypt avec unbound, DNSSec, et deux résolveurs de noms de domaine.

 

Petite préparation : choisir les deux résolveurs

Avant de commencer l'installation proprement dite, nous allons choisir deux résolveurs DNSCrypt parmi la liste maintenue sur github.

On choisira des serveurs en IPV4, qui assurent la validation DNSSec et ne gardent pas de logs (dérouler les lignes vers la droite pour faire apparaître ces deux critères).

Il faut noter le nom simple (celui tout à gauche) pour la suite de la configuration.

Dans cet exemple, j'ai sélectionné le serveur "ipredator" et "dnscrypt.eu-nl".

 

Installation de DNSCrypt

 

$ sudo pacman -S dnscrypt-proxy

 

Pour pouvoir configurer deux résolveurs différents, nous allons créer un service systemd qui appelera deux "sockets" différents :

 

$ sudo nano /etc/systemd/system/dnscrypt-proxy@.service

 

[Unit]
 Description=DNSCrypt client proxy
 Documentation=man:dnscrypt-proxy(8)
 Requires=dnscrypt-proxy@%i.socket

[Service]
 Type=notify
 NonBlocking=true
 ExecStart=/usr/bin/dnscrypt-proxy \
 --resolver-name=%i
 Restart=always

 

Ctrl-o, Ctrl-x pour enregistrer et fermer.

 

Création du socket pour le serveur ipredator :

 

$ sudo cp /usr/lib/systemd/system/dnscrypt-proxy.socket /etc/systemd/system/dnscrypt-proxy@ipredator.socket

 

Création du socket pour le serveur dnscrypt.eu-nl :

 

$ sudo cp /usr/lib/systemd/system/dnscrypt-proxy.socket /etc/systemd/system/dnscrypt-proxy@dnscrypt.eu-nl.socket

 

Configuration des sockets

 

On les fait pointer sur 127.0.0.1 avec un port différent pour chacun (prendre un port supérieur à 1024).

Pour savoir si un port est déjà utilisé, exécuter la commande :

 

$ sudo netstat -upln|grep ":5354 "

 

(Bien mettre un espace après le numéro de port et avant le guillemet).

Si la commande retourne quelque chose, c'est que ce port est déjà pris.

 

$ sudo nano /etc/systemd/system/dnscrypt-proxy@ipredator.socket

 

[Unit]
 Description=dnscrypt-proxy listening socket

[Socket]
 ListenStream=127.0.0.1:5354
 ListenDatagram=127.0.0.1:5354

[Install]
 WantedBy=sockets.target

 

$ sudo nano /etc/systemd/system/dnscrypt-proxy@dnscrypt.eu-nl.socket

 

[Unit]
 Description=dnscrypt-proxy listening socket

[Socket]
 ListenStream=127.0.0.1:5355
 ListenDatagram=127.0.0.1:5355

[Install]
 WantedBy=sockets.target

 

Sandboxing des services

 

Si on souhaite que ces services soient "sandboxés", c'est à dire qu'ils soient restreints en accès au système d'exploitation sans perdre en capacité mais avec une meilleure sécurité, pour chacun d'entre eux :

 

$ sudo systemctl edit dnscrypt-proxy@ipredator.socket

 

[Socket]
 CapabilityBoundingSet=CAP_IPC_LOCK CAP_SETGID CAP_SETUID
 ProtectSystem=strict
 ProtectHome=true
 ProtectKernelTunables=true
 ProtectKernelModules=true
 ProtectControlGroups=true
 PrivateTmp=true
 PrivateDevices=true
 MemoryDenyWriteExecute=true
 NoNewPrivileges=true
 RestrictRealtime=true
 RestrictAddressFamilies=AF_INET
 SystemCallArchitectures=native
 SystemCallFilter=~@clock @cpu-emulation @debug @keyring @ipc @module @mount @obsolete @raw-io

 

Si on souhaite finalement annuler cette configuration, il faut par la suite exécuter la commande :

$ sudo systemctl revert dnscrypt-proxy@ipredator.socket

 

Lancement des deux services :

 

$ sudo systemctl daemon-reload
 $ sudo systemctl start dnscrypt-proxy@ipredator
 $ sudo systemctl status dnscrypt-proxy@ipredator
 $ sudo systemctl enable dnscrypt-proxy@ipredator.socket
 $ sudo systemctl start dnscrypt-proxy@dnscrypt.eu-nl
 $ sudo systemctl status dnscrypt-proxy@dnscrypt.eu-nl
 $ sudo systemctl enable dnscrypt-proxy@dnscrypt.eu-nl.socket

 

Configuration de resolv.conf

 

resolv.conf est le fichier qui indique l'adresse IP des serveurs de noms de domaines.

Nous commençons par indiquer à Network Manager que nous ne souhaitons pas qu'il écrase à chaque démarrage cette liste :

 

$ sudo nano /etc/NetworkManager/NetworkManager.conf

 

On ajoute :

[main]
 dns=none

 

$ sudo nano /etc/resolv.conf

 

On commente (en mettant un # en début de ligne le ou les serveurs précédents) et on rajoute le serveur local en 127.0.0.1/

# nameserver 8.8.8.8
# nameserver 8.8.4.4
nameserver 127.0.0.1

 

Installation de unbound

 

$ sudo pacman -S unbound

 

$ sudo nano /etc/unbound/unbound.conf

 

Dans la partie "server:"

 

On ajoute à la fin :

do-not-query-localhost: no
 forward-zone:
 name: "."
 forward-addr: 127.0.0.1@5354
 forward-addr: 127.0.0.1@5355

 

Si pour une raison ou une autre, on a choisi des serveurs qui ne sont pas compatibles DNSSec, il faut commenter la ligne :

trust-anchor-file: trusted-key.key

 

$ sudo systemctl start unbound
$ sudo systemctl status unbound
$ sudo systemctl enable unbound

 

Pour mettre unbound dans une sandbox :

$ sudo systemctl edit unbound.service

 

 [Service]
 CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT
 MemoryDenyWriteExecute=true
 NoNewPrivileges=true
 PrivateDevices=true
 PrivateTmp=true
 ProtectHome=true
 ProtectControlGroups=true
 ProtectKernelModules=true
 ProtectKernelTunables=true
 ProtectSystem=strict
 ReadWritePaths=/etc/unbound /run
 RestrictAddressFamilies=AF_INET AF_UNIX
 RestrictRealtime=true
 SystemCallArchitectures=native
 SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete

Mise en œuvre de DNSCrypt et unbound

 

Modification des connexions gérées par Network Manager

 

Clic droit sur l'icône de Network Manager, Configurer les connexions réseau.

 

configuration connexion réseau

 

On choisir la connexion que l'on souhaite modifier et on se rend dans l'onglet IPV4.

On choisit en Méthode : Automatique (adresses seulement),

On efface les adresses des précédents serveurs DNS pour les remplacer par 127.0.0.1

 

changement serveur dns

 

Une fois fait, Appliquer puis OK.

 

Redémarrer ensuite l'ordinateur.

 

Vérification du fonctionnement

 

Pour vérifier que nos serveurs DNS sont bien ceux de DNSCrypt, on se rend sur un site de test de leak DNS.

 

Par exemple, https://dnsleak.com/

Il devrait nous renvoyer les deux DNS que nous avons configurés.

 

Pour vérifier qu'unbound fonctionne correctement et met en cache les adresses visitées :

 

$ drill google.com
 ;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 10293
 ;; flags: qr rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
 ;; QUESTION SECTION:
 ;; google.com. IN A

;; ANSWER SECTION:
 google.com. 260 IN A 172.217.21.206

;; AUTHORITY SECTION:

;; ADDITIONAL SECTION:

;; Query time: 112 msec
 ;; SERVER: 127.0.0.1
 ;; WHEN: Sat Mar 18 13:27:00 2017
 ;; MSG SIZE rcvd: 44

 

Le résultat nous indique qu'il a fallu 112 millisecondes pour résoudre l'adresse IP de google.com.

 

On reproduit la même commande :

 

$ drill google.com

 

;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 27970
 ;; flags: qr rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
 ;; QUESTION SECTION:
 ;; google.com. IN A

;; ANSWER SECTION:
 google.com. 234 IN A 172.217.21.206

;; AUTHORITY SECTION:

;; ADDITIONAL SECTION:

;; Query time: 0 msec
 ;; SERVER: 127.0.0.1
 ;; WHEN: Sat Mar 18 13:27:26 2017
 ;; MSG SIZE rcvd: 44

 

La réponse a été cette fois immédiate car unbound a mis en cache local l'adresse IP de google.com.

 

DNSCrypt et Unbound sont donc fonctionnels.

À savoir, il peut être utile de vérifier de temps en temps la liste de serveurs DNSCrypt donnée en début d'article pour s'assurer que les deux serveurs sont toujours opérationnels ou que d'autres plus intéressants ont été mis en ligne.

On peut également mettre plus que deux serveurs différents en rajoutant un socket supplémentaire.

You may also like...

7 Responses

  1. Michel dit :

    Merci pour ce tutoriel très clair et très complet !

    Cependant, je me pose une question, est-ce que le fait que l’échange avec le résolveur DNS soit chiffré empêche quiconque (FAI compris) de voir les sites que nous consultons ? En ce cas, l’usage d’un VPN devient dès lors, inutile, non ?

    Aussi, j’ai rencontré un problème supplémentaire. En effet, j’utilise le client DHCP dhcpcd qui a, comme NetworkManager, la fâcheuse tendance à réécrire resolv.conf. Un simple paramètre trouvé sur la page du wiki d’Arch m’a permis de palier à ça, mais maintenant, lorsque je regarde sur DNSleak, un seul de mes deux résolveurs apparaît (le dernier configuré). Peut être car ils ont la même IP (127.0.0.1) ? En tout cas, si tu as un avis sur la question, je suis preneur. 🙂

    Encore merci !

    • SoozX dit :

      Bonjour,
      le chiffrage du résolveur DNS permet effectivement de masquer au FAI l’adresse des sites consultés.
      Une connexion VPN fournit d’autres protections. Entre autres : le masquage de l’adresse IP de ton ordinateur auprès du site consulté, le chiffrage du contenu même lorsque l’on se connecte en http, l’impossibilité pour le FAI de voir le protocole utilisé (par exemple, protocole bittorrent), etc. Par contre, le fournisseur VPN a lui accès à tout, d’où la nécessité d’avoir confiance en lui, de s’assurer qu’il conserve le moins de logs possibles et de continuer à se connecter en https dès que possible.
      A savoir aussi que les services VPN proposent eux-mêmes la plupart du temps leurs propres DNS permettant d’échapper aux FAI. Si on utilise et VPN et DNS chiffré hors VPN, on peut simplement se dire que l’on a pas mis tous ses oeufs dans le même panier …
      Concernant les tests DNSleak, même en utilisant NetworkManager, il arrive fréquemment qu’un seul des deux résolveurs soit détecté. Le principal, c’est de ne pas voir apparaître un résolveur non désiré …

      • Michel dit :

        Merci pour cette réponse et toutes ces précieuses informations. 🙂

        J’ai pu depuis me rendre compte que les deux résolveurs apparaissent parfois.

        Encore merci pour cet article !

  2. P0ulz dit :

    Bonjour,

    DNSSec semble, encore à ce jour, assez timide, aussi ai-je du mal à comprendre son fonctionnement.

    Fonctionne-t-il “out of the box”, c’est à dire que le processus d’authentification se fait tout seul dès lors que mes résolveurs sont compatibles et configurés comme dans l’article ?

    Ou bien y-a-t-il quelque chose à faire du côté des serveurs distants ? Par exemple, si je souhaites utiliser DNSSec pour télécharger des ressources sur un serveur de Google en m’assurant que celui-ci est bien légitime, faut-il que Google ait au préalable configuré ses serveurs d’une façon ou d’une autre pour supporter DNSsec ?

    Merci d’éclairer ma lanterne.

    • SoozX dit :

      Bonjour,

      La validation DNSSec fonctionne effectivement automatiquement avec cette installation à condition que le serveur distant soit compatible.
      Pour que la validation se fasse, il faut que les domaines de premier (.com) et deuxième niveau (google) soient signés DNSSec et que le résolveur utilisé soit capable d’utiliser DNSSec (l’objet de cet article).
      Si l’on accède à un site non signé DNSSec, la résolution se fait malgré tout, mais sans la validation.

  3. xse dit :

    Salut !
    Je laisse un petit commentaire, toutes les parties ou tu propose de modifier les unit systemd pour sandboxer les services sont mauvaises, en effet, tu ne peux pas modifier la section [service] d’un .socket ( concernant dnscrypt ) et tu ne peux pas ajouter tous ces paramêtres dans la section [unit] en ce qui concerne unbound.
    Les services se lanceront quand même mais les modifications ne seront pas appliquées, cf https://i.imgur.com/FJB9yYy.png

    tu peux en revanche modifier le .service de dnscrypt, ou mettre les options dans la section [socket] des .sockets

    Et concernant unbound il faut les mettres dans la section service, cf https://www.freedesktop.org/software/systemd/man/systemd.exec.html

    Bonne journée

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *