Les clés SSH : générer, déployer et se connecter en SFTP
Se connecter à un serveur en tapant son mot de passe à chaque fois fonctionne, mais c’est lent, peu sûr et impossible à automatiser. L’authentification par clés SSH règle ces trois problèmes d’un coup : une paire de fichiers correctement placés, et la connexion devient immédiate, robuste et scriptable — que ce soit pour ouvrir un terminal distant, déposer des fichiers en SFTP ou déclencher une sauvegarde nocturne.
Ce guide reprend le sujet depuis le début : ce que sont réellement une clé publique et une clé privée, où les ranger et avec quelles permissions, comment les générer, comment transmettre la bonne moitié au serveur, à quoi servent authorized_keys et known_hosts, comment tester une connexion qui refuse de passer, et pourquoi tout cela s’applique tel quel au SFTP.
Pourquoi des clés plutôt qu’un mot de passe
Un mot de passe est un secret partagé : vous le connaissez, le serveur le connaît (sous forme de empreinte), et il transite au moment de la connexion. Il peut être deviné, rejoué, réutilisé sur dix machines, ou tenté des milliers de fois par des robots qui balaient le port 22 en permanence.
Une clé SSH repose sur un principe différent, la cryptographie asymétrique. Vous détenez deux fichiers complémentaires générés ensemble. L’un peut être diffusé sans risque, l’autre ne doit jamais quitter votre machine. Au moment de la connexion, le serveur envoie un défi ; votre poste y répond en utilisant la clé privée, sans jamais la transmettre. Le serveur vérifie la réponse avec la clé publique qu’il possède déjà. Rien de secret ne circule sur le réseau.
Les conséquences pratiques sont immédiates :
- une attaque par force brute sur le mot de passe devient sans objet ;
- la connexion est instantanée, donc utilisable dans un script ou une tâche
cron; - on peut révoquer l’accès d’une machine précise sans changer quoi que ce soit pour les autres ;
- le même mécanisme sert pour SSH, SCP, SFTP,
rsyncet Git.
Clé publique et clé privée : la différence
L’analogie la plus parlante est celle du cadenas. La clé publique est un cadenas ouvert : vous pouvez en distribuer autant d’exemplaires que vous voulez, sur autant de serveurs que nécessaire. La clé privée est la seule clé qui ouvre ces cadenas : elle reste dans votre poche, elle ne se copie pas, elle ne s’envoie pas par mail.
| Clé privée | Clé publique | |
|---|---|---|
| Nom de fichier typique | id_ed25519 |
id_ed25519.pub |
| Où elle vit | Sur votre poste uniquement | Sur chaque serveur où vous voulez entrer |
| Peut être diffusée ? | Jamais | Oui, sans risque |
| Permissions | 600 |
644 |
| Contenu | Bloc -----BEGIN OPENSSH PRIVATE KEY----- |
Une seule ligne ssh-ed25519 AAAA… commentaire |
Retenez la règle qui évite 90 % des incidents : seul le fichier .pub se transmet. Si un hébergeur, un prestataire ou un collègue vous demande « votre clé SSH », il attend le contenu du .pub. Une clé privée envoyée par mail est une clé privée à regénérer.
La passphrase
La clé privée peut être elle-même chiffrée par une passphrase. Sans elle, un fichier volé sur un poste portable donne un accès immédiat à tous les serveurs concernés. Avec elle, le voleur récupère un fichier inutilisable.
L’objection classique — « je vais devoir la taper à chaque connexion » — tombe avec l’agent SSH, décrit plus bas : la passphrase est saisie une fois par session et l’agent s’occupe du reste. Une clé sans passphrase reste acceptable pour un usage purement automatisé (une clé de déploiement dédiée, restreinte à une seule commande), mais pas pour votre clé personnelle du quotidien.
SSH, SCP, SFTP : quel est le lien ?
C’est une source de confusion fréquente, notamment parce que le sigle SFTP ressemble à FTP. En réalité :
- SSH (Secure Shell) est le protocole. Il ouvre un canal chiffré et authentifié entre deux machines, généralement sur le port 22.
- SFTP (SSH File Transfer Protocol) n’est pas un protocole séparé : c’est un sous-système qui circule à l’intérieur de ce même canal SSH. Même port, même serveur, même authentification — donc les mêmes clés.
- SCP est l’ancêtre simplifié du transfert de fichiers sur SSH : une copie, sans navigation interactive.
- FTPS, en revanche, est du FTP classique enrobé de TLS. Il n’a rien à voir avec SSH, utilise d’autres ports et d’autres certificats. SFTP et FTPS ne sont pas interchangeables.
La conclusion pratique est simple : dès que vous avez configuré vos clés pour SSH, votre client SFTP — en ligne de commande, dans FileZilla ou dans WinSCP — s’authentifie exactement de la même façon. Il n’y a rien de plus à installer côté serveur, et aucun compte supplémentaire à créer.
Où stocker les clés, et avec quelles permissions
Par convention, tout se passe dans un répertoire caché à la racine de votre compte : $HOME/.ssh, soit /home/<utilisateur>/.ssh sous Linux, /Users/<utilisateur>/.ssh sous macOS et C:\Users\<utilisateur>\.ssh sous Windows.
OpenSSH est volontairement intransigeant sur les droits de ces fichiers : un répertoire ou une clé privée lisible par d’autres utilisateurs fait échouer la connexion, sans négociation. Ce comportement, contrôlé côté serveur par l’option StrictModes, est la première cause de « ça marche chez moi mais pas sur le serveur ».
| Élément | Permission | Rôle |
|---|---|---|
$HOME |
755 ou 750 |
Ne doit pas être inscriptible par le groupe ou les autres |
$HOME/.ssh |
700 |
Accessible au seul propriétaire |
id_ed25519 (privée) |
600 |
Lecture/écriture par le propriétaire uniquement |
id_ed25519.pub |
644 |
Publique, lisible sans risque |
authorized_keys |
600 |
Liste des clés autorisées à entrer |
known_hosts |
644 |
Serveurs déjà reconnus |
config |
600 |
Raccourcis et options de connexion |
La mise en conformité tient en quelques commandes, à passer aussi bien sur votre poste que sur le serveur :
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/authorized_keys
chown -R $USER:$USER ~/.ssh
Le chown final n’est pas décoratif : un fichier créé par root dans le .ssh d’un utilisateur (typiquement après un sudo malheureux) sera ignoré par le démon SSH.
Générer une paire de clés avec ssh-keygen
L’outil est fourni avec OpenSSH, présent nativement sous Linux, macOS et Windows 10/11. La commande recommandée aujourd’hui :
ssh-keygen -t ed25519 -C "poste-portable-2026"
Décomposons les options :
-t ed25519: l’algorithme. Ed25519 est plus court, plus rapide et au moins aussi solide que RSA. C’est le choix par défaut sauf contrainte particulière.-C: un commentaire libre, ajouté en fin de clé publique. Il n’a aucun rôle cryptographique mais devient précieux le jour où vous relisez unauthorized_keyscontenant huit lignes : mettez-y de quoi identifier la machine ou l’usage, pas un simple prénom.-f: le chemin du fichier, si vous ne voulez pas écraser la clé par défaut. Par exemple-f ~/.ssh/id_ed25519_prod.
Pour un serveur ancien qui ne gère pas Ed25519 (certains équipements ou systèmes non maintenus), repliez-vous sur RSA avec une taille suffisante :
ssh-keygen -t rsa -b 4096 -C "acces-serveur-legacy"
Les algorithmes dsa et les clés RSA de 1024 bits sont obsolètes et refusés par les versions récentes d’OpenSSH : ne les utilisez plus.
La commande pose ensuite deux questions : l’emplacement du fichier (validez pour le défaut) et la passphrase (saisie deux fois, invisible à l’écran). Le résultat :
ls -l ~/.ssh
# -rw------- 1 user user 411 id_ed25519
# -rw-r--r-- 1 user user 103 id_ed25519.pub
La clé publique est une simple ligne de texte, que vous pouvez afficher sans crainte :
cat ~/.ssh/id_ed25519.pub
# ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI… poste-portable-2026
Vérifier une empreinte
Chaque clé possède une empreinte (fingerprint), résumé court qui permet de la comparer sans manipuler la clé entière — utile pour vérifier que la clé enregistrée chez un hébergeur est bien la vôtre :
ssh-keygen -lf ~/.ssh/id_ed25519.pub
# 256 SHA256:9v1Qk… poste-portable-2026 (ED25519)
Changer la passphrase sans regénérer la clé
ssh-keygen -p -f ~/.ssh/id_ed25519
La paire reste valide : inutile de redéployer la clé publique sur vos serveurs.
Transférer la clé publique vers le serveur
La méthode simple : ssh-copy-id
C’est l’outil prévu pour ça. Il se connecte une dernière fois par mot de passe, crée le répertoire .ssh si nécessaire, ajoute votre clé et corrige les permissions :
ssh-copy-id -i ~/.ssh/id_ed25519.pub utilisateur@serveur.exemple.fr
Si le serveur n’écoute pas sur le port standard :
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 2222 utilisateur@serveur.exemple.fr
Notez le .pub dans le chemin. Sans lui, ssh-copy-id saura retrouver la clé publique correspondante, mais prenez l’habitude de le préciser : c’est un bon garde-fou mental.
La méthode manuelle
Quand ssh-copy-id n’est pas disponible (macOS sans Homebrew, certains environnements Windows), une seule ligne suffit :
cat ~/.ssh/id_ed25519.pub | ssh utilisateur@serveur.exemple.fr \
"mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
Le double chevron >> est capital : il ajoute la clé à la suite des autres. Un simple > écraserait le fichier et couperait l’accès de tous les autres postes déjà autorisés — y compris, parfois, le vôtre.
Par copier-coller
Chez un hébergeur mutualisé, dans un panneau d’administration ou sur une forge logicielle (GitHub, GitLab), il n’y a pas de shell : un champ de formulaire attend le contenu de la clé publique. Copiez la ligne complète, de ssh-ed25519 jusqu’au commentaire final, sans retour à la ligne au milieu.
# Linux
xclip -sel clip < ~/.ssh/id_ed25519.pub
# macOS
pbcopy < ~/.ssh/id_ed25519.pub
# Windows (PowerShell)
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub | Set-Clipboard
authorized_keys : la liste des clés autorisées
Côté serveur, le fichier ~/.ssh/authorized_keys de l’utilisateur cible contient la liste des clés publiques habilitées à ouvrir une session sous ce compte. Une clé par ligne, sans limite de nombre :
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI… poste-portable-2026
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI… poste-fixe-bureau
ssh-rsa AAAAB3NzaC1yc2EAAAADAQAB… serveur-sauvegarde
Ce fichier est votre inventaire des accès. Le relire une fois par an, sur chaque serveur, est un réflexe d’hygiène élémentaire : c’est là qu’on retrouve la clé d’un poste revendu il y a deux ans ou d’un prestataire dont la mission est terminée. Pour retirer un accès, supprimez la ligne correspondante — l’effet est immédiat, sans redémarrage du service.
Restreindre ce qu’une clé a le droit de faire
Chaque ligne accepte des options placées avant le type de clé. C’est particulièrement utile pour les clés automatisées, qui n’ont souvent besoin que d’une seule action :
from="203.0.113.10",restrict,command="/usr/local/bin/sauvegarde.sh" ssh-ed25519 AAAAC3… cle-sauvegarde
from=limite l’usage de la clé à une adresse ou un réseau donné ;command=force l’exécution d’une commande unique, quelle que soit celle demandée par le client ;restrictdésactive d’un coup le transfert de ports, l’agent forwarding, X11 et l’allocation de terminal ; on peut ensuite réactiver ce dont on a besoin.
Une clé de déploiement sans passphrase mais verrouillée par from= et command= est bien plus sûre qu’une clé personnelle sans restriction.
known_hosts : l’authentification du serveur
Jusqu’ici, le serveur vérifie votre identité. Le fichier ~/.ssh/known_hosts répond à la question symétrique : comment savoir que la machine en face est bien la bonne ? Sans cette vérification, un attaquant placé sur le réseau pourrait se faire passer pour votre serveur et récupérer tout ce que vous y tapez.
Chaque serveur possède sa propre clé d’hôte. À la première connexion, votre client ne la connaît pas et vous prévient :
The authenticity of host 'serveur.exemple.fr (203.0.113.20)' can't be established.
ED25519 key fingerprint is SHA256:tS4Rk8…
Are you sure you want to continue connecting (yes/no/[fingerprint])?
En répondant yes, l’empreinte est mémorisée dans known_hosts et ne vous sera plus redemandée. Idéalement, cette empreinte se compare à celle communiquée par l’hébergeur ou relevée depuis la console du serveur :
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
Quand l’empreinte change
Un jour, la connexion se solde par un avertissement en majuscules et un refus catégorique :
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Dans la grande majorité des cas, l’explication est bénigne : le serveur a été réinstallé, la machine virtuelle recréée, ou l’adresse IP réattribuée à un autre hôte. Mais le message signale précisément le scénario d’attaque que known_hosts est censé détecter — alors prenez trois secondes pour vérifier auprès de la source avant de purger l’entrée :
ssh-keygen -R serveur.exemple.fr
La commande retire proprement la ligne concernée, y compris lorsque le fichier est haché (option HashKnownHosts, activée par défaut sur beaucoup de distributions, qui rend les noms d’hôtes illisibles à l’œil nu). La connexion suivante redemandera confirmation.
Pré-remplir known_hosts pour l’automatisation
Un script ne peut pas répondre « yes » à une question interactive. Plutôt que de désactiver la vérification — mauvaise idée, elle vide le mécanisme de son intérêt — récupérez la clé d’hôte à l’avance :
ssh-keyscan -t ed25519 serveur.exemple.fr >> ~/.ssh/known_hosts
Sur un parc de machines, on peut aussi centraliser ces empreintes dans /etc/ssh/ssh_known_hosts, valable pour tous les utilisateurs du poste.
Tester la connectivité SSH
Le test le plus direct consiste à ouvrir une session :
ssh utilisateur@serveur.exemple.fr
Pour tester l’authentification sans ouvrir de terminal — cas des forges logicielles, qui n’autorisent pas de shell :
ssh -T git@github.com
# Hi utilisateur! You've successfully authenticated…
Pour un contrôle utilisable dans un script, qui ne bloque jamais sur une demande de mot de passe et renvoie un code de retour exploitable :
ssh -o BatchMode=yes -o ConnectTimeout=5 utilisateur@serveur.exemple.fr "echo OK"
echo $?
Le mode verbeux, l’outil de diagnostic n°1
Quand une connexion échoue sans explication, -v déroule chaque étape : résolution du nom, négociation, clés proposées, méthode retenue.
ssh -v utilisateur@serveur.exemple.fr
On peut monter à -vv ou -vvv pour plus de détail. Les lignes à repérer commencent par Offering public key (votre client propose bien la clé) et Authentications that can continue (ce que le serveur accepte). Si votre clé n’apparaît nulle part, le problème est côté client ; si elle est proposée puis rejetée, il est côté serveur.
Vérifier que le port répond
Avant de suspecter les clés, assurez-vous que le service est joignable — un pare-feu ou un port non standard suffit à tout bloquer :
nc -zv serveur.exemple.fr 22
Lire les journaux côté serveur
Si vous avez la main sur la machine cible, les logs du démon SSH sont sans ambiguïté :
sudo tail -f /var/log/auth.log # Debian, Ubuntu
sudo tail -f /var/log/secure # RHEL, CentOS, Rocky
sudo journalctl -u sshd -f # systemd, toutes distributions
Les erreurs les plus fréquentes
| Message | Cause la plus probable | Piste de correction |
|---|---|---|
Permission denied (publickey) |
Clé absente de authorized_keys, ou permissions incorrectes |
Vérifier le fichier côté serveur, puis chmod 700 ~/.ssh |
Connection refused |
Service arrêté ou mauvais port | Tester le port, vérifier sshd |
Connection timed out |
Pare-feu, mauvaise adresse | Contrôler les règles réseau |
Host key verification failed |
Empreinte différente de celle mémorisée | ssh-keygen -R <hôte> après vérification |
Bad owner or permissions |
Droits trop larges sur .ssh ou config |
Réappliquer 700 / 600 |
Too many authentication failures |
L’agent propose trop de clés avant la bonne | Forcer la clé avec -i et IdentitiesOnly yes |
L’agent SSH : saisir sa passphrase une seule fois
ssh-agent garde vos clés déverrouillées en mémoire pour la durée de la session. Vous tapez la passphrase une fois, puis toutes les connexions suivantes passent sans rien demander.
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
ssh-add -l # lister les clés chargées
ssh-add -D # tout décharger
Sous macOS, ssh-add --apple-use-keychain mémorise la passphrase dans le trousseau. Sous Windows, le service « OpenSSH Authentication Agent » joue le même rôle. La plupart des environnements de bureau Linux démarrent un agent automatiquement à l’ouverture de session.
L’option ForwardAgent (ssh -A) permet de rebondir d’un serveur vers un autre en réutilisant vos clés locales. C’est pratique, mais un administrateur du serveur intermédiaire peut alors s’en servir à votre insu : préférez ProxyJump, décrit ci-dessous, qui atteint le même résultat sans exposer l’agent.
Le fichier ~/.ssh/config, ou comment arrêter de tout retaper
Ce fichier permet de nommer vos connexions et d’associer à chacune ses options. Il est lu par ssh, scp, sftp et rsync indifféremment.
Host prod
HostName 203.0.113.20
User deploy
Port 2222
IdentityFile ~/.ssh/id_ed25519_prod
IdentitiesOnly yes
Host bastion
HostName bastion.exemple.fr
User admin
Host interne
HostName 10.0.0.15
User admin
ProxyJump bastion
Host *
ServerAliveInterval 60
AddKeysToAgent yes
Une fois ce fichier en place (permissions 600), ssh prod remplace la ligne complète, et sftp prod ouvre un transfert de fichiers vers la même machine avec la même clé. IdentitiesOnly yes évite l’erreur Too many authentication failures en n’envoyant que la clé désignée, et ProxyJump traverse un rebond sans exposer votre agent.
Le SFTP en pratique
Rien de nouveau à configurer : si ssh prod fonctionne, sftp prod aussi.
sftp utilisateur@serveur.exemple.fr
sftp -i ~/.ssh/id_ed25519 -P 2222 utilisateur@serveur.exemple.fr
Attention à la casse : ssh utilise -p pour le port, sftp et scp utilisent -P majuscule. C’est un grand classique des cinq minutes perdues.
Une fois la session ouverte, quelques commandes suffisent. Celles préfixées d’un l agissent en local :
| Commande | Effet |
|---|---|
ls / lls |
Lister le répertoire distant / local |
cd / lcd |
Changer de répertoire distant / local |
get fichier |
Télécharger depuis le serveur |
put fichier |
Envoyer vers le serveur |
get -r dossier |
Télécharger une arborescence complète |
bye |
Quitter |
Pour un transfert ponctuel sans session interactive, scp reste le plus court :
scp rapport.pdf utilisateur@serveur.exemple.fr:/var/www/documents/
scp -r ./site utilisateur@serveur.exemple.fr:/var/www/
Et pour synchroniser des dossiers volumineux, rsync sur SSH ne transfère que les différences :
rsync -avz -e "ssh -i ~/.ssh/id_ed25519" ./site/ utilisateur@serveur.exemple.fr:/var/www/site/
Automatiser un dépôt SFTP
Un fichier de commandes permet de scripter un transfert récurrent :
cat > /tmp/depot.txt <<'EOF'
cd /depot/entrant
put /export/flux_du_jour.csv
bye
EOF
sftp -b /tmp/depot.txt -i ~/.ssh/id_ed25519 utilisateur@serveur.exemple.fr
C’est le schéma type d’un échange de fichiers planifié : clé sans passphrase dédiée à ce seul usage, restreinte par from= dans authorized_keys, et empreinte du serveur pré-enregistrée avec ssh-keyscan.
Les clients graphiques
FileZilla, WinSCP, Cyberduck et les explorateurs de fichiers intégrés aux éditeurs de code acceptent tous l’authentification par clé. Le principe est identique : choisir le protocole SFTP, indiquer l’hôte et l’utilisateur, puis désigner le fichier de clé privée au lieu du mot de passe.
Une particularité concerne l’écosystème PuTTY, qui utilise son propre format .ppk. La conversion se fait avec PuTTYgen, en chargeant la clé OpenSSH puis en l’exportant. WinSCP, qui s’appuie sur la même bibliothèque, propose la conversion à la volée.
Bonnes pratiques et sécurisation du serveur
Quelques principes qui coûtent peu et évitent beaucoup :
- Une clé par machine, pas une clé partagée entre plusieurs postes ou plusieurs personnes. C’est ce qui permet de révoquer un accès précis sans perturber les autres.
- Une passphrase sur toute clé personnelle, combinée à l’agent pour le confort.
- Ne jamais versionner une clé privée. Ajoutez
*.pem,id_*et.ssh/à votre.gitignore— une clé poussée sur un dépôt, même privé, est une clé à considérer comme compromise. - Sauvegarder les clés privées dans un gestionnaire de secrets ou un support chiffré : perdre sa clé, c’est perdre l’accès à tout ce qu’elle ouvrait.
- Auditer les
authorized_keyspériodiquement, sur chaque serveur et chaque compte.
Côté serveur, une fois vos clés déployées et testées depuis une seconde session déjà ouverte, durcissez la configuration dans /etc/ssh/sshd_config :
PasswordAuthentication no
PermitRootLogin prohibit-password
PubkeyAuthentication yes
sudo sshd -t # vérifier la syntaxe AVANT de recharger
sudo systemctl reload sshd
Le sshd -t et la seconde session ouverte ne sont pas des précautions théoriques : une erreur de configuration SSH sur une machine distante sans accès console physique est l’une des rares fautes réellement irrattrapables.
Enfin, pour les accès les plus sensibles, OpenSSH gère depuis la version 8.2 les clés adossées à une clé matérielle FIDO2, générées avec ssh-keygen -t ed25519-sk. La clé privée devient inutilisable sans la présence physique du jeton.
En résumé
- Une paire de clés = un fichier public qui se diffuse, un fichier privé qui ne bouge jamais.
- Tout vit dans
$HOME/.ssh, en700pour le répertoire,600pour la clé privée etauthorized_keys. - On génère avec
ssh-keygen -t ed25519 -C "commentaire", on transmet avecssh-copy-id. authorized_keysliste qui peut entrer ;known_hostsmémorise l’identité des serveurs visités.- En cas de blocage,
ssh -vpuis les journaux du serveur donnent la réponse dans presque tous les cas. - SFTP n’est pas un protocole distinct mais un sous-système de SSH : la configuration faite pour l’un vaut automatiquement pour l’autre.
La mise en place demande dix minutes une fois pour toutes, et fait gagner un temps considérable ensuite — tout en supprimant la principale porte d’entrée des attaques automatisées sur un serveur exposé.
Une dernière recommandation : gardez toujours une session ouverte pendant que vous modifiez une configuration SSH. C’est le filet de sécurité qui transforme une erreur bloquante en simple correction de deux minutes.