Pour pouvoir bloquer des domaines (publicité, phishing, etc.) directement au niveau dns ou passer outre des restrictions gouvernementales, une approche possible est l'utilisation d'un résolveur DNS personnel. Pour ce faire, le plus simple d'utilisation est d'utiliser Pi-Hole, que nous couplerons avec DNScrypt-proxy pour permettre le chiffrement des requêtes dns. Il sera nottament possible de résoudre les domaines utilisant DNSSEC.

La suite de ce billet porte essentiellement sur une installation et une configuration sous Archlinux, alors si vous utilisez une autre distribution vous aurez probablement à adapter cela.

Installation

Premièrement, procédez à l'installation des paquets php-fpm, nginx-mainline, dnscrypt-proxy depuis les dépôts officiels d'archlinux, puis installez nottament les paquets pi-hole-ftl, pi-hole-server depuis AUR à l'aide d'un enrobeur comme Yay.

Pour l'interface web de Pi-Hole il nous faudra également le paquet php-sqlite

Configuration

Nous allons configurer Pi-Hole qui fonctionnera avec nginx. Vous pouvez nottament utiliser un nom de domaine local accompagné d'un certificat https valide en utilisant mkcert.

Pihole

On édite le fichier /etc/php/php.ini et décommentez les lignes suivantes, cela activera les extensions requises.

[...]
extension=pdo_sqlite
[...]
extension=sockets extension=sqlite3
[...]

Ensuite on touche au fichier /etc/php/php-fpm.d/www.conf en modifiant la ligne d'écoute comportant un listen par :

listen = 127.0.0.1:9000

On continue en ajoutant les lignes suivantes dans /etc/nginx/nginx.conf :

gzip            on;
gzip_min_length 1000;
gzip_proxied    expired no-cache no-store private auth;
gzip_types      text/plain application/xml application/json application/javascript application/octet-stream text/css;
include /etc/nginx/conf.d/*.conf;

On peut maintenant copiez le fichier de configuration de nginx dans le répertoire approprié :

# mkdir /etc/nginx/conf.d
# cp /usr/share/pihole/configs/nginx.example.conf /etc/nginx/conf.d/pihole.conf

Enfin, on active les services nginx.service et php-fpm.service, puis on les démarre.

# systemctl enable nginx php-fpm
# systemctl start nginx php-fpm

Mot de passe :

On définie un mot de passe pour l'administration de Pi-Hole

pihole -a -p

Domaine local (optionnel) :

On vérifie que dans le fichier /etc/hosts on a les lignes suivantes :

127.0.0.1 localhost
127.0.0.1 pi.hole

On utilise maintenant un domaine personnalisé pour Pi-Hole et un certificat généré à l'aide de mkcert. Je ne traite pas ici la création d'un certificat. Se référer au billet à ce sujet. Ainsi on édite le fichier de configuration de nginx /etc/nginx/conf.d/pihole.conf pour avoir quelque chose comme ceci. En assumant que {user} est votre nom d'utilisateur et {hostname} le nom de votre machine.

server {
    listen 80;
    listen [::]:80;
    server_name pi.hole;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
	server_name pi.hole;

	root /srv/http/pihole/admin;
	autoindex off;

	error_page 404 ../pihole/index.php;

	index pihole/index.php index.php index.html index.htm;

	ssl_certificate /home/{user}/.mkcert/localhost+9.pem;
	ssl_certificate_key /home/{user}/.mkcert/localhost+9-key.pem;
	ssl_trusted_certificate /etc/ssl/certs/mkcert_root_{hostname}.pem;
	ssl_session_timeout 5m;
	ssl_session_cache shared:SSL:5m;
	ssl_prefer_server_ciphers On;
	ssl_protocols TLSv1.2;
	ssl_ciphers 'EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA:!CAMELLIA256-SHA:!AES256-SHA:!CAMELLIA128-SHA:!AES128-SHA';
	ssl_dhparam /etc/ssl/private/dhparam4096.pem; # Create it with `openssl dhparam -out /etc/ssl/private/dhparam4096.pem 4096`
	add_header Strict-Transport-Security max-age=15768000; # six months
	gzip off;

	location ~ \.php$ {
		include fastcgi.conf;
		fastcgi_intercept_errors on;
		fastcgi_pass  127.0.0.1:9000;
		fastcgi_param SERVER_NAME $host;
	}
	location / {
		root /srv/http/pihole/admin;
		index index.php index.html index.htm;
		add_header X-Pi-hole "The Pi-hole Web interface is working!";
		add_header X-Frame-Options "DENY";
		add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
	}
	location ~ ../\.ttf {
		add_header Access-Control-Allow-Origin "*";
	}
	location ~ ../admin/\. {
		deny all;
	}
	location ~ ../\.ht {
		deny all;
	}
}

DNSCrypt

Pour utiliser le service dnscrypt-proxy, on va changer le serveur DNS parent dans l'interface d'administration (normalement accessible sur votre nouveau domaine, tel https://pi.hole/) comme suit, en décochant tout autre utilisation de serveurs DNS :

Paramètres DNS sur l'interface de Pi-Hole

On édite le fichier /etc/dnscrypt-proxy/dnscrypt-proxy.toml de façon à ce qu'il contienne ces lignes. Vous pouvez modifier cette configuration comme vous le souhaitez ☺

[...]

listen_addresses = ['127.0.0.1:5300', '[::1]:5300']
ipv4_servers = true
ipv6_servers = true

### On utilise seulement dnscrypt, pas de dns over https

dnscrypt_servers = true
doh_servers = false

### Seulement des serveurs qui ne log pas, sans filtrage et utilisant dnssec

require_dnssec = true
require_nolog = true
require_nofilter = true
block_ipv6 = false

### Un cache dns local

cache = true
cache_size = 2048
cache_min_ttl = 600
cache_max_ttl = 86400
cache_neg_min_ttl = 60
cache_neg_max_ttl = 600

### Si vous voulez enregistrer un fichier de log

file = '/var/log/dnscrypt-proxy/query.log'
format = 'tsv'
ignored_qtypes = ['DNSKEY', 'NS']

### Source des serveurs DNS

[sources]
   [sources.'public-resolvers']
   urls = ['https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v2/public-resolvers.md', 'https://download.dnscrypt.i>
   cache_file = '/var/cache/dnscrypt-proxy/public-resolvers.md'
   minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3'
   refresh_delay = 72
   prefix = ''

[...]

On modifie /etc/pihole/setupVars.conf en commentant toutes les lignes PIHOLE_DNS= en ajoutant un # au début de chaque ligne.

De même pour le fichier sudo nano /etc/dnsmasq.d/01-pihole.conf, on commente les lignes server=... en mettant un # au début.

Dorénavant, on peut activer et démarrer le service dnscrypt.

DNSSEC

Pour terminer, on active l'utilisation de DNSSEC comme suit.

echo "proxy-dnssec" >> /etc/dnsmasq.d/02-dnscrypt.conf

FIN !

On termine de lancer tout les services.

# systemctl enable dnscrypt-proxy.service
# systemctl start dnscrypt-proxy.service
# systemctl enable pihole-FTL.service
# systemctl start pihole-FTL.service

Changez le serveur DNS que vous utilisez. Par exemple dans NetworkManager :

IPv4
IPv6

Et… c'est terminé 😋

Vous pouvez maintenant vérifier la bonne utilisation de serveurs supportant DNSCrypt et la validation DNSSEC à l'aide des sites suivants :

Sources :