/ Linux

Déclaration des empreintes SSH dans le DNS avec SSHFP

Il est possible depuis quelques années de publier les empreintes des clés SSH dans le DNS grâce aux enregistrements SSHFP (RFC4255). Ça permet aux clients de vérifier les empreintes via le DNS au moment de l'authentification et ainsi éviter ce message que tout sysadmin connaît par coeur :

The authenticity of host '[hostname.domain.tld]:xxxxx ([xx.xx.xx.xx]:xxxxx)' can't be established.
ECDSA key fingerprint is SHA256:XJ604zOO3doHr459ozM+eHswTcDlbgTJ4pSwGGcp1j8.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[hostname.domain.tld]:xxxxx ([xx.xx.xx.xx]:xxxxx)' (ECDSA) to the list of known hosts.

Pour suivre cette article, vous devez avoir configuré un serveur DNSSEC pour pouvoir y publier les clés SSH de vos serveurs. Si ce n'est pas le cas, vous pouvez aller voir mon tutoriel sur la mise en place d'un serveur DNS sécurisé avec DNSSEC disponible sur mondedie.fr.

Nous allons dans un premier temps récupérer les empreintes avec la commande ssh-keygen (à exécuter sur le serveur distant) :

ssh-keygen -r $(hostname --fqdn).

Vous devriez avoir quelque chose comme ça :

hostname.domain.tld. IN SSHFP 1 1 35a45b718b3c7a0030a8da396c1c24e7f920c1c0
hostname.domain.tld. IN SSHFP 1 2 784dda59431f3bbf4dca78845c5c957a31294ecde3ffe50a252b74ba8716fa52
hostname.domain.tld. IN SSHFP 2 1 29eb39d8b59bd0f3d9b44ecb0c5e7fb5ef0e5303
hostname.domain.tld. IN SSHFP 2 2 4fc839751ff94bdfad3064fbacfae4e7efe901b57aad35fb03cce1d78a56b3df
hostname.domain.tld. IN SSHFP 3 1 5a8645290413b085725c5e593003a1ba9cb59897
hostname.domain.tld. IN SSHFP 3 2 5c9eb4e3338eddda07af8e7da3333e787b304dc0e56e04c9e294b0186729d63f
hostname.domain.tld. IN SSHFP 4 1 a5207d11eee6ae1af17d0687cd95b69ae67ecc46
hostname.domain.tld. IN SSHFP 4 2 a20778344e5d99b09a708d50d1b9847a1791d247c751a740faf019025913b2e5

Un enregistrement SSHFP s'organise comme ceci :

  • Domaine : FQDN (domaine complètement qualifié) lié à l'empreinte
  • Algorithme : Algorithme de la clé publique.
    • 1 = RSA
    • 2 = DSS
    • 3 = ECDSA (non supporté par OpenSSH v5)
    • 4 = Ed25519 (depuis OpenSSH v6.7)
  • Type d'empreinte : Type de hash utilisé pour l'empreinte.
    • 1 = SHA-1
    • 2 = SHA-256

Si vous êtes le seul à vous connecter à votre serveur, inutile de prendre l'ensemble des enregistrements SSHFP, prenez seulement ceux ayant le même algorithme que votre clé SSH.

Voila maintenant que vous avez ajouté les enregistements dans votre fichier de zone, il faut maintenant configurer un résolveur local validant les signatures DNSSEC. Personnellement j'ai choisi bind 9.10, question d'habitude, mais Ubound fait très bien le job aussi.

Korben a fait [un article dessus](http://korben.info/installer-serveur dns-unbound.html), n'hésitez pas à jeter un coup d'oeil si vous êtes sous Windows. Par contre lors de l'installation, il est préférable de cocher la case "DLV - dlv.isc.org" pour activer la validation « Lookaside » permettant d'utiliser le registre de l'ISC comme solution de fallback. Je ne vais pas m'étendre sur le sujet, vous pouvez aller voir l'article de Stéphane Bortzmeyer qui traite du sujet.

Voila la configuration de mon résolveur local :

acl goodclients {
    # Autoriser les équipements du réseau local à requêter le serveur DNS
    # 192.168.1.0/24;
    localhost;
    localnets;
};

options {
    directory "/var/named";
    pid-file "/run/named/named.pid";

    listen-on { any; };
    auth-nxdomain no;
    recursion yes;

    dnssec-enable yes;
    dnssec-validation auto;
    dnssec-lookaside auto;

    allow-query { goodclients; };
    allow-recursion { goodclients; };
    allow-transfer { none; };
    allow-update { none; };

    version none;
    hostname none;
    server-id none;
};

La configuration parle d'elle même, c'est un simple serveur dns récursif validant les signatures DNSSEC. Vous pouvez autoriser les équipements du réseau local à requêter le serveur DNS, comme ça tout le monde peut en profiter à la maison ^^

Pour vérifier que notre résolveur valide bien les enregistrements DNSSEC, on va utiliser la commande dig :

dig +noall +dnssec +comments SSHFP hostname.domain.tld

Si votre serveur valide bien les signatures DNSSEC, vous devriez avoir « ad » dans la liste flags de la requête, comme ceci :

;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23981
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 7, AUTHORITY: 3, ADDITIONAL: 6

Si vous n'avez pas dig, vous pouvez utiliser ce site : http://dnssec.vs.uni-due.de/

On a preque terminé, il nous reste plus qu'à configurer SSH (côté client), modifier la directive « VerifyHostKeyDNS » dans /etc/ssh/ssh_config :

Host hostname.domain.tld
    VerifyHostKeyDNS yes
    # ...

Et pour finir, ajouter l'adresse du résolveur local dans le fichier /etc/resolv.conf :

nameserver 127.0.0.1

Attention ce fichier peut-être écrasé par le network manager si vous utilisez DHCP. Regardez la documentation de votre distribution pour préserver les paramètres DNS via netctl ou dhcpcd par exemple.

Sous Archlinux : https://wiki.archlinux.org/index.php/Resolv.conf#Preserve_DNS_settings

Sinon la solution la plus simple, c'est d'ajouter l'attribut « immutable » au fichier resolv.conf :

chattr +i /etc/resolv.conf

Sous Windows c'est ici qu'il faut spécifier l'adresse :

Windows DNS

Voila on a terminé, il nous reste plus qu'à tester tout ça. Connectez-vous à votre serveur avec SSH en mode verbose et regardez le debug. Normalement vous devriez être connecté sans message d'avertissement (vérifier qu'il n'existe pas d'entrée dans le fichier known_hosts correspondant à votre seveur).

Dans le debug, les lignes suivantes doivent apparaître :

debug1: Connecting to hostname.domain.tld [xx.xx.xx.xx] port xxxxx.
debug1: Connection established.
...
debug1: Server host key: ecdsa-sha2-nistp256 SHA256:XJ604zOO3doH...
debug1: found X secure fingerprints in DNS
debug1: matching host key fingerprint found in DNS
...
debug1: Authentication succeeded (publickey).

Authenticated to hostname.domain.tld ([xx.xx.xx.xx]:xxxxx).

SSH a bien trouvé les empreintes dans le DNS, on est donc sûr de l'identité du serveur, l'authentification peut se faire en toute sécurité.

Déclaration des empreintes SSH dans le DNS avec SSHFP
Share this