The Daily Shaarli
Les DNS adapters (anciennement nommés I/O adapters, de mémoire), qui sont apparus avec la version 1.4 d'OpenDNSSEC, lui permettent de se comporter comme un serveur DNS c'est-à-dire que, plutôt que d'avoir le fichier de zone à signer sur un support de stockage, OpenDNSSEC peut très bien la recevoir depuis un serveur DNS, via un transfert de zone tout à fait standard dans DNS. De même, plutôt que d'écrire la zone signée sur le stockage, OpenDNSSEC peut la distribuer à un serveur DNS qui, lui, la servira à tout l'Internet.
En gros, le tech modifie le fichier de zone et la recharge dans son serveur de noms interne qui fait autorité habituel (BIND, nsd, knot, etc.). Celui-ci envoie une notification à OpenDNSSEC. OpenDNSSEC effectue un transfert de la zone depuis le serveur DNS interne puis signe la zone puis envoie une notification au serveur DNS qui fait autorité exposé sur le net. Ce serveur récupère la zone signée auprès d'OpenDNSSEC en effectuant un transfert de zone.
Cela permet deux choses :
ods-signer sign) : une équipe, pourquoi pas celle dédiée à la sécurité, met en place, maintient et debug DNSSEC et le reste des techs utilise le DNS comme à son habitude, comme on le voit en cours : modif' du fichier de zone et faire relire son contenu par un serveur de noms bien connu (BIND, la plupart du temps, malheureusement).Évidemment, il est tout à fait possible de mixer les I/O adapters et d'utiliser le stockage comme entrée du signataire DNSSEC et un transfert de zone en sortie du même signataire (configuration du master furtif) ou un transfert de zone en entrée et une écriture sur le stockage en sortie.
Je me suis fait une petite maquette : dns1/198.18.0.1/Debian+BIND9 -> opendnssec/198.18.0.2/Debian+OpenDNSSEC -> dns2/198.18.0.3/Debian+nsd. dns2 est la seule machine accessible depuis Internet. Oui, normalement dns2 devrait être dans un réseau IP différent de dns1.
sudo apt-get install bind9
sudo mkdir -p /var/named/zones/master
sudo chown -R bind:root /var/named
sudo chown -R 555 /var/named
Conf' (/etc/bind/named.conf.local) :
zone "guiguishow.example." IN {
type master;
file "/var/named/zones/master/db.guiguishow.example";
allow-transfer { 198.18.0.2; };
notify yes;
also-notify { 198.18.0.2; };
};
La ligne allow-notify est importante : par défaut un serveur de noms envoie une notification uniquement aux machines désignées par un enregistrement NS dans la zone. Comme dit, dns1 et OpenDNSSEC n'apparaissent pas dans les enregistrements NS de guiguishow.example.
Pour le contenu du fichier de zone, c'est du classique :
$ORIGIN guiguishow.example.
$TTL 3600
guiguishow.example. IN SOA dns1.guiguishow.example. dnsmaster.guiguishow.example. 2017041200 7200 3600 604800 3600
@ IN NS dns2
dns2 IN A 198.18.0.3
Oui, mon enregistrement SOA est parfaitement valide : le champ mname, « dns1.guiguishow.example » dans cet exemple, doit indiquer le nom de n'importe quel serveur DNS qui fait autorité sur la zone. Par convention, on y met la machine qui est la source de la zone, c'est-à-dire le serveur sur lequel sont effectuées les modifications. Il n'a jamais été question que ce champ contienne forcément le premier NS public de la zone et encore moins que ce nom soit utilisé dans le processus de résolution d'un nom.
Le début ne change pas d'une installation OpenDNSSEC classique.
sudo apt-get install opendnssec opendnssec-enforcer-sqlite3 softhsmsudo softhsm --init-token --slot 0 --label "OpenDNSSEC"
Puis, on configure le DNS adapters. La première étape est d'indiquer sur quelle-s interface-s et quel port réseau écouter (par défaut : port 53 sur toutes les interfaces) en décommentant le Listener dans conf.xml :
<Listener>
<Interface>
<!-- <Address></Address> -->
<Port>53</Port>
</Interface>
</Listener>
Sans ça, l'erreur « no dnshandler/listener configured, but zones are configured with dns adapters: notify and zone transfer requests will not work properly » apparaît dans les logs.
Ensuite, on configure les serveurs DNS source (dns1) et destination (dns2) dans le fichier /etc/opendnssec/addns.xml :
<?xml version="1.0" encoding="UTF-8"?>
<Adapter>
<DNS>
<Inbound>
<!-- Address of host to request XFR from -->
<RequestTransfer>
<Remote>
<Address>198.18.0.1</Address>
</Remote>
</RequestTransfer>
<!-- Allow NOTIFY messages from host -->
<AllowNotify>
<Peer>
<Prefix>198.18.0.1</Prefix>
</Peer>
</AllowNotify>
</Inbound>
<Outbound>
<!-- Provide XFR to host -->
<ProvideTransfer>
<Peer>
<Prefix>198.18.0.3</Prefix>
</Peer>
</ProvideTransfer>
<!-- Send NOTIFY messages to host -->
<Notify>
<Remote>
<Address>198.18.0.3</Address>
</Remote>
</Notify>
</Outbound>
</DNS>
</Adapter>
Puis, on ajoute notre zone dans /etc/opendnssec/zonelist.xml :
<?xml version="1.0" encoding="UTF-8"?>
<ZoneList>
<Zone name="guiguishow.example">
<Policy>default</Policy>
<SignerConfiguration>/var/lib/opendnssec/signconf/guiguishow.example.xml</SignerConfiguration>
<Adapters>
<Input>
<Adapter type="DNS">/etc/opendnssec/addns.xml</Adapter>
</Input>
<Output>
<Adapter type="DNS">/etc/opendnssec/addns.xml</Adapter>
</Output>
</Adapters>
</Zone>
</ZoneList>
On constate qu'il est tout à fait possible d'avoir plusieurs serveurs DNS en entrée, chacun servant une ou plusieurs zones. Même chose en sortie.
Enfin, on met en place les politiques de signature :
sudo ods-ksmutil setup
sudo apt-get install nsd
sudo mkdir -p /var/named/zones/slave
sudo chown -R nsd:root /var/named
sudo chmod -R 555 /var/named
sudo chmod u+w /var/named/zones/slave
Conf' (/etc/nsd/nsd.conf) :
zone:
name: "guiguishow.example."
zonefile: "/var/named/zones/slave/db.guiguishow.example"
allow-notify: 198.18.0.2 NOKEY
request-xfr: 198.18.0.2 NOKEY
Évidemment, il faut veiller à ne jamais autoriser un transfert de zones entre dns1 et dns2, sinon ça va plutôt mal se passer au moins jusqu'à ce qu'OpenDNSSEC notifie un serial plus important et que dns2 récupère cette zone signée en conséquence.
On lance nsd sur dns2 :
sudo systemctl restart nsd
On lance OpenDNSSEC :
sudo systemctl restart opendnssec-enforcer.service opendnssec-signer.service
On lance BIND sur dns1 :
sudo systemctl restart bind9
dns2 sert bien une zone signée \o/ :
$ dig @::1 +dnssec SOA guiguishow.example
; <<>> DiG 9.9.5-9+deb8u10-Debian <<>> @::1 +dnssec SOA guiguishow.example
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41788
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 2, ADDITIONAL: 3
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;guiguishow.example. IN SOA
;; ANSWER SECTION:
guiguishow.example. 3600 IN SOA dns1.guiguishow.example. dnsmaster.guiguishow.example. 2017041201 7200 3600 604800 3600
guiguishow.example. 3600 IN RRSIG SOA 8 2 3600 20170426074413 20170412150401 18114 guiguishow.example. MgP6rIs4Uf/SDAzFyJnw8w+JWh0EgxrFmbdlpMZxhdaQd/9NOsf07/mg JxV1qQ42xIAMUziF5wn0yX0DOqIr6S2jE+lGLWsRHB2swUQ1eaBsTKlV cLpRoRz6J1XtAha90OggjmGdL8EHMNczdjeYzmXwSAtpFsj20A+CcxYk LfM=
;; AUTHORITY SECTION:
guiguishow.example. 3600 IN NS dns2.guiguishow.example.
guiguishow.example. 3600 IN RRSIG NS 8 2 3600 20170426104704 20170412150401 18114 guiguishow.example. dISERsUbOSL03zWzTKMuoATfYws21RhxekZRjRbn5oFe/HIDxqCar2DQ hj5JxnBwQV9/Kjwa2/ZASBhUqEmzQe3ZCrvPdbTQUFCtoHuRSXtuJMB8 cHot6AuM1MJRkwPEwnem+F9excJR9vX4MRY08+pYEvKHHbz91ysnGkFP ESY=
;; ADDITIONAL SECTION:
dns2.guiguishow.example. 3600 IN A 198.18.0.3
dns2.guiguishow.example. 3600 IN RRSIG A 8 3 3600 20170427015329 20170412150401 18114 guiguishow.example. DSgNZI7MG53qMecbXT+bU73qGY8uu0QTxYrcTrjwFiGU5deUot8CKkEz SNJ/ahBCfpexdpf4IffjHqAw527o2O6OUdqNj6VwYj/wScgdWSZJQhcO wtmTyZwyC1jWviiaVTX/e24coQMFickOjYOSBqiSDeNqe7sPOkT7XHgm qlE=
;; Query time: 0 msec
;; SERVER: ::1#53(::1)
;; WHEN: Wed Apr 12 18:05:19 CEST 2017
;; MSG SIZE rcvd: 667
Attention : la commande ods-signer sign n'a pas d'effet lorsqu'elle est utilisée sur une zone qui utilise un adaptateur DNS en entrée car OpenDNSSEC n'effectue pas un transfert de zone de sa propre initiative. Pour ce faire, il faut soit redémarrer OpenDNSSEC (ce qui est inapproprié !), soit envoyer une notification depuis le serveur DNS interne (exemple avec BIND : sudo rndc reload <nom_zone> ; exemple avec nsd : sudo nsd-control notify <nom_zone>).
In this paper (PDF) delivered at the CODASPY’17 conference in March, Kranch explains that the TCP/IP headers of a Netflix HTTPS stream provide a 99.5 per cent content fingerprint.
Yes, HTTPS is meant to provide privacy, and no, Netflix isn't doing anything dumb like putting movie titles in headers: the variable bitrate (VBR) encoding happens to yield up predictable behaviour, particularly in how the byte-range portion of HTTP GET commands perfectly aligns with individual video segment boundaries.
[…]
Kranch offers a couple of ideas to fix the issue. For example, he says, “the browser could average the size of several consecutive segments and send HTTP GETs for this average size. As an alternative approach, the browser could randomly combine consecutive segments and send HTTP GETs for the combined video data.”
Joli mais sans surprise (le chiffrement ne résout pas tous les problèmes, quelle surprise). :)
Via #ttnn
Article très intéressant qui part d'un cas d'usage concret pour explorer le traitement des trames réseaux par Linux.
Un pont réseau (aussi appelé « commutateur » ou « switch ») permet d’interconnecter plusieurs segments Ethernet ensemble. C’est un élément d’infrastructure banal et implémenté de longue date par Linux.
Un usage typique est exposé dans la figure ci-dessous. L’hyperviseur exécute trois machines virtuelles. Chacune d’elle est attachée au pont br0 (représenté par un segment horizontal). L’hyperviseur dispose de deux interfaces réseau physiques :
- eth0 est attachée à un réseau public fournissant divers services aux machines virtuelles (DHCP, DNS, NTP, routeurs vers Internet, …). Elle fait partie du pont br0.
- eth1 est attachée à un réseau d’infrastructure fournissant divers services à l’hyperviseur (DNS, NTP, gestion de la configuration, routeurs vers Internet, …). Elle ne fait pas partie du pont br0.
Dans une telle configuration, il est raisonnable de penser que les machines virtuelles peuvent accéder aux ressources du réseau public sans être capable d’atteindre les ressources du réseau d’infrastructure (y compris les ressources hébergées par l’hyperviseur lui-même, comme le serveur SSH). En d’autres mots, la séparation entre le domaine vert et le domaine violet doit être totale. Ce n’est pas le cas. Depuis n’importe quelle machine virtuelle […]
[…]
Une autre méthode est de configurer arp_ignore à la valeur 2 pour l’interface du pont. Le noyau ne répondra aux requêtes ARP que si l’adresse IP cible est configurée sur l’interface entrante. Comme l’interface du pont n’a pas d’IP, cela revient à ignorer toute les requêtes. […] À noter que désactiver le traitement des requêtes ARP ne dispense pas d’appliquer une méthode spécifique à IPv4. Un utilisateur peut en effet ajouter manuellement une entrée dans son cache ARP […] Étant donné que Linux est assez libéral sur les adresses MAC autorisées, il n’est même pas nécessaire de deviner l’adresse MAC […]
[…]
Dans l’exemple ci-dessus, la machine virtuelle reçoit des réponses ICMP car celles-ci sont routées à travers le réseau d’infrastructure vers Internet (c’est-à-dire que l’hyperviseur a en route par défaut une passerelle qui va également faire du NAT vers Internet). Quand ce n’est pas le cas, la communication ne peut se faire que dans un seul sens. Cela permet toujours de faire quelques dégâts dont des dénis de service.
De plus, si l’hyperviseur est également un routeur, les machines virtuelles peuvent atteindre n’importe quelle machine du réseau d’infrastructure, exposant ainsi certains nœuds peu protégés tels que des PDU disposant d’un agent SNMP. L’attaquant peut aussi forger son adresse IP pour contourner certains mécanismes d’authentification.
