Paramiko : pilote tes serveurs en SSH avec Python, sans ouvrir de terminal

De quoi avez-vous besoin

Version de Python

3.x

Packages

  • {"nom":"paramiko","version":"5.0.0"}

Difficulté

Intermédiaire

Se connecter en SSH, taper la même commande sur dix serveurs, rapatrier un fichier de log en pleine nuit : ce genre de corvée, Python peut le faire à ta place. Paramiko est une bibliothèque 100 % Python qui implémente le protocole SSH côté client. Pas de binaire à installer, pas de dépendance système : tu exécutes des commandes à distance, tu transfères des fichiers et tu automatises toute ton infrastructure depuis un simple script. C'est d'ailleurs la brique qui fait tourner Ansible et Fabric sous le capot.

1. Installer Paramiko

Paramiko s'installe comme n'importe quel paquet. Il embarque automatiquement ses dépendances de chiffrement (cryptography, bcrypt, pynacl), tu n'as rien d'autre à gérer.

bash
pip install paramiko

Vérifie que l'import passe :

python
import paramiko
print(paramiko.__version__)

2. Se connecter à un serveur

Le point d'entrée, c'est SSHClient. Deux choses à savoir : tu définis d'abord une politique pour les clés d'hôte (AutoAddPolicy accepte tout, pratique pour tester, à remplacer en production), puis tu appelles connect.

python
import paramiko

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

client.connect(
    hostname="192.168.1.10",
    username="debian",
    password="ton_mot_de_passe",
)

print("Connecté !")
client.close()

En production, charge plutôt les clés déjà connues avec client.load_system_host_keys() au lieu d'accepter n'importe quelle empreinte.

3. Exécuter une commande à distance

exec_command renvoie trois flux : l'entrée standard, la sortie standard et la sortie d'erreur. Tu lis la sortie, puis tu récupères le code de retour pour savoir si tout s'est bien passé.

python
stdin, stdout, stderr = client.exec_command("df -h")
sortie = stdout.read().decode()
erreur = stderr.read().decode()
code_retour = stdout.channel.recv_exit_status()

print(sortie)
if code_retour != 0:
    print("Échec :", erreur)

La commande s'exécute dans le shell distant. Tu peux enchaîner avec && ou des pipes, exactement comme dans un terminal.

4. Automatiser plusieurs serveurs en boucle

C'est là que ça devient intéressant : tu fais tourner la même vérification sur toute ta flotte en quelques lignes.

python
serveurs = [
    ("192.168.1.10", "debian", "mdp1"),
    ("192.168.1.11", "debian", "mdp2"),
    ("192.168.1.12", "debian", "mdp3"),
]

for hote, user, mdp in serveurs:
    c = paramiko.SSHClient()
    c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    c.connect(hostname=hote, username=user, password=mdp)
    _, out, _ = c.exec_command("uptime -p")
    print(f"{hote}: {out.read().decode().strip()}")
    c.close()

Remplace uptime -p par ce que tu veux : redémarrer un service, purger un cache, vérifier l'espace disque. Ton script devient ton sysadmin de garde.

5. Transférer des fichiers avec SFTP

Paramiko embarque aussi un client SFTP pour pousser ou rapatrier des fichiers, sans rsync ni scp externe.

python
sftp = client.open_sftp()
sftp.put("rapport.csv", "/home/debian/rapport.csv")  # local vers distant
sftp.get("/var/log/syslog", "syslog_local.txt")      # distant vers local
sftp.close()

put envoie, get télécharge. Tu peux aussi lister un répertoire avec sftp.listdir("/var/log") ou supprimer un fichier avec sftp.remove().

6. Se connecter sans mot de passe, avec une clé SSH

Saisir des mots de passe en clair dans un script, c'est risqué. Préfère une clé SSH :

python
client.connect(
    hostname="192.168.1.10",
    username="debian",
    key_filename="/home/toi/.ssh/id_ed25519",
)

Si tu as besoin de charger la clé toi-même (pour y attacher une passphrase, par exemple), passe-la via pkey :

python
cle = paramiko.Ed25519Key.from_private_key_file("/home/toi/.ssh/id_ed25519")
client.connect(hostname="192.168.1.10", username="debian", pkey=cle)

RSAKey.from_private_key_file fait pareil pour une clé id_rsa classique. Génère ta paire avec ssh-keygen -t ed25519 si tu n'en as pas encore.

7. Gérer les erreurs proprement

Un serveur peut être éteint, un mot de passe périmé, un port fermé. Enveloppe tes connexions pour que le script ne meure pas bêtement.

python
import socket

try:
    client.connect(hostname=hote, username=user, key_filename=cle)
except paramiko.AuthenticationException:
    print(f"{hote}: authentification refusée")
except paramiko.SSHException as e:
    print(f"{hote}: erreur SSH ({e})")
except socket.timeout:
    print(f"{hote}: pas de réponse")

Une boucle, un try/except, et tu obtiens un script de supervision qui continue de tourner même quand un serveur tombe.

En une trentaine de lignes, tu as remplacé des heures de connexions manuelles. Paramiko est la fondation : une fois que tu sais exécuter une commande et déplacer un fichier à distance, tu peux écrire tes propres mini-outils de déploiement, de sauvegarde ou de monitoring. Pour aller plus loin, regarde Fabric, qui s'appuie dessus pour des déploiements encore plus fluides, ou paramiko.SSHConfig pour lire directement ton ~/.ssh/config.