Project

General

Profile

Actions

DNS récursif Ouvert DoH DoT & haute disponibilité

45.67.81.23 - dns.aquilenet.fr

Aquilenet propose deux serveurs DNS ouverts cf https://www.aquilenet.fr/services/dns/
On a mis aussi un DNS ouvert sur l'IP 45.67.81.23 car facile à retenir, avec l'adresse de dns.aquilenet.fr (voir http://dns.aquilenet.fr) . Nous en avons profité pour ajouter DoH et DoT et d'avoir cette adresse en IP Virtuelle partagée entre pan1 et pan2.
Cette IP virtuelle est portée par Keepalived sur pan1 le primaire et pan2 le secondaire. Si le démon Keepalived est arrêté sur pan1, l'ip bascule sur pan2. Si on redémarre le démon sur pan1, ce dernier reprend l'IP: pratique pour les mises à jour, le service continue à fonctionner.

Une configuration spécifique pour l'ip de ce vlan a été fait sur les switches et les hyperviseurs, ce qui permet au final à pan1 et pan2 d'avoir une seconde interface qui porte l'IP virtuelle, elle n'est pas abordée dans ce document.

Configurations communes à pan1 et pan2

Nginx

  • /etc/nginx/site-avaible
server {
  listen       443 ssl http2 default_server;
  listen       [::]:443 ssl http2 default_server;
  server_name dns.aquilenet.fr; 
  root /var/www/dns.aquilenet.fr; 

  include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


  server_tokens off;

  ssl_session_cache shared:SSL:10m;
#  resolver 127.0.0.1 valid=300s;            # Replace with your local resolver
  resolver_timeout 5s;
  # HTTP Security Headers
  add_header X-Frame-Options DENY;
  add_header X-Content-Type-Options nosniff;
  add_header X-XSS-Protection "1; mode=block";
  add_header Strict-Transport-Security "max-age=63072000";
    ssl_certificate /etc/letsencrypt/live/dns.aquilenet.fr/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/dns.aquilenet.fr/privkey.pem; # managed by Certbot
location / {
  try_files $uri /index.htm;
} 
  location /dns-query {
    proxy_pass       http://localhost:1443/dns-query;
    proxy_set_header Host      $host;
    proxy_set_header X-Real-IP $remote_addr;
  }

}

Unbound



AppArmor

  • /etc/apparmor.d/usr.sbin.unbound
    décomenter:
    include

  • /etc/apparmor.d/local/usr.sbin.unbound

    /etc/letsencrypt/archive/** r,
    /etc/letsencrypt/live/** r,
    

    appliquer avec: apparmor_parser -r /etc/apparmor.d/usr.sbin.unbound

Iptables

# Web
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -i eth0 -p tcp --dport 443 -j ACCEPT
-A INPUT -d 45.67.81.23 -p tcp -m tcp --dport 53 -j dns_limit
-A INPUT -d 45.67.81.23 -p udp -m udp --dport 53 -j dns_limit
-A INPUT -d 45.67.81.23 -p tcp -m tcp --dport 443 -j dns_limit
-A INPUT -d 45.67.81.23 -p tcp -m tcp --dport 853 -j dns_limit

Configurations spécifiques

Génération du certificat SSL sur Hades

certbot --apache --agree-tos --email sysop@aquilenet.fr -d dns.aquilenet.fr
chgrp bind /etc/letsencrypt/live/dns.aquilenet.fr/privkey.pem
chmod 0640 /etc/letsencrypt/live/dns.aquilenet.fr/privkey.pem
openssl dhparam -out /etc/bind/dhparam.pem 4096

Copie du certificat sur gaia

  • /etc/letsencrypt/renewal-hooks/post/sync-cert.sh ~~~ #!/bin/bash rsync -aPHSA /etc/letsencrypt/archive/dns.aquilenet.fr gaia:/etc/letsencrypt/archive/ ~~~

Clée sdns (auth par épinglage de la clé / key pining)

  • A partir de la clé ~~~ hades|19:21:08|:~# openssl rsa -in /etc/letsencrypt/live/dns.aquilenet.fr/privkey.pem -outform der -pubout | openssl dgst -sha256 -binary | openssl enc -base64 writing RSA key lBk09CRIPJ+J4O9rmbvJkEiGYoH5r9rxOIQdxkYxyII= ~~~
  • ou à partir du certificat ~~~ hades|19:22:21|:~# openssl x509 -in /etc/letsencrypt/live/dns.aquilenet.fr/cert.pem -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64 writing RSA key lBk09CRIPJ+J4O9rmbvJkEiGYoH5r9rxOIQdxkYxyII= ~~~

Keepalived

Hades Master

  • /etc/keepalived/keepalived.conf
global_defs {
  notification_email {
    sysop@aquilenet.fr
  }
  notification_email_from vrrp-dns@aquilenet.fr.fr
  smtp_server localhost
  smtp_connect_timeout 30
}

vrrp_instance DNS {
  state MASTER 
  interface eth0
  virtual_router_id 101 
  priority 100
  advert_int 2
  smtp_alert
  unicast_src_ip 185.233.100.16 
  unicast_peer {
    185.233.100.2
  }
  virtual_ipaddress {
    45.67.81.23/32 dev eth1 scope global # VIP
  }
}

Gaia Slave

  • /etc/keepalived/keepalived.conf
global_defs {
  notification_email {
    sysop@aquilenet.fr
  }
  notification_email_from vrrp-dns@aquilenet.fr.fr
  smtp_server localhost
  smtp_connect_timeout 30
}

vrrp_instance DNS {
  state BACKUP
  interface eth0
  virtual_router_id 101
  priority 50
  advert_int 2
  smtp_alert
  unicast_src_ip 185.233.100.2
  unicast_peer {
    185.233.100.16
  }
  virtual_ipaddress {
    45.67.81.23/32 dev eth1 scope global # VIP
  }
}

Validation

  • test du service

    dig +short dns.aquilenet.fr @45.67.81.23 
    45.67.81.23
    dig +https +short dns.aquilenet.fr @45.67.81.23      
    45.67.81.23
    dig +tls +short dns.aquilenet.fr @45.67.81.23      
    45.67.81.23
    
  • bascule keepalived

sur hades: systemctl stop keepalived
sur gaia: ip a |grep /32doit donner "inet 45.67.81.23/32 scope global eth1"
http://dns.aquilenet.fr/host permet de savoir quel est le serveur qui porte l'IP virtuelle

Indexes de serveurs DNS ouverts:

https://github.com/curl/curl/wiki/DNS-over-HTTPS#publicly-available-servers <= fait
https://diyisp.org/dokuwiki/doku.php?id=technical:dnsresolver <= fait
https://diyisp.org/dokuwiki/doku.php?id=technical:dnsresolver <= fait
https://dnsprivacy.org/public_resolvers/

Ressources

https://www.bortzmeyer.org/doh-bortzmeyer-fr-policy.html
https://www.bortzmeyer.org/7858.html
https://kb.isc.org/docs/aa-01386

Updated by sacha 3 months ago · 18 revisions