Serveur DNS récursif ouvert

Adresses

Nous avons un serveur DNS récursif ouvert (rate-limité, supervisé) sur l’extérieur qui répond au doux nom de ns0.ldn-fai.net. Son adresse IPv6 est 2001:913::8 et son adresse IPv4 est 80.67.188.188.

Si vous êtes sur un réseau qui filtre ou censure le trafic DNS, vous pouvez tenter les approches suivantes :

  • utiliser un port alternatif (le serveur écoute aussi sur le port 9000) ;
  • forcer l’utilisation de TCP plutôt qu’UDP ;
  • passer par TLS (le serveur écoute en TLS sur le port TCP 443 ainsi que le port 853)
    • le port 443 est le port réservé pour HTTPS et n’est donc généralement pas filtré ;
    • le port 853 est le port réservé pour DNS sur TLS (RFC 7858).

Attention : le service sur TLS est expérimental.

Le port 9000 est moyennement utile dans un environnement très filtré et le service sera probablement mis prochainement sur le port 80.

Utiliser un port alternatif

Pour passer par le port 9000, plusieurs possibilités :

  • PAT (Port Address Translation) avec Netfilter (iptables Linux) ;
  • utiliser un serveur DNS local et le configurer pour utiliser notre serveur comme upstream via le port 9000 (Unbound peut faire ça) ;
  • utiliser Socat pour rediriger des requêtes DNS locales vers le port 9000 de notre récursif.

Forcer l’utilisation de TCP

Plusieurs possibilités :

  • forcer l’utilisation de TCP dans le stub resolver ;
  • unbound est capable d’utliser un serveur upstream en utilisant uniquement TCP ;
  • utiliser un logicial spécialisé pour la ré-encapsulation DNS UDP↔UDP.

Résumé des montages possibles :

  1. stub resolver TCP → récursif
  2. stub resolver → unbound en mode forward TCP →  récursif
  3. stub resolver → dnsfwd (ou dns-tcp2udp) → récursif
  4. stub resolver → unbound → dnsfwd (ou dns-tcp2udp) → récursif (recommandé)

Unbound initie une connection TCP par requête ce qui a un impact négatif sur la latence des requêtes DNS. Nous avons obtenu de meilleurs résultats (dans le cadre du du chiffrement TLS indiqué plus bas) en réutilisant une même connection TCP pour plusieurs requêtes DNS avec dnsfwd (développé pour l’occasion). Le même problème se pose lorsque l’on force l’utilisation de TCP dans le stub resolver (de plus ce réglage peut être ignoré par certaines applications).

Forcer l’utilisation de TCP dans le stub resolver

  • pour les systèmes utilisant la Libc de GNU (GNU/Linux mais pas Android), il est possible d’utiliser l’option use-vc dans le fichier /etc/resolv.conf  (cette option n’est disponible qu’à partir de glibc 2.14 ; dans Debian, elle disponible depuis Jessie ; pour Ubuntu, elle est disponible depuis 12.04) ;
  • pour la Libc d’OpenBSD, cette option s’appelle tcp ;
  • les autres Libc que nous avons regardés n’ont pas d’option similaire.

Défauts:

  • Certains logiciels (qui n’utilsent pas le stub resolver de la libc du système mais interprètent tout de même resolv.conf) peuvent ignorer cette configuration.
  • Une connexion TCP est établie par requête ce qui n’est pas très efficace.

Configuration avec unbound en mode forward TCP

server:
 tcp-upstream: yes
forward-zone:
 name: "."
 forward-addr: 80.67.188.188

Défauts :

  • initie une connexion TCP par requête DNS.

Ré-encapsulation DNS TCP↔UDP

Logiciels :

  • dnsfwd
    • prototype fonctionnel développé pour l’occasion ;
    • il manque certaines fonctionnalités pour pouvoir être considéré comme production-ready ;
  • Une solution alternative est dns-tcp2udp (que nous n’avons pas testé).

Chiffrer le DNS avec TLS

Le principe reste le même que précédemment mais en ajoutant un chiffrment TLS par stunnel ou socat.

Attention : Unbound est capable de faire du DNS/TLS nativement il ne vérifie le certificat X.509 distant. Dans une telle configuration, il est donc susceptible de subir une attaque MITM. Pour cette raison nous recommendons de gérer l’encapsulation TLS par Stunnel.

Résumé des montages possibles :

  1. stub resolver TCP → stunnel (ou socat) → récursif
  2. stub resolver → unbound en mode forward TLS → récursif (Attention : pas de vérification du certificat !)
  3. stub resolver → unbound en mode forward TCP →  stunnel (ou socat) → récursif
  4. stub resolver → dnsfwd (ou dns-tcp2udp) → stunnel (ou socat) → récursif (recommandé)
  5. stub resolver → unbound → dnsfwd (ou dns-tcp2udp) → stunnel (ou socat) → récursif (recommandé)

Voir recursive DNS over TLS over TCP 443 pour plus de détails.

Configuration unbound → stunnel (ou socat)

Attention : Unbound est capable de faire du DNS/TLS nativement il ne vérifie le certificat X.509 distant. Dans une telle configuration, il est donc susceptible de subir une attaque MITM. Pour cette raison nous recommandons de gérer l’encapsulation TLS par Stunnel.

Récupération du certificat

Le certificat actuel est :

-----BEGIN CERTIFICATE-----
MIIFYzCCA0ugAwIBAgIJAP3sZe6dzCxGMA0GCSqGSIb3DQEBCwUAMEgxCzAJBgNV
BAYTAkZSMRMwEQYDVQQIDApTb21lLVN0YXRlMQwwCgYDVQQKDANMRE4xFjAUBgNV
BAMMDTgwLjY3LjE4OC4xODgwHhcNMTYwOTI2MjI0MzMzWhcNMTgwOTI2MjI0MzMz
WjBIMQswCQYDVQQGEwJGUjETMBEGA1UECAwKU29tZS1TdGF0ZTEMMAoGA1UECgwD
TEROMRYwFAYDVQQDDA04MC42Ny4xODguMTg4MIICIjANBgkqhkiG9w0BAQEFAAOC
Ag8AMIICCgKCAgEAuIPaKHc6zgGFgdDxJPaw7hf63ytMGw0roFMlYOklC3uiFTp8
QLHA9NKTXWXEl0OBnaNerPsQpnoCR8UOf9pWKZa2kiLXQDvShsz9pHXzfLskRxOh
Fegk3m/lO7C8Hj6QI3leTm6naVdrWySaZ1K5RAx6kRwdUSZ08x/je4Vc1ZTe1Hbr
qYexvX94EJhrmIxA9u9q7RoRYAUbNR3h8QhotO6APYlsSsaDE2hkju4vjfz8/M4T
jSClvEn6Keto/UkB0Xno1jDvxxSqSansxOymha1JM5u4G95XfYKLpnebqpShGN0Y
UhUK26q8MVKCWAV6fEN4cDfofqGF+zGC/js8GyiZWP/qxuOf9QJWbs78oa0pQRS+
yO8W+F2ue0ND5gu89/VzoejfJO0MHiyl60g/548EGffCp4gCCSasV+bDbHrgctw1
8iQvnu5Thi7IbCFp7Sgfypj57Ryq/nmcipXSxxcm7g/ZP16V5+Bcy/u3JQox2OUv
WvvikbduUjN6Zx5qs5XBBVRqiqpHtyU8rHR23344ARHE+nf3XQZS+Sy9ItskAbPV
thpX33GfUslR1P9GOwBFewC64DtErqOrzyzCqWuLdBbvBGOnc9uD1hZdFJIX685O
nMkQThaiKWNFAJGL6zGyTxHAJ3Ipn3HgbpSeBLHVtA+EOLCa/ZQZYvsyVgcCAwEA
AaNQME4wHQYDVR0OBBYEFIjES3O/vxZcx1wJ3SFlhQLRz/+fMB8GA1UdIwQYMBaA
FIjES3O/vxZcx1wJ3SFlhQLRz/+fMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEL
BQADggIBAB7C5/+Ej4n4mZzvymZYqb3TgQcpTsiyqW0jQNs66e1zaI8u5Tce/tk9
X+G09CVPu7BYCgGe1t489mnUc+3AeVkw5kS7FHS/JldhV/i4pDs1b3z9FuiVvcmq
EJCOkkn2IDqvraQU3RP4356d89cz140VrR7l6dqh1bKT6C+u0Atd1HiGpyhBZvG3
9BS3qtyhLxCVUBjITvN3dK4/MLeW3oppUYvcqhusZI+XxfpML5DCLPP+MFLEFYt9
tqiwzBrbiAYH7B00h/PZRjNMdhA5jxFIKIaBM6iO6trGEC455tzMjI6OhFY5P5nE
UUjj+r8dwhpz88Lqsm6SFLqumMbSapsGdLkL4prvMz1Meph5WYetnCa9+op5xoyS
bMvae/kSOrmy43N+Zd5Uod2v9jBZsA8n87ykq+m80i2ZHG9GH654aHSTaNPptCYU
E9/YFzvwDWc9k6b0eT9rqNdgx8B4uZkNpE6kJBVCsJ38CLczqR3wawbE0cm/nkXi
Os4ifJ1NwlBMujJ7AnPXmATCTvOjiDgVkxgdnjWFjcdtv8J/iozrj6TOVvHRPGRo
RG8TjLQZWf0KtBF+dmaoujWoSt3kknWc6MSRTxMqygWL0mKsXz1xDqaIFhGY/Oau
LpOaxq75VIywhC0XSEAAnaxPBjajnU6Sixsr2EYtl9/4kQkdz+yd
-----END CERTIFICATE-----

Afin de s’assurer que le certificat est correct, il est préférable de passer par HTTPS.

Configuration de stunnel

Fichier de configuation pour stunnel en mode « client » :

setuid=stunnel4
setgid=stunnel4
pid=/var/run/stunnel4/dns.pid
CAfile=/etc/stunnel/dns.pem
output=/var/log/stunnel4/dns.log
client=yes
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1

[dns]
accept=127.0.0.1:1234
connect=80.67.188.188:443
verify=4

Utilisation de Socat

Alternativement, on peut utiliser socat à la place de stunnel :

sudo socat \
  TCP4-LISTEN:1234,bind=127.0.0.1,fork,nodelay,su=nobody \
  OPENSSL:80.67.188.188:443,verify=1,cafile=dns.pem,nodelay

Configuration de unbound

Unbound est configuré pour parler en TCP à un serveur upstream. Le serveur désigne est l’entrée locale du tunnel TLS :

server:
 tcp-upstream: yes
 do-not-query-localhost: no
forward-zone:
 name: "."
 forward-addr: 127.0.0.1@1234

Configuration du stub resolver

Finalement, il faut demander aux applications de parler à unbound (dans /etc/revolv.conf) :

nameserver 127.0.0.1

Et DNSSEC dans tout ça ?

La vérification DNSSEC permet de vérifier que la réponse n’a pas été modifiée/falsifiée mais ne permet

  1. ni d’empêcher la falsification ;
  2. ni d’empêcher la surveillance des requêtes DNS effectuées.

L’encapsulation du traffic DNS par TLS vers un serveurs récursif distant de confiance permet de coutourner de telles mesure de censure/survreillance sur le réseau utilisé. Par contre, il est toujours possible d’opérer ces attaques à la sortie de l’encapsulation TLS.