Ce qui est écrit dans le fichier .ssh / known_hosts


Chaque fois que nous nous connectons via le protocole ssh au serveur, le client ssh vérifie si la clé publique de ce serveur correspond à celle qui était la dernière fois (au moins il recommande de faire la norme ssh). Dans OpenSSH, une liste des clés de serveur connues est stockée dans le fichier known_hosts. Sous katom brièvement sur quoi et comment exactement y est stocké.

Toutes les expériences ont été menées sur Linux (Debian / Mint / Ubuntu). Je ne peux pas garantir l'emplacement et le contenu des fichiers dans d'autres systèmes d'exploitation.

Lorsque vous vous connectez au serveur ssh pour la première fois, nous voyons quelque chose comme ceci:
L'authenticité de l'hôte '192.168.0.2 (192.168.0.2)' ne peut pas être établie.
L'empreinte digitale de la clé RSA est SHA256: kd9mRkEGLo + RBBNpxKp7mInocF3 / Yl / 0fXRsGJ2JfYg.
Voulez-vous vraiment continuer à vous connecter (oui / non)?
Si vous acceptez, la ligne suivante sera ajoutée au fichier ~ / .ssh / known_hosts:
| 1 | CuXixZ + EWfgz40wpkMugPHPalyk = | KNoVhur7z5NAZmNndtwWq0kN1SQ = ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCeiF4OOOUhWvOYrh / e4q91 + iz + i9S0s3M2LPq + GAhRlhKt5vKyEVd6x6m26cc98Y + SQXnCB9GWeVYk8jlFHEXnY4YWeWLDwXIhHBJYt5yz3j5Wkg95x + mPvO9FLSBk / Al2GbH5q6F + hZIlLmO6ciISmX4TtcG1sw4SwoTADrrhdM0OJd + c5CU8iqCbc6PznYbLZXCvqPZTWeSbTLUcUu1Ti + 7xGwT8DF + tIyLFcU + zxd0QnwJIbNvewkHs0LsMOWFVPz / Nd0XiVXimX + ugCDBZ / 4q8NUwH9SGzCMAvnnr + D1I8X2vhSuRsTsQXL5P3vf8elDxPdDrMJzNtlBCbLWzV
Ici, trois éléments sont écrits avec un espace: un hachage au nom du serveur, le nom de l'algorithme asymétrique utilisé et la clé publique du serveur. Prenons-les à part.

Et si vous lisez les instructions
En fait, selon le manuel d'Ubunt, il peut y avoir 2 champs supplémentaires, également séparés par des espaces:
  • au début de la ligne, il peut y avoir une marque «@ cert-autorité» ou «@revoked», ce qui signifie, respectivement, que la clé publique de l'AC est écrite sur cette ligne ou que cette clé a été révoquée et ne peut pas être utilisée.
  • il peut y avoir un commentaire arbitraire à la fin de la ligne


Nom du serveur


Dans l'exemple, le hachage au nom du serveur (hôte) ressemble à ceci:
| 1 | CuXixZ + EWfgz40wpkMugPHPalyk = | KNoVhur7z5NAZmNndtwWq0kN1SQ =
En fait, le nom d'hôte en texte clair ou un masque qui spécifie l'ensemble de noms valides peut être écrit ici. Mais mon nom de hachage par défaut est enregistré. L'enregistrement est divisé en 3 parties par le symbole "|". La première partie est l'algorithme de hachage. "1" correspond à HMAC-SHA1 (je n'en ai pas vu d'autres). La deuxième partie est le sel (clé pour HMAC). La troisième partie est le hachage lui-même (sortie HMAC).

Vérifier
from base64 import b64decode import hmac salt = b64decode("CuXixZ+EWfgz40wpkMugPHPalyk=") host = b'192.168.0.2' hash = hmac.HMAC(salt, host, 'sha1').digest() print(b64encode(hash).decode()) 

> 'KNoVhur7z5NAZmNndtwWq0kN1SQ ='

Algorithme asymétrique


La RFC-4253 répertorie 4 algorithmes asymétriques: ssh-dss (obligatoire par standard, mais considéré comme faible et désactivé par défaut depuis OpenSSH7.0), ssh-rsa (recommandé), pgp-sign-rsa (facultatif), pgp- sign-dss (facultatif). Par défaut, les clés des deux premiers types sont générées sous Linux pour les algorithmes de courbe elliptique non mentionnés dans le RFC. Ce dernier est préféré, mais le client peut sélectionner l'algorithme avec l'option HostKeyAlgorithms.

Comment vérifier l'empreinte digitale de la touche souhaitée (pas celle par défaut)
Cela peut être utile si, par exemple, lorsque vous entrez pour la première fois sur le serveur, vous souhaitez vérifier l'empreinte digitale de la clé et que vous ne connaissez que l'empreinte digitale de la clé ssh-rsa. Ensuite, vous pouvez vous connecter avec cette commande:
ssh root@192.168.0.2 -o HostKeyAlgorithms = ssh-rsa

Si vous devez également spécifier un algorithme de hachage de clé, vous pouvez utiliser l'option FingerprintHash. Par exemple, si seul md5 est connu de ssh-rsa, vous pouvez vous connecter comme ceci:
ssh root@192.168.0.2 -o HostKeyAlgorithms = ssh-rsa -o FingerprintHash = md5


Clé publique


La clé publique dans known_hosts est la même que celle enregistrée dans le fichier /etc/ssh/ssh_host_rsa_key.pub sur le serveur (remplacez le nom de l'algorithme utilisé au lieu de rsa). Si vous supprimez l'encodage Base64, le nom de l'algorithme et les composants clés réels seront de nouveau à l'intérieur.

Pourquoi ne pas supprimer Base64
 b'\x00\x00\x00\x07ssh-rsa\x00\x00\x00\x03\x01\x00\x01\x00\x00\x01\x01\x00\x9e\x88^\x0e8\xe5!Z\xf3\x98\xae\x1f\xde\xe2\xafu\xfa,\xfe\x8b\xd4\xb4\xb3s6,\xfa\xbe\x18\x08Q\x96\x12\xad\xe6\xf2\xb2\x11Wz\xc7\xa9\xb6\xe9\xc7=\xf1\x8f\x92Ay\xc2\x07\xd1\x96yV$\xf29E\x1cE\xe7c\x86\x16yb\xc3\xc1r!\x1c\x12X\xb7\x9c\xb3\xde>V\x92\x0fy\xc7\xe9\x8f\xbc\xefE- d\xfc\tv\x19\xb1\xf9\xab\xa1~\x85\x92%.c\xbar"\x12\x99~\x13\xb5\xc1\xb5\xb3\x0e\x12\xc2\x84\xc0\x0e\xba\xe1t\xcd\x0e%\xdf\x9c\xe4%<\x8a\xa0\x9bs\xa3\xf3\x9d\x86\xcbep\xaf\xa8\xf6SY\xe4\x9bL\xb5\x1cR\xedS\x8b\xee\xf1\x1b\x04\xfc\x0c_\xad#"\xc5qO\xb3\xc5\xdd\x10\x9f\x02Hl\xdb\xde\xc2A\xec\xd0\xbb\x0c9aU??\xcdwE\xe2Ux\xa6_\xeb\xa0\x080Y\xff\x8a\xbc5L\x07\xf5!\xb3\x08\xc0/\x9ez\xfe\x0fR<_k\xe1J\xe4lN\xc4\x17/\x93\xf7\xbd\xff\x1e\x94<Ot:\xcc\'3m\x94\x10\x9b-l\xd5' 
On peut voir qu'il y a 4 octets dans lesquels la longueur du champ est écrite, puis le champ lui-même, etc. Le premier champ est le nom de l'algorithme, le reste dépend de l'algorithme particulier. Dans la clé ci-dessus, 3 champs:
 b'ssh-rsa' -  b'\x01\x00\x01' -   b'\x00\x9e\x88^\x0e8\xe5!Z\xf3\x98\xae\x1f\xde\xe2\xafu\xfa,\xfe\x8b\xd4\xb4\xb3s6,\xfa\xbe\x18\x08Q\x96\x12\xad\xe6\xf2\xb2\x11Wz\xc7\xa9\xb6\xe9\xc7=\xf1\x8f\x92Ay\xc2\x07\xd1\x96yV$\xf29E\x1cE\xe7c\x86\x16yb\xc3\xc1r!\x1c\x12X\xb7\x9c\xb3\xde>V\x92\x0fy\xc7\xe9\x8f\xbc\xefE- d\xfc\tv\x19\xb1\xf9\xab\xa1~\x85\x92%.c\xbar"\x12\x99~\x13\xb5\xc1\xb5\xb3\x0e\x12\xc2\x84\xc0\x0e\xba\xe1t\xcd\x0e%\xdf\x9c\xe4%<\x8a\xa0\x9bs\xa3\xf3\x9d\x86\xcbep\xaf\xa8\xf6SY\xe4\x9bL\xb5\x1cR\xedS\x8b\xee\xf1\x1b\x04\xfc\x0c_\xad#"\xc5qO\xb3\xc5\xdd\x10\x9f\x02Hl\xdb\xde\xc2A\xec\xd0\xbb\x0c9aU??\xcdwE\xe2Ux\xa6_\xeb\xa0\x080Y\xff\x8a\xbc5L\x07\xf5!\xb3\x08\xc0/\x9ez\xfe\x0fR<_k\xe1J\xe4lN\xc4\x17/\x93\xf7\xbd\xff\x1e\x94<Ot:\xcc\'3m\x94\x10\x9b-l\xd5' -  N (0x101 * 8 = 2048 ) 


Empreinte digitale


L'empreinte digitale de la clé qu'il est proposé de vérifier sur la première connexion est le hachage correspondant (dans l'exemple, SHA256) de la clé publique du dernier paragraphe et de /etc/ssh/ssh_host_rsa_key.pub encodé en base64 pour le hachage des fonctions de la famille SHA ou en hexadécimal pour MD5.

Nous considérons
 from hashlib import sha256 from base64 import b64decode, b64encode pub_key_bin = b64decode("AAAAB3NzaC1yc2EAAAADAQABAAABAQCeiF4OOOUhWvOYrh/e4q91+iz+i9S0s3M2LPq+GAhRlhKt5vKyEVd6x6m26cc98Y+SQXnCB9GWeVYk8jlFHEXnY4YWeWLDwXIhHBJYt5yz3j5Wkg95x+mPvO9FLSBk/Al2GbH5q6F+hZIlLmO6ciISmX4TtcG1sw4SwoTADrrhdM0OJd+c5CU8iqCbc6PznYbLZXCvqPZTWeSbTLUcUu1Ti+7xGwT8DF+tIyLFcU+zxd0QnwJIbNvewkHs0LsMOWFVPz/Nd0XiVXimX+ugCDBZ/4q8NUwH9SGzCMAvnnr+D1I8X2vhSuRsTsQXL5P3vf8elDxPdDrMJzNtlBCbLWzV") hash = sha256(pub_key_bin).digest() fingerprint = b64encode(hash) print(fingerprint) > b'kd9mRkEGLo+RBBNpxKp7mInocF3/Yl/0fXRsGJ2JfYg=' + iz + + i9S0s3M2LPq GAhRlhKt5vKyEVd6x6m26cc98Y + SQXnCB9GWeVYk8jlFHEXnY4YWeWLDwXIhHBJYt5yz3j5Wkg95x + mPvO9FLSBk / Al2GbH5q6F + hZIlLmO6ciISmX4TtcG1sw4SwoTADrrhdM0OJd + + c5CU8iqCbc6PznYbLZXCvqPZTWeSbTLUcUu1Ti 7xGwT8DF + tIyLFcU + zxd0QnwJIbNvewkHs0LsMOWFVPz / Nd0XiVXimX + ugCDBZ / 4q8NUwH9SGzCMAvnnr + D1I8X2vhSuRsTsQXL5P3vf8elDxPdDrMJzNtlBCbLWzV") from hashlib import sha256 from base64 import b64decode, b64encode pub_key_bin = b64decode("AAAAB3NzaC1yc2EAAAADAQABAAABAQCeiF4OOOUhWvOYrh/e4q91+iz+i9S0s3M2LPq+GAhRlhKt5vKyEVd6x6m26cc98Y+SQXnCB9GWeVYk8jlFHEXnY4YWeWLDwXIhHBJYt5yz3j5Wkg95x+mPvO9FLSBk/Al2GbH5q6F+hZIlLmO6ciISmX4TtcG1sw4SwoTADrrhdM0OJd+c5CU8iqCbc6PznYbLZXCvqPZTWeSbTLUcUu1Ti+7xGwT8DF+tIyLFcU+zxd0QnwJIbNvewkHs0LsMOWFVPz/Nd0XiVXimX+ugCDBZ/4q8NUwH9SGzCMAvnnr+D1I8X2vhSuRsTsQXL5P3vf8elDxPdDrMJzNtlBCbLWzV") hash = sha256(pub_key_bin).digest() fingerprint = b64encode(hash) print(fingerprint) > b'kd9mRkEGLo+RBBNpxKp7mInocF3/Yl/0fXRsGJ2JfYg=' 

Nous voyons que le hachage correspond vraiment à l'empreinte digitale affichée lors de la première connexion (citation au début de l'article), précise au symbole "=" à la fin.

Voici un petit programme pour trouver des hôtes dans le fichier known_hosts, qui est apparu pendant les expériences.

Source: https://habr.com/ru/post/fr421477/


All Articles