🛠 Outils IT
🛠 78 outils 📚 32 docs
🤖 Assistant

SSH - Secure Shell

1. Installation Client / Serveur (OpenSSH)

SSH (Secure Shell) est le protocole standard pour l'administration distante securisee des serveurs. OpenSSH est l'implementation la plus repandue, disponible sur quasiment tous les systemes Unix/Linux et integree nativement depuis Windows 10.

1.1 Installation du client SSH

Le client SSH permet de se connecter a un serveur distant.

Debian / Ubuntu

# Le client est generalement installe par defaut
sudo apt update
sudo apt install openssh-client

# Verifier la version
ssh -V

CentOS / RHEL / Rocky Linux

sudo dnf install openssh-clients

ssh -V

Windows

# Windows 10/11 : OpenSSH est integre
# Verifier dans PowerShell :
ssh -V

# Si absent, installer via les fonctionnalites optionnelles :
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

1.2 Installation du serveur SSH

Le serveur SSH (sshd) permet d'accepter les connexions entrantes.

Debian / Ubuntu

sudo apt update
sudo apt install openssh-server

# Demarrer et activer le service
sudo systemctl start ssh
sudo systemctl enable ssh

# Verifier le statut
sudo systemctl status ssh

CentOS / RHEL / Rocky Linux

sudo dnf install openssh-server

sudo systemctl start sshd
sudo systemctl enable sshd

sudo systemctl status sshd

Ouvrir le port dans le firewall

# UFW (Debian/Ubuntu)
sudo ufw allow ssh
# ou explicitement :
sudo ufw allow 22/tcp

# firewalld (CentOS/RHEL)
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload

# iptables
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
Astuce : sur la plupart des distributions Linux serveur, le serveur OpenSSH est deja installe et actif par defaut. Verifiez avec sudo systemctl status ssh (ou sshd) avant de l'installer.

2. Connexion de base et options

2.1 Syntaxe de base

# Connexion simple (utilisateur@hote)
ssh utilisateur@192.168.1.100
ssh admin@serveur.example.com

# Si le nom d'utilisateur local est identique au distant
ssh 192.168.1.100

# Specifier un port different
ssh -p 2222 utilisateur@serveur.example.com

# Specifier une cle privee
ssh -i ~/.ssh/ma_cle utilisateur@serveur.example.com

2.2 Options courantes

Option Description Exemple
-p PORT Specifier le port de connexion ssh -p 2222 user@host
-i CLE Specifier la cle privee a utiliser ssh -i ~/.ssh/id_ed25519 user@host
-v / -vv / -vvv Mode verbose (debug niveaux 1, 2 ou 3) ssh -vvv user@host
-L Tunnel local (port forwarding) ssh -L 8080:localhost:80 user@host
-R Tunnel distant (reverse port forwarding) ssh -R 9090:localhost:3000 user@host
-D Tunnel dynamique (proxy SOCKS) ssh -D 1080 user@host
-N Pas de commande distante (utile pour les tunnels) ssh -N -L 8080:localhost:80 user@host
-f Passer en arriere-plan apres authentification ssh -f -N -L 8080:localhost:80 user@host
-J ProxyJump (passer par un bastion) ssh -J bastion@jump user@cible
-A Activer le forwarding de l'agent SSH ssh -A user@host
-X / -Y Activer le X11 forwarding (affichage graphique) ssh -X user@host
-o Passer une option de configuration ssh -o StrictHostKeyChecking=no user@host
-t Forcer l'allocation d'un pseudo-terminal ssh -t user@host sudo commande

2.3 Executer une commande distante

# Executer une seule commande et revenir
ssh utilisateur@serveur "df -h"
ssh utilisateur@serveur "uptime && free -m"

# Executer un script local sur le serveur distant
ssh utilisateur@serveur 'bash -s' < script_local.sh

# Executer avec sudo (necessite -t pour le terminal)
ssh -t utilisateur@serveur "sudo systemctl restart nginx"
Astuce : utilisez des guillemets simples pour empecher l'interpretation des variables localement : ssh user@host 'echo $HOSTNAME' affichera le hostname du serveur distant, pas celui de votre machine.

3. Generation de cles (ssh-keygen)

L'authentification par cle est plus securisee et plus pratique que le mot de passe. Elle repose sur un couple cle privee (secrete, sur votre poste) et cle publique (distribuee sur les serveurs).

3.1 Types de cles

Algorithme Commande Recommandation
Ed25519 ssh-keygen -t ed25519 Recommande - Rapide, securise, cles compactes
RSA ssh-keygen -t rsa -b 4096 Bonne alternative - Compatible partout, utiliser 4096 bits minimum
ECDSA ssh-keygen -t ecdsa -b 521 Acceptable - Preferer Ed25519 quand possible
DSA ssh-keygen -t dsa Obsolete - Ne plus utiliser (deprecie dans OpenSSH 7.0+)

3.2 Generer une cle Ed25519 (recommande)

# Generation avec commentaire (pour identifier la cle)
ssh-keygen -t ed25519 -C "admin@monserveur - cle principale"

# Deroulement interactif :
# Generating public/private ed25519 key pair.
# Enter file in which to save the key (/home/user/.ssh/id_ed25519): [Entree]
# Enter passphrase (empty for no passphrase): [votre passphrase]
# Enter same passphrase again: [confirmer]

# Resultat :
# Your identification has been saved in /home/user/.ssh/id_ed25519
# Your public key has been saved in /home/user/.ssh/id_ed25519.pub

3.3 Generer une cle RSA 4096 bits

# RSA avec 4096 bits (pour compatibilite avec les systemes anciens)
ssh-keygen -t rsa -b 4096 -C "admin@monserveur - cle RSA"

# Specifier un chemin de fichier different
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_serveur_prod

3.4 Options utiles de ssh-keygen

# Generer une cle sans passphrase (pour les scripts automatises)
ssh-keygen -t ed25519 -f ~/.ssh/id_automation -N ""

# Changer la passphrase d'une cle existante
ssh-keygen -p -f ~/.ssh/id_ed25519

# Afficher l'empreinte (fingerprint) d'une cle
ssh-keygen -l -f ~/.ssh/id_ed25519.pub

# Afficher l'empreinte au format visuel (randomart)
ssh-keygen -lv -f ~/.ssh/id_ed25519.pub

# Convertir une cle publique au format RFC 4716
ssh-keygen -e -f ~/.ssh/id_ed25519.pub

# Generer la cle publique a partir de la cle privee
ssh-keygen -y -f ~/.ssh/id_ed25519 > ~/.ssh/id_ed25519.pub
Attention : protegez toujours vos cles privees avec une passphrase forte, surtout pour les cles utilisees manuellement. Les cles sans passphrase ne doivent etre utilisees que pour des scripts automatises et avec des restrictions strictes (commande forcee, IP source limitee).

3.5 Fichiers generes

# Arborescence typique de ~/.ssh/
~/.ssh/
├── id_ed25519          # Cle privee (NE JAMAIS PARTAGER)
├── id_ed25519.pub      # Cle publique (a copier sur les serveurs)
├── id_rsa              # Cle privee RSA (si generee)
├── id_rsa.pub          # Cle publique RSA
├── known_hosts         # Empreintes des serveurs connus
├── authorized_keys     # Cles autorisees (cote serveur)
└── config              # Configuration client SSH

4. Authentification par cle

4.1 Copier la cle publique sur le serveur

Methode 1 : ssh-copy-id (recommande)

# Copie automatique de la cle publique par defaut
ssh-copy-id utilisateur@serveur

# Specifier une cle particuliere
ssh-copy-id -i ~/.ssh/id_ed25519.pub utilisateur@serveur

# Specifier un port different
ssh-copy-id -p 2222 utilisateur@serveur

# Resultat : la cle publique est ajoutee dans
# ~/.ssh/authorized_keys sur le serveur distant

Methode 2 : copie manuelle

# Si ssh-copy-id n'est pas disponible (ex: Windows sans Git Bash)
# Afficher la cle publique
cat ~/.ssh/id_ed25519.pub

# Copier le contenu et l'ajouter manuellement sur le serveur :
ssh utilisateur@serveur "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys" < ~/.ssh/id_ed25519.pub

# Ou en une seule commande avec pipe
cat ~/.ssh/id_ed25519.pub | ssh utilisateur@serveur "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

4.2 Format du fichier authorized_keys

# ~/.ssh/authorized_keys - une cle par ligne
# Format : type cle commentaire
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... admin@poste-bureau
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQ... admin@poste-portable

# Avec des options de restriction :
# Limiter a une commande specifique
command="/usr/local/bin/backup.sh" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... backup-auto

# Limiter par IP source
from="192.168.1.0/24,10.0.0.5" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... admin-interne

# Desactiver le port forwarding et le X11
no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... cle-restreinte

# Combinaison de restrictions
from="10.0.0.0/8",command="/usr/bin/rsync --server",no-pty ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... rsync-backup

4.3 Permissions critiques

# Cote CLIENT (votre poste) :
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519        # Cle privee
chmod 644 ~/.ssh/id_ed25519.pub    # Cle publique
chmod 644 ~/.ssh/known_hosts
chmod 600 ~/.ssh/config

# Cote SERVEUR (machine distante) :
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

# Le repertoire home ne doit PAS etre en ecriture par le groupe/autres
chmod go-w ~
Attention : SSH refuse l'authentification par cle si les permissions sont incorrectes. C'est la cause numero 1 des echecs de connexion par cle. Verifiez toujours les permissions avec ls -la ~/.ssh/ en cas de probleme.

4.4 Tester la connexion par cle

# Connexion (ne devrait plus demander de mot de passe)
ssh utilisateur@serveur

# Si la passphrase est configuree, ssh-agent evite de la retaper
# (voir section Agent SSH)

# En cas d'echec, utiliser le mode verbose pour diagnostiquer
ssh -vvv utilisateur@serveur 2>&1 | grep -E "Offering|Accepted|Trying"

5. Configuration client (~/.ssh/config)

Le fichier ~/.ssh/config permet de definir des alias et des parametres par defaut pour vos connexions SSH. Il evite de taper de longues commandes a chaque fois.

5.1 Syntaxe de base

# ~/.ssh/config
# Chaque bloc Host definit un alias de connexion

Host mon-serveur
    HostName 192.168.1.100
    User admin
    Port 22
    IdentityFile ~/.ssh/id_ed25519

# Connexion : ssh mon-serveur
# Equivalent a : ssh -i ~/.ssh/id_ed25519 -p 22 admin@192.168.1.100

5.2 Exemples pratiques pour sysadmin

# ~/.ssh/config

# === PARAMETRES GLOBAUX ===
Host *
    # Garder la connexion active (envoyer un ping toutes les 60s)
    ServerAliveInterval 60
    ServerAliveCountMax 3
    # Reutiliser les connexions existantes (accelere les connexions multiples)
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 600
    # Ajouter automatiquement les cles a l'agent
    AddKeysToAgent yes
    # Algorithme de cle prefere
    IdentitiesOnly yes

# === SERVEURS DE PRODUCTION ===
Host prod-web01
    HostName 10.0.1.10
    User sysadmin
    Port 2222
    IdentityFile ~/.ssh/id_ed25519_prod

Host prod-web02
    HostName 10.0.1.11
    User sysadmin
    Port 2222
    IdentityFile ~/.ssh/id_ed25519_prod

Host prod-db01
    HostName 10.0.1.20
    User dba
    Port 2222
    IdentityFile ~/.ssh/id_ed25519_prod

# === SERVEURS DE STAGING ===
Host staging-*
    User deploy
    Port 22
    IdentityFile ~/.ssh/id_ed25519_staging

Host staging-web
    HostName 172.16.0.10

Host staging-api
    HostName 172.16.0.11

# === ACCES VIA BASTION ===
Host bastion
    HostName bastion.example.com
    User jump-admin
    Port 2222
    IdentityFile ~/.ssh/id_ed25519_bastion

Host interne-*
    ProxyJump bastion
    User admin
    IdentityFile ~/.ssh/id_ed25519_prod

Host interne-app01
    HostName 10.10.0.50

Host interne-app02
    HostName 10.10.0.51

# === GITHUB / GITLAB ===
Host github.com
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_github

Host gitlab.example.com
    HostName gitlab.example.com
    User git
    IdentityFile ~/.ssh/id_ed25519_gitlab
    Port 2222

5.3 Multiplexage de connexions

Le multiplexage permet de reutiliser une connexion SSH existante, accelerant considerablement les connexions subsequentes et les transferts SCP/SFTP :

# Creer le repertoire pour les sockets
mkdir -p ~/.ssh/sockets

# Configuration dans ~/.ssh/config
Host *
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 600

# ControlMaster auto : cree automatiquement un socket maitre
# ControlPath : chemin du fichier socket (%r=user, %h=host, %p=port)
# ControlPersist 600 : garde la connexion 10 minutes apres deconnexion

# Verifier les connexions multiplexees actives
ssh -O check mon-serveur

# Fermer une connexion multiplexee
ssh -O exit mon-serveur

5.4 Wildcard et patterns

# Appliquer des parametres a plusieurs hotes
Host 192.168.1.*
    User admin
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null

# Negation : tous les hotes SAUF ceux en .internal
Host * !*.internal
    ProxyJump bastion

# Pattern avec ? (un seul caractere)
Host web??
    User www-data
    Port 2222
Astuce : l'ordre des blocs Host est important. SSH lit le fichier de haut en bas et applique la premiere valeur trouvee pour chaque parametre. Placez les blocs specifiques avant les blocs generiques (Host * en dernier).

6. Configuration serveur (sshd_config)

Le fichier /etc/ssh/sshd_config controle le comportement du daemon SSH. La securisation de ce fichier est essentielle pour proteger vos serveurs.

6.1 Configuration securisee recommandee

# /etc/ssh/sshd_config - Configuration securisee

# === PORT ET ADRESSE ===
Port 2222                              # Changer le port par defaut (evite les scans basiques)
AddressFamily inet                     # IPv4 uniquement (ou 'any' pour IPv4+IPv6)
ListenAddress 0.0.0.0                  # Ecouter sur toutes les interfaces (ou IP specifique)

# === AUTHENTIFICATION ===
PermitRootLogin no                     # INTERDIT la connexion root directe
PubkeyAuthentication yes               # Activer l'authentification par cle
PasswordAuthentication no              # DESACTIVER l'authentification par mot de passe
PermitEmptyPasswords no                # Interdire les mots de passe vides
ChallengeResponseAuthentication no     # Desactiver challenge-response
KbdInteractiveAuthentication no        # Desactiver clavier interactif

# === CLES ET ALGORITHMES ===
# N'autoriser que les algorithmes modernes
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
PubkeyAcceptedAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256

# === SECURITE ===
MaxAuthTries 3                         # Nombre max de tentatives par connexion
MaxSessions 5                          # Sessions max par connexion
LoginGraceTime 30                      # Temps max pour s'authentifier (secondes)
ClientAliveInterval 300                # Ping client toutes les 5 minutes
ClientAliveCountMax 2                  # Deconnexion apres 2 pings sans reponse
MaxStartups 10:30:60                   # Limiter les connexions non authentifiees

# === RESTRICTIONS D'ACCES ===
AllowUsers admin deploy                # Seuls ces utilisateurs peuvent se connecter
# AllowGroups ssh-users                # Alternative : autoriser par groupe
DenyUsers root test guest              # Utilisateurs explicitement interdits

# === FONCTIONNALITES ===
X11Forwarding no                       # Desactiver le X11 forwarding
AllowTcpForwarding yes                 # Autoriser les tunnels TCP (adapter selon besoin)
AllowAgentForwarding yes               # Autoriser le forwarding de l'agent
PrintMotd yes                          # Afficher le message du jour
PrintLastLog yes                       # Afficher la derniere connexion
TCPKeepAlive yes                       # Garder la connexion TCP active
UseDNS no                              # Desactiver la resolution DNS inverse (accelere la connexion)

# === LOGGING ===
SyslogFacility AUTH
LogLevel VERBOSE                       # Logging detaille pour l'audit

# === SFTP ===
Subsystem sftp /usr/lib/openssh/sftp-server

# === RESTRICTION SFTP PAR GROUPE (chroot) ===
Match Group sftp-users
    ChrootDirectory /home/%u
    ForceCommand internal-sftp
    AllowTcpForwarding no
    X11Forwarding no

6.2 Appliquer les modifications

# TOUJOURS verifier la syntaxe avant de recharger
sudo sshd -t

# Si la syntaxe est correcte, recharger le service
sudo systemctl reload ssh    # Debian/Ubuntu
sudo systemctl reload sshd   # CentOS/RHEL

# IMPORTANT : gardez toujours une session SSH ouverte
# pendant les modifications pour ne pas vous enfermer dehors !
Attention : avant de desactiver PasswordAuthentication, assurez-vous que votre cle publique est bien installee sur le serveur et que vous pouvez vous connecter par cle. Testez dans une nouvelle session tout en gardant l'ancienne ouverte. En cas d'erreur, vous aurez toujours acces via la session existante.

6.3 Securisation supplementaire avec Fail2ban

# Installer Fail2ban
sudo apt install fail2ban    # Debian/Ubuntu
sudo dnf install fail2ban    # CentOS/RHEL

# Creer la configuration locale
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# /etc/fail2ban/jail.local - Section SSH
[sshd]
enabled  = true
port     = 2222
filter   = sshd
logpath  = /var/log/auth.log
maxretry = 3
bantime  = 3600
findtime = 600
# Demarrer Fail2ban
sudo systemctl start fail2ban
sudo systemctl enable fail2ban

# Verifier le statut
sudo fail2ban-client status sshd

# Debannir une IP
sudo fail2ban-client set sshd unbanip 203.0.113.50

6.4 Regenerer les cles du serveur

# Supprimer les anciennes cles host
sudo rm /etc/ssh/ssh_host_*

# Regenerer les cles (ed25519 et rsa)
sudo ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""
sudo ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ""

# Redemarrer le service
sudo systemctl restart ssh
Astuce : apres avoir regenere les cles du serveur, les clients recevront un avertissement WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!. Il faudra supprimer l'ancienne empreinte dans ~/.ssh/known_hosts sur chaque client (voir section Depannage).

7. Tunnels SSH (local, remote, dynamic)

Les tunnels SSH permettent de chiffrer et rediriger le trafic reseau a travers une connexion SSH. Tres utile pour acceder a des services internes, contourner les restrictions reseau ou securiser des protocoles non chiffres.

7.1 Tunnel local (-L) : Local Port Forwarding

Redirige un port de votre machine locale vers un service accessible depuis le serveur SSH.

# Syntaxe : ssh -L [bind_address:]port_local:hote_distant:port_distant user@serveur_ssh

# Acceder a un serveur web interne via le tunnel
# localhost:8080 -> serveur SSH -> 10.0.0.50:80
ssh -L 8080:10.0.0.50:80 admin@bastion.example.com
# Ouvrir http://localhost:8080 dans le navigateur

# Acceder a une base MySQL interne
# localhost:3307 -> serveur SSH -> db-interne:3306
ssh -L 3307:db-interne:3306 admin@bastion.example.com
# Connexion : mysql -h 127.0.0.1 -P 3307 -u user -p

# Acceder a l'interface web Proxmox interne
ssh -L 8006:10.0.0.1:8006 admin@bastion.example.com
# Ouvrir https://localhost:8006

# Tunnel en arriere-plan (sans terminal interactif)
ssh -f -N -L 8080:10.0.0.50:80 admin@bastion.example.com

# Tunnel qui ecoute sur toutes les interfaces (pas seulement localhost)
ssh -L 0.0.0.0:8080:10.0.0.50:80 admin@bastion.example.com

7.2 Tunnel distant (-R) : Remote Port Forwarding

Redirige un port du serveur distant vers un service de votre machine locale. Utile pour rendre un service local accessible depuis l'exterieur.

# Syntaxe : ssh -R [bind_address:]port_distant:hote_local:port_local user@serveur_ssh

# Rendre votre serveur web local accessible sur le serveur distant
# serveur:9090 -> votre machine -> localhost:3000
ssh -R 9090:localhost:3000 admin@serveur.example.com
# Depuis le serveur : curl http://localhost:9090

# Exposer un service de dev local sur un serveur public
ssh -R 0.0.0.0:8080:localhost:3000 admin@serveur-public.com

# En arriere-plan
ssh -f -N -R 9090:localhost:3000 admin@serveur.example.com
Astuce : pour que le tunnel distant ecoute sur toutes les interfaces (pas seulement localhost sur le serveur), il faut activer GatewayPorts yes dans le sshd_config du serveur distant.

7.3 Tunnel dynamique (-D) : Proxy SOCKS

Cree un proxy SOCKS5 local qui route tout le trafic a travers le serveur SSH. Equivalent a un mini-VPN pour le navigateur.

# Syntaxe : ssh -D [bind_address:]port user@serveur_ssh

# Creer un proxy SOCKS5 sur le port 1080
ssh -D 1080 admin@serveur.example.com

# En arriere-plan
ssh -f -N -D 1080 admin@serveur.example.com

# Configurer Firefox : Parametres > Reseau > Proxy SOCKS
# Hote : 127.0.0.1, Port : 1080, SOCKS v5

# Utiliser avec curl
curl --socks5-hostname 127.0.0.1:1080 https://ifconfig.me

# Utiliser avec wget (via tsocks ou proxychains)
proxychains wget https://example.com/fichier.tar.gz

7.4 Resume visuel des tunnels

# TUNNEL LOCAL (-L) : vous accedez a un service distant via votre port local
# [Votre PC :8080] ==SSH==> [Serveur SSH] -----> [Service interne :80]

# TUNNEL DISTANT (-R) : le serveur distant accede a votre service local
# [Serveur SSH :9090] ==SSH==> [Votre PC] -----> [Service local :3000]

# TUNNEL DYNAMIQUE (-D) : proxy SOCKS, tout le trafic passe par le serveur SSH
# [Votre PC :1080] ==SSH=SOCKS==> [Serveur SSH] -----> [N'importe ou sur Internet]

7.5 Gerer les tunnels actifs

# Lister les tunnels SSH actifs
ps aux | grep "ssh -[fNLD]"

# Trouver quel processus utilise un port
sudo ss -tlnp | grep 8080
# ou
sudo lsof -i :8080

# Fermer un tunnel en arriere-plan
kill $(pgrep -f "ssh -f -N -L 8080")

8. Agent SSH (ssh-agent, ssh-add)

L'agent SSH garde vos cles privees deverrouillees en memoire, evitant de retaper la passphrase a chaque connexion. C'est un composant essentiel pour un workflow SSH efficace.

8.1 Demarrer l'agent

# Demarrer l'agent dans le shell courant
eval "$(ssh-agent -s)"
# Resultat : Agent pid 12345

# Ajouter au .bashrc ou .zshrc pour un demarrage automatique
# Methode 1 : demarrage simple
if [ -z "$SSH_AUTH_SOCK" ]; then
    eval "$(ssh-agent -s)"
fi

# Methode 2 : reutiliser un agent existant (recommande)
SSH_ENV="$HOME/.ssh/agent-env"
if [ -f "$SSH_ENV" ]; then
    . "$SSH_ENV" > /dev/null
    if ! kill -0 "$SSH_AGENT_PID" 2>/dev/null; then
        eval "$(ssh-agent -s)" > /dev/null
        echo "export SSH_AUTH_SOCK=$SSH_AUTH_SOCK" > "$SSH_ENV"
        echo "export SSH_AGENT_PID=$SSH_AGENT_PID" >> "$SSH_ENV"
    fi
else
    eval "$(ssh-agent -s)" > /dev/null
    echo "export SSH_AUTH_SOCK=$SSH_AUTH_SOCK" > "$SSH_ENV"
    echo "export SSH_AGENT_PID=$SSH_AGENT_PID" >> "$SSH_ENV"
fi

8.2 Gerer les cles avec ssh-add

# Ajouter la cle par defaut (~/.ssh/id_ed25519 ou id_rsa)
ssh-add

# Ajouter une cle specifique
ssh-add ~/.ssh/id_ed25519_prod

# Ajouter toutes les cles du repertoire ~/.ssh/
ssh-add ~/.ssh/id_*

# Lister les cles chargees dans l'agent
ssh-add -l

# Lister avec les cles publiques completes
ssh-add -L

# Supprimer une cle de l'agent
ssh-add -d ~/.ssh/id_ed25519_prod

# Supprimer toutes les cles de l'agent
ssh-add -D

# Ajouter une cle avec un delai d'expiration (en secondes)
ssh-add -t 3600 ~/.ssh/id_ed25519    # La cle expire apres 1 heure

# Verrouiller l'agent avec un mot de passe
ssh-add -x
# Deverrouiller
ssh-add -X

8.3 Agent Forwarding

Le forwarding de l'agent permet d'utiliser vos cles SSH locales sur un serveur distant, sans copier vos cles privees sur ce serveur. Tres utile pour les rebonds multiples et les operations Git depuis un serveur.

# Activer le forwarding pour une connexion
ssh -A utilisateur@serveur-intermediaire

# Depuis le serveur intermediaire, vous pouvez maintenant :
# - Vous connecter a un autre serveur avec vos cles locales
ssh utilisateur@serveur-final
# - Faire un git pull/push avec votre cle
git pull origin main

# Configuration permanente dans ~/.ssh/config
Host serveur-intermediaire
    HostName 10.0.0.1
    User admin
    ForwardAgent yes

# Verifier que le forwarding fonctionne (sur le serveur distant)
ssh-add -l    # Doit lister vos cles locales
Attention : n'activez le forwarding d'agent (-A / ForwardAgent yes) que vers des serveurs de confiance. Un administrateur root malveillant sur le serveur intermediaire pourrait utiliser votre agent pour s'authentifier en votre nom sur d'autres serveurs. Privilegiez ProxyJump quand c'est possible.

8.4 Agent SSH sous systemd (Linux)

# Creer un service utilisateur pour l'agent SSH
# ~/.config/systemd/user/ssh-agent.service
[Unit]
Description=SSH Agent

[Service]
Type=simple
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
ExecStart=/usr/bin/ssh-agent -D -a $SSH_AUTH_SOCK

[Install]
WantedBy=default.target
# Activer et demarrer le service
systemctl --user enable ssh-agent
systemctl --user start ssh-agent

# Ajouter dans ~/.bashrc ou ~/.zshrc
export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket"

9. SCP et SFTP (transfert de fichiers)

9.1 SCP (Secure Copy)

SCP permet de copier des fichiers entre machines via SSH. Syntaxe similaire a cp.

# === COPIE VERS LE SERVEUR (upload) ===

# Copier un fichier local vers le serveur
scp fichier.tar.gz utilisateur@serveur:/home/utilisateur/
scp fichier.tar.gz utilisateur@serveur:~/

# Copier vers un chemin specifique
scp backup.sql admin@serveur:/var/backups/

# Copier un repertoire entier (recursif)
scp -r /var/www/monsite/ admin@serveur:/var/www/

# === COPIE DEPUIS LE SERVEUR (download) ===

# Telecharger un fichier du serveur
scp utilisateur@serveur:/var/log/syslog ./logs/

# Telecharger un repertoire entier
scp -r utilisateur@serveur:/etc/nginx/ ./backup-nginx/

# === OPTIONS COURANTES ===

# Specifier le port
scp -P 2222 fichier.tar.gz admin@serveur:~/

# Specifier la cle privee
scp -i ~/.ssh/id_ed25519 fichier.tar.gz admin@serveur:~/

# Limiter la bande passante (en Kbit/s)
scp -l 5000 gros-fichier.iso admin@serveur:~/

# Compresser pendant le transfert
scp -C fichier.tar.gz admin@serveur:~/

# Copier entre deux serveurs distants (via votre machine)
scp utilisateur@serveur1:/data/dump.sql utilisateur@serveur2:/backups/

# Mode verbose
scp -v fichier.tar.gz admin@serveur:~/

# Preserver les attributs (date de modification, permissions)
scp -p fichier.conf admin@serveur:/etc/app/
Astuce : pour les transferts reguliers ou volumineux, privilegiez rsync plutot que scp. Rsync est incremental (ne transfere que les differences), supporte la reprise en cas d'interruption, et offre plus d'options : rsync -avz -e "ssh -p 2222" /source/ user@serveur:/destination/

9.2 SFTP (SSH File Transfer Protocol)

SFTP offre une session interactive pour naviguer et transferer des fichiers, similaire a un client FTP classique.

# Ouvrir une session SFTP
sftp utilisateur@serveur

# Avec un port specifique
sftp -P 2222 utilisateur@serveur

# Avec une cle specifique
sftp -i ~/.ssh/id_ed25519 utilisateur@serveur

Commandes SFTP interactives

# Navigation
sftp> pwd                      # Repertoire courant (distant)
sftp> lpwd                     # Repertoire courant (local)
sftp> ls                       # Lister les fichiers (distant)
sftp> lls                      # Lister les fichiers (local)
sftp> cd /var/www              # Changer de repertoire (distant)
sftp> lcd ~/downloads          # Changer de repertoire (local)

# Transfert
sftp> put fichier.tar.gz       # Upload un fichier
sftp> put -r mon-dossier/      # Upload un repertoire
sftp> get backup.sql           # Download un fichier
sftp> get -r logs/             # Download un repertoire
sftp> mput *.conf              # Upload multiple (wildcard)
sftp> mget *.log               # Download multiple (wildcard)

# Gestion de fichiers distants
sftp> mkdir nouveau-dossier    # Creer un repertoire
sftp> rmdir dossier-vide       # Supprimer un repertoire vide
sftp> rm fichier.tmp           # Supprimer un fichier
sftp> rename ancien nouveau    # Renommer
sftp> chmod 644 fichier.conf   # Changer les permissions
sftp> chown user:group fichier # Changer le proprietaire

# Divers
sftp> df -h                    # Espace disque sur le serveur
sftp> !commande_locale         # Executer une commande locale
sftp> exit                     # Quitter (ou bye, quit)

9.3 SFTP en mode batch (non interactif)

# Creer un fichier de commandes batch
cat > sftp-batch.txt << 'EOF'
cd /var/backups
put backup-2025-01-15.sql.gz
chmod 600 backup-2025-01-15.sql.gz
ls -la
bye
EOF

# Executer en mode batch
sftp -b sftp-batch.txt utilisateur@serveur

10. ProxyJump / Bastion Host

Un bastion host (ou jump host) est un serveur intermediaire qui sert de point d'entree securise vers un reseau interne. ProxyJump est la methode moderne pour realiser des rebonds SSH.

10.1 Architecture typique

# Schema reseau classique avec bastion :
#
# [Internet] --> [Bastion / Jump Host] --> [Reseau interne]
#                 (IP publique)             (IPs privees)
#                 bastion.example.com       10.0.0.x
#
# Seul le bastion est expose sur Internet (port SSH uniquement).
# Les serveurs internes ne sont accessibles que via le bastion.

10.2 ProxyJump en ligne de commande (-J)

# Syntaxe : ssh -J user@bastion user@cible

# Connexion a un serveur interne via le bastion
ssh -J admin@bastion.example.com admin@10.0.0.50

# Avec un port personnalise sur le bastion
ssh -J admin@bastion.example.com:2222 admin@10.0.0.50

# Rebond multiple (bastion1 -> bastion2 -> cible)
ssh -J admin@bastion1.example.com,admin@bastion2.internal admin@10.0.0.50

# SCP via ProxyJump
scp -J admin@bastion.example.com fichier.tar.gz admin@10.0.0.50:~/

# SFTP via ProxyJump
sftp -J admin@bastion.example.com admin@10.0.0.50

10.3 Configuration dans ~/.ssh/config

# ~/.ssh/config

# Definition du bastion
Host bastion
    HostName bastion.example.com
    User admin
    Port 2222
    IdentityFile ~/.ssh/id_ed25519_bastion

# Serveurs internes accessibles via le bastion
Host srv-web-01
    HostName 10.0.0.50
    User deploy
    ProxyJump bastion

Host srv-db-01
    HostName 10.0.0.60
    User dba
    ProxyJump bastion

Host srv-app-*
    User deploy
    ProxyJump bastion

Host srv-app-01
    HostName 10.0.0.70

Host srv-app-02
    HostName 10.0.0.71

# Connexion directe : ssh srv-web-01
# Equivalent a : ssh -J admin@bastion.example.com:2222 deploy@10.0.0.50

10.4 Ancienne methode : ProxyCommand

ProxyJump est un raccourci pour ProxyCommand. L'ancienne syntaxe est encore utile pour les systemes avec OpenSSH < 7.3 :

# Equivalent de ProxyJump avec ProxyCommand
Host srv-web-01
    HostName 10.0.0.50
    User deploy
    ProxyCommand ssh -W %h:%p admin@bastion.example.com

# Avec netcat (systemes tres anciens)
Host srv-web-01
    HostName 10.0.0.50
    User deploy
    ProxyCommand ssh admin@bastion.example.com nc %h %p

10.5 Securiser le bastion

# /etc/ssh/sshd_config du bastion - Restrictions recommandees

# Authentification par cle uniquement
PasswordAuthentication no
PubkeyAuthentication yes

# Limiter les utilisateurs autorises
AllowUsers admin jump-user

# Desactiver les fonctionnalites inutiles
X11Forwarding no
PermitTunnel no

# Autoriser le forwarding TCP (necessaire pour ProxyJump)
AllowTcpForwarding yes

# Limiter la duree des sessions
ClientAliveInterval 180
ClientAliveCountMax 2

# Logger toutes les connexions
LogLevel VERBOSE

# Optionnel : forcer un shell restreint pour les utilisateurs de rebond
Match User jump-user
    ForceCommand /bin/false
    AllowTcpForwarding yes
    PermitOpen 10.0.0.0/24:22
Astuce : ProxyJump est toujours preferable a ForwardAgent pour les rebonds. Avec ProxyJump, la connexion est chiffree de bout en bout entre votre poste et la cible finale. La cle privee ne quitte jamais votre machine, contrairement au forwarding d'agent qui expose le socket de l'agent sur le serveur intermediaire.

11. Depannage

11.1 Mode verbose (-v, -vv, -vvv)

Le mode verbose est votre premier reflexe en cas de probleme de connexion SSH.

# Niveau 1 : informations generales
ssh -v utilisateur@serveur

# Niveau 2 : plus de details sur les echanges
ssh -vv utilisateur@serveur

# Niveau 3 : debug complet (tres detaille)
ssh -vvv utilisateur@serveur

# Rediriger la sortie debug dans un fichier pour analyse
ssh -vvv utilisateur@serveur 2> /tmp/ssh-debug.log

# Ce qu'il faut chercher dans la sortie :
# - "Offering public key" : SSH propose vos cles
# - "Server accepts key" : la cle est acceptee
# - "Authentication succeeded" : connexion reussie
# - "Permission denied" : echec d'authentification
# - "Connection refused" : port ferme ou service arrete
# - "Connection timed out" : probleme reseau ou firewall

11.2 Problemes de permissions

# Erreur typique :
# "WARNING: UNPROTECTED PRIVATE KEY FILE!"
# "Permissions 0644 for '/home/user/.ssh/id_ed25519' are too open."
# "It is required that your private key files are NOT accessible by others."

# Solution : corriger les permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_ed25519.pub
chmod 644 ~/.ssh/id_rsa.pub
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/config
chmod 644 ~/.ssh/known_hosts

# Verifier les permissions du repertoire home (cote serveur)
# Le home ne doit PAS etre en ecriture par le groupe ou les autres
chmod go-w /home/utilisateur
ls -la /home/ | grep utilisateur

11.3 Gestion du fichier known_hosts

# Erreur typique apres reinstallation d'un serveur :
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# @    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

# Supprimer l'ancienne empreinte d'un serveur specifique
ssh-keygen -R serveur.example.com
ssh-keygen -R 192.168.1.100

# Supprimer par numero de ligne
# (le message d'erreur indique la ligne fautive, ex: "line 42")
sed -i '42d' ~/.ssh/known_hosts

# Afficher l'empreinte d'un serveur (sans se connecter)
ssh-keyscan -t ed25519 serveur.example.com
ssh-keyscan -H serveur.example.com >> ~/.ssh/known_hosts

# Verifier l'empreinte d'un serveur
ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key.pub    # Sur le serveur

# Desactiver la verification (UNIQUEMENT pour les tests)
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null user@host
Attention : ne desactivez StrictHostKeyChecking que dans un environnement de test controle. En production, ce mecanisme vous protege contre les attaques Man-in-the-Middle. Si l'empreinte change de maniere inattendue, verifiez la legitimite du changement avant de supprimer l'ancienne empreinte.

11.4 Diagnostic cote serveur

# Verifier que le service SSH est actif
sudo systemctl status ssh       # Debian/Ubuntu
sudo systemctl status sshd      # CentOS/RHEL

# Verifier que SSH ecoute sur le bon port
sudo ss -tlnp | grep ssh
# ou
sudo netstat -tlnp | grep ssh

# Consulter les logs d'authentification
# Debian/Ubuntu :
sudo tail -50 /var/log/auth.log | grep ssh
# CentOS/RHEL :
sudo tail -50 /var/log/secure | grep ssh
# systemd (toutes distributions) :
sudo journalctl -u ssh -n 50 --no-pager
sudo journalctl -u sshd -n 50 --no-pager

# Suivre les logs en temps reel pendant un test de connexion
sudo tail -f /var/log/auth.log

# Tester la configuration sshd sans redemarrer
sudo sshd -t
# Mode test verbose (affiche la configuration complete)
sudo sshd -T

# Demarrer sshd temporairement en mode debug sur un port alternatif
# (utile quand la connexion principale ne fonctionne plus)
sudo /usr/sbin/sshd -d -p 2233

11.5 Problemes courants et solutions

Probleme Cause probable Solution
Connection refused Service SSH arrete ou port incorrect sudo systemctl start ssh et verifier le port
Connection timed out Firewall bloque le port ou serveur injoignable Verifier le firewall (ufw status), tester avec telnet host 22
Permission denied (publickey) Cle non installee, permissions incorrectes, ou mauvais utilisateur Verifier authorized_keys, les permissions, et l'utilisateur
Permission denied (password) Mot de passe incorrect ou authentification par mot de passe desactivee Verifier PasswordAuthentication dans sshd_config
Host key verification failed L'empreinte du serveur a change ssh-keygen -R hostname (apres verification)
Too many authentication failures Trop de cles proposees avant la bonne Utiliser -i cle ou IdentitiesOnly yes dans le config
Connexion tres lente (10+ secondes) Resolution DNS inverse sur le serveur Ajouter UseDNS no dans sshd_config
Deconnexion apres inactivite Timeout du serveur ou du reseau ServerAliveInterval 60 dans le config client
broken pipe Connexion coupee (reseau, timeout) Ajouter ServerAliveInterval et ServerAliveCountMax
Agent forwarding ne fonctionne pas Agent non demarre ou forwarding desactive cote serveur Verifier ssh-add -l, AllowAgentForwarding yes

11.6 Checklist de diagnostic rapide

# 1. Le serveur est-il joignable ?
ping serveur.example.com

# 2. Le port SSH est-il ouvert ?
nc -zv serveur.example.com 22
# ou
telnet serveur.example.com 22
# ou (si nmap est installe)
nmap -p 22 serveur.example.com

# 3. Le service SSH tourne-t-il ? (sur le serveur)
sudo systemctl status ssh

# 4. Le firewall laisse-t-il passer le trafic ?
sudo ufw status                          # UFW
sudo firewall-cmd --list-all             # firewalld
sudo iptables -L -n | grep 22           # iptables

# 5. Les permissions sont-elles correctes ? (sur le serveur)
ls -la ~/.ssh/
ls -la ~/.ssh/authorized_keys

# 6. La cle publique est-elle dans authorized_keys ? (sur le serveur)
grep "votre-commentaire-de-cle" ~/.ssh/authorized_keys

# 7. La configuration sshd est-elle valide ?
sudo sshd -t

# 8. Les logs donnent-ils des indices ?
sudo tail -20 /var/log/auth.log
Astuce : en cas de perte totale d'acces SSH, utilisez la console de votre fournisseur (KVM, iLO, iDRAC, console VPS, etc.) pour acceder au serveur et corriger la configuration. Testez toujours les modifications SSH dans une nouvelle session en gardant l'ancienne ouverte.