But : se connecter en secure shell (SSH) sans entrer de mot de passe entre deux machines Linux.
Principe
Il peut-être utile d'automatiser des transferts de fichiers de façon sécurisée entre deux machines fonctionnant sous une distribution Linux.
Vous pouvez par exemple créer des CRONS qui se chargeront d'effectuer un transfert via rsync, généralement utilisé pour créer des sauvegardes entre deux serveurs distincts.
Le principe reste le même : on établit une connexion SSH dans laquelle vont circuler les données (via rsync, scp ou sftp).
Une connexion SSH s'établit avec un nom d'utilisateur autorisé à se connecter en SSH sur la machine (voir sshd_config), ainsi qu'un mot de passe associé à ce compte. Un échange de clé publique s'effectue ensuite pour créer une connexion SSH sécurisée, plus d'infos chez Wikipedia.
Pour que la machine distante accepte une connexion sans mot de passe, il faut que le serveur distant possède la clé publique du serveur local (dans la liste des clés publiques autorisées à effectuer une connexion sans mot de passe).
Nota : toutes les commandes de ce guide ont été effectuées sous Debian Etch (4.0), mais elle restent valables sur de nombreuses distributions : Debian toutes versions, Red Hat, CentOS, etc.
MàJ : 11/2017 passage du mode opératoire en RSA 2048 car DSA déprécié
Etape 1 : générer la clé publique (machine locale)
Connectez-vous en root sur la machine locale, puis générer la clé (minimum 2048) :
ssh-keygen -t rsa -b 2048
serveurlocal:# ssh-keygen -t rsa -b 2048 -C "un commentaire pertinent" Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): [TOUCHE ENTREE] Enter passphrase (empty for no passphrase):[TOUCHE ENTREE] Enter same passphrase again:[TOUCHE ENTREE] Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: 44:f8:69:4b:ad:9f:bd:42:dd:3d:17:04:0d:f0:b9:81 root@serveurlocal The key's randomart image is: +--[ RSA 2048]----+ | .. ..o+ | | .. o .o | | ..o E +. | | .= . o. | | oSo . o ..| | o . . ..o| | o o o| | + . | | ... | +-----------------+ serveurlocal:#
Attention : n'entrez aucun passphrase, validez par entrée. Si vous entrez un passphrase il devra être entré à chaque demande de connexion, nous perdons le bénéfice de l'automatisation 😉 Cela va générer deux fichiers dans le répertoire /root/.ssh/ :
- id_rsa : la clé privée (à ne pas diffuser), appelée identification pour identité
- id_rsa.pub : la clé publique
Note : n'utilisez que des clés de 1024 bits maximum, vous pourrez sinon avoir le message d'erreur : "DSA keys must be 1024 bits".
Etape 2 : transférer la clé publique dans le serveur distant
Plusieurs méthodes s'offrent à vous pour transférer la clé publique vers la machine distante, nous allons toutes les voir en détail.
Méthode A : Transfert via ssh-copy-id
La commande ssh-copy-id permet d'installer votre clé publique sur une machine distante :
serveurlocal:~# ssh-copy-id -i /root/.ssh/id_rsa.pub root@serveurdistant root@serveurdistant's password: Now try logging into the machine, with "ssh 'root@serveurdistant'", and check in: .ssh/authorized_keys to make sure we haven't added extra keys that you weren't expecting. serveurlocal:~#
L'intérêt de cette commande est double puisqu'elle place la clé directement dans le serveur distant et elle applique également les bons droits (chmod) sur le répertoire ~/.ssh ainsi que sur le fichier authorized_keys. Liens utiles : QTH (pour ssh-copy-id)
Méthode B : Transfert via SCP
Pré-requis : connectez-vous en SSH sur le serveur distant, puis vérifiez que le répertoire ~/.ssh existe ainsi que le fichier authorized_keys Si ce n'est pas le cas, les créer et appliquer les bons droits :
serveurdistant:# mkdir ~/.ssh chmod 700 ~/.ssh touch ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys
Vous pouvez ensuite envoyer la clé publique du serveur local en utilisant le de transfert SeCure coPy (SCP) : scp ~/.ssh/id_rsa.pub root@serveurdistant:/root/clelocale.pub
serveurlocal:~# scp ~/.ssh/id_rsa.pub root@serveurdistant:/root/clelocale.pub The authenticity of host 'serveurdistant (82.0.1.2)' can't be established. RSA key fingerprint is 17:5d:99:24:b5:e1:b0:3a:98:e9:90:59:0d:1e:c6:9c. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'serveurdistant,82.0.1.2' (RSA) to the list of known hosts. root@serveurdistant's password: id_rsa.pub 100% 608 0.6KB/s 00:00 serveurlocal:~#
A la question "Are you sure you want to continue connecting" bien répondre yes (en toutes lettres). Ajoutons ensuite la clé dans le fichier ~/.ssh/authorized_keys :
cat /root/clelocale.pub >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys rm -f /root/clelocale.pubLiens : Joël Brogniart, NotMyIdea (Alexis Métaireau)
Méthode C : Transfert via SSH + commande (manuel)
Réservée aux geeks ultimes, cette technique permet en une ligne de commande de faire tout le boulot, elle ressemble un peu à la commande ssh-copy-id puisqu'elle permet d'écrire la valeur de la clé stockée localement dans le serveur distant 😉
ssh root@serveurdistant "echo $(cat ~/.ssh/id_rsa.pub) >> .ssh/authorized_keys"
Une fois connecté au serveur distant :
cat /root/clelocale.pub >> ~/.ssh/authorized_keys
Ou directement en une seule ligne de commande :
cat ~/.ssh/id_rsa.pub | ssh root@serveurdistant "cat >> ~/.ssh/authorized_keys"
Enfin définir à 600 le chmod par mesure de sécurité :
chmod 600 ~/.ssh/authorized_keys rm -f /root/clelocale.pub
Liens : Hostingrails, Ubuntu (ssh), Yoann's Blog
Exemple de transfert via Rsync
Voici un exemple de transfert de fichier entre les deux machines grâce à Rsync, il ne faut pas oublier de préciser la clé publique dans la commande :
rsync -avz -e "ssh -i /root/.ssh/id_rsa" root@serveurdistant:/chemin/distant /chemin/local
Lien : Jdmz
Aspect sécurité
Je vous déconseille fortement d'utiliser ce genre de transfert directement avec l'utilisateur root, vous comprendrez que si la clé publique vous est dérobée (par un quelconque piratage de votre site/serveur) vous offrez une connexion à un second serveur en SSH sans mot de passe...
Je vous invite plutôt à créer un second utilisateur unix qui ne sera pas super-utilisateur, quitte à lui donner différents droits d'exécution via le fichiers sudoers. C'est aussi pour cela que j'ai assez insisté sur le chmod, qui ne rendra visible la clé publique que à l'utilisateur concerné : il serait impossible, en exploitant une quelconque faille d'un mauvais script PHP, de récupérer cette clé publique car l'utilisateur exécutant sera celui d'apache (www-data ou httpd) et n'aura aucun droit dessus.
Je partagerai prochainement l'un de mes scripts à base de rsync qui exploite ces échanges SSH sans mot de passe 😉
Note : le fichier ~/.ssh/authorized_keys ne doit contenir aucun retour chariot pour une même clé, mais uniquement pour séparer les différentes clés autorisée.
Si mon tutoriel n'est pas clair je vous propose un second tuto sur un autre blog, si vous souhaitez utiliser un passphrase voir ce tuto
Auteur : Mr Xhark
Fondateur du blog et passionné par les nouvelles techno, suivez-moi sur twitter
48 commentaires
Très bon tutorial, merci !
Excellent tuto,
Par contre il faut éviter à tout prix son application en production, un clé publique (comme son nom l'indique) est censée être publique, hors elle sert ici de passe partout magique. Mais ça tu nous la prévenu 🙂
Merci 🙂 tu peux ajouter un passphrase pour compliquer la chose comme je l'ai dit, mais tu perds le bénéfice de l'automatisation.
Ce que je peux te conseiller c'est de générer régulièrement (et pourquoi pas de façon automatique maintenant qu'on sait faire) cette clé publique 🙂
J'ai cherché pendant des heures un bon tuto : un tuto pas compliqué mais expliquant un minimum les choses à savoir. Et ici j'ai trouvé mon bonheur ^^.
Merci à l'auteur :).
@Over : c'est aussi pour cette raison que j'ai rédigé ce billet 🙂
Étape 2
Méthode A vs Méthode B
Pourquoi dans un cas c'est le transfert de ~/.ssh/id_dsa.pub et dans l'autre ~/.ssh/id_dsa ? Petite faille de sécurité ? 😉
@Lonix : il s'agissait d'une "coquille", c'est corrigé, merci
La dernière commande ca ne serait pas plutot ?
rsync -avz -e "ssh -i /root/.ssh/id_dsa" root@serveurdistant:/chemin/distant /chemin/local
Sans le .pub, justement ?
Merci pour ce post, impeccable (très pratique surtout la commande ssh-copy-id !)
Effectivement il y a une petite erreur dans la dernière commande donnée en exemple. C'est bien la clef privée qu'il faut appeler en argument du ssh et non la clef publique .pub
... -e "ssh -i /root/.ssh/id_dsa" ...
@Phil @peredom : c'est corrigé, merci
Salut,
Et saurais-tu comment faire lorsque la machine distante est Windows?
Je tourne depuis un moment sur le net et j'ai beaucoup vu la méthode que tu décris ici, mais comment faire dès lors qu'une machine est sous Xp ? Je pense que le système de clef ne va pas avec windows... Y aurait-il d'autres moyens ?
Très bon post en tout cas,
A bientôt
@Vick951 : il est possible d'installer OpenSSH sur Windows mais l'utilisation et l'intérêt sont limités si tu veux faire de la synchro de fichiers. Mieux vaut le faire via un partage Windows/FTPS ou autre.
Ce post est plutôt destiné pour le monde GNU/Linux. Quels sont tes besoins ?
Salut désolé de répondre que maintenant j'étais en déplacement.
Bah en fait on a mis en place un SFTP pour automatiser certains échange de fichiers mensuelle avec des collaborateurs.
Je pensais faire comme en FTP, un truc genre :
psftp User@172.xxx.xxx.xxx
Password
Put/Get
Bye
Mais cela ne fonctionne pas, cela n'écrit pas le pwd... Et si je le tape, après il balance toutes les lignes à la suite...(Ce qui me va très bien 😉 )
Mais je préfèrerais ne pas avoir à taper le Pwd, pour faire tourner cela de nuit...
J'utilise putty, enfin pas la console, juste le psftp.exe
Enfin voilà voilà 🙂 si jamais tu as une petite idée je suis preneur 😉
A bientôt !
@Vick951 : il faut utiliser "-pw" voir au point 6.1.4 http://the.earth.li/~sgtatham/putty/0.52/htmldoc/Chapter6.html
Wouaw, je dis bravo ^^
T'as trouvé le tuto parfait que je cherchais depuis 2jours lol!
Bah que dire, si ce n'est merci ça marche nikel 😀
A bientôt,
merci du coup de main 🙂
@Vick951 : toujours se référer à la documentation produit en cas de questions 🙂 Surtout que dans le domaine système c'est généralement très fourni. Au plaisir !
merci je met ça en place tout de suite c'est exactement ce que je cherchais pour automatiser mes backup !
je viens de tester et quand je lance la commande depuis mon serveur de prod pour envoyer la sauvegarde :
rsync -avz -e "ssh -i /root/.ssh/id_dsa" root@xx.xxx.xxx.93:/ma_sauvegard/aaa /home/aaa/
j'ai :
Warning: Identity file /root/.ssh/id_dsa not accessible: No such file or directory.
Password:
Merci de votre aide
@Stanislas Roussot: Voir étape 1
la clé a bien été généré et les 2 fichiers ont bien été créés j'ai vérifié :-~
Bonjour
quelqu'un a une piste pour moi ?
Merci
Bonjour
j'ai progressé, la clé a bien été créée et transférée mais la commande
rsync -avz -e "ssh -i /root/.ssh/id_dsa" root@cc.cc.ccc.cc:/yyyyyyyyy/ /root/xxxxxxxx.sql
renvoie
"Password: "
comme-ci l'identification ne marchait pas.
merci de votre aide
Il faut entrer le mot de passe au moins une fois, après il ne le demande plus
ok merci (peut être rajouter ce détail dans ce super tuto), sinon :
1- la connexion se fait bien mais j'ai une erreur dans l'envoi du fichier (je vais checker)
2- quand je réessaye, il me redemande le password !
Merci
Excellent tuto qui m'a permis d'automatiser tous mes sauvegardes !! 🙂
Merci
et as tu eu le même souci que moi ? à savoir un password qui n'est pas conservé ???
Concernant l'aspect sécurité, il y a une chose que je ne saisis pas (n'étant, et de loin, pas un expert).
Il est recommandé de ne pas lancer la commande scp directement en root. Soit.
Mais parle-t-on de ne pas lancer la commande en tant que root sur le serveur A (envoyant les données) ou en fournissant le login root sur le serveur B dans la commande (réceptionnaire des données) ?
Pourquoi ? Parce que si la clé publique vient à être dérobée sur le serveur B, en quoi cette clé donne-t-elle accès au serveur A en root ?
Elle ne contient pas le mot de passe rootA à ma connaissance. Et la clé publique n'étant stockée dans authorized_keys que sur le serveur B, avec cette clé il n'est pas possible de passer dans l'autre sens.
Ou alors ce que vous voulez dire, c'est que si cette clé publique est dérobée sur le serveur B, en utilisant cette même clé depuis "ailleurs", on peut accéder au serveur B en root sans mot de passe, ce qui est le principe.
Alors on préconise de créer un second utilisateur, mais cet utilisateur doit avoir accès au serveur B en ssh, donc on ne résout pas le problème, il a tout de même accès en ssh au serveur B.
Où fais-je erreur ?
pour info , après avoir réalisé ce qui est ci-dessus , il m'était toujours demandé le mot de passe, pour résoudre mon soucie j'ai fini par me rendre compte que le clé privé ne devait pas disposer de trop de droit, donc un chmod 600 est un bon choix
@toine: Si tu copies la clé à la mano il faut effectivement descendre les droits en chmod 600 (ssh-copy-id le fait tout seul)
Bonjour, Ce tuto date un peu et pourtant il reste d'une extrême efficacité. J'ai fait et cela fonctionne merveilleusement bien.
Je reste tout même interrogatif comme pierrot-01.
En quoi le vol de la clé publique est un problème pour le serveur distant. Sauf erreur, c'est le jeu de clé qui sert à authentifier. Tant que la clé privée n'est pas dérobée, aucune connexion n'est possible sur le serveur distant.
Pourrais-je avoir un peu plus d'info (autre tuto, site de référence...) avant de mettre en prod ?
Merci d'avance,
Grand merci pour ce tuto d'une efficacité qui n'a d'égale que la clarté et la simplicité. J'aimerais bien, comme certains collègues l'ont fait remarqué plus haut comprendre en quoi le vol de la clé publique pourrait compromettre quelque chose, si la clé privée reste confidentielle.
Merci encore
Tuto utile et bienvenu, merci pour ce bon boulot.
J'ai essayé de le suivre (mac os 10.10) et les clés locales ont été écrites dans /var/root/.ssh/ (j'ai accepté les propositions par défaut) ;
pour lancer ma commande rsync, ça ne marche que si je suis identifié en root (sudo -s), sinon il me dit : "Identity file /var/root/.ssh/id_dsa not accessible: Permission denied" et me demande le mot de passe du serveur distant : ai-je fait une erreur ? dois-je déplacer mes clés ? puis-je changer mes droits pour y avoir accès même sans être root ?
merci.
@gilles: il faut que ton fichier id_dsa soit accessible pour l'utilisateur que tu utilises, donc déplaces le plutôt dans son homedir
Ahah, mais ça ne fait pas mon affaire 😉 Tu me suggères de déplacer mon répertoire .ssh (actuellement dans /var/root/) vers gilles par exemple ? un simple mv peut marcher ou c'est un brin plus compliqué ? as-tu une piste de tuto pour ces manips ? remerci.
@gilles: je n'utilises pas de mac, désolé 🙂 mais ce chemin me semble étrange... ce qui est sûr c'est que tant que ce répertoire n'est pas accessible à l'utilisateur ça ne fonctionnera pas
mac@Mr Xhark: J'utilise mac, mais pas depuis assez longtemps, et il me reste pas mal de choses à apprendre. Je vais chercher, merci 😉
Question bete.
Avec root en local vers root distant cela marche. Mais utiliser root me plait "guerre".
En distant j'ai déjà un user denny. Et j'aimerais utiliser celui mais la il me me demande un mdp quand je fait
ssh denny@mon_ip_distante
Comment résoudre ce souci
merci
@denny: il faut que la clé de l'utilisateur source source présente sur l'utilisateur cible. Cela fonctionne avec tous les utilisateurs, pas uniquement le root.
Donc si tu es en root sur la machine cible il faut envoyer la clé de root sur le profile "denny" sur la machine distante
Merci pour ce tuto, malgré tout j'ai aussi ce problème de mot de passe que l'on me demande à chaque fois. (upload d'une debian vers un nas synology)
Voici ma commande : rsync --ignore-existing --progress -vr --rsh='ssh -p999 -i /root/.ssh/id_dsa' --rsync-path=/usr/bin/rsync /home/* unuserdedie@nas.mondomaine.fr:/volume1/Backup/mondossier/
La clé est bien présente au bon endroit /volume1/homes/unuserdedie/.ssh/authorized_keys
Je suis persuadé que le problème est sur le serveur distant (le nas synology) mais je n'arrive pas à savoir quoi...
merci !!
"Je partagerai prochainement l'un de mes scripts à base de rsync qui exploite ces échanges SSH sans mot de passe 😉" puis-je voir le script?
@anna: http://troy.jdmz.net/rsync/index.html