Login Logout

Howto OpenSSH

OpenSSH est l’implémentation la plus répandue du protocole SSH permettant de se connecter sur une machine à travers le réseau de manière sécurisée. OpenSSH est développé par le projet OpenBSD avec une grande attention sur la sécurité. Il offre de nombreuses fonctionnalités : SCP, SFTP, clés SSH, tunnels, VPN, etc.

Installation

Debian

On peut installer les parties client et serveur indépendamment :

# apt install openssh-client
# ssh -V
OpenSSH_7.4p1 Debian-10+deb9u1, OpenSSL 1.0.2l  25 May 2017

# apt install openssh-server
# nc localhost 22
SSH-2.0-OpenSSH_7.4p1 Debian-10+deb9u1
# systemctl status ssh
● ssh.service - OpenBSD Secure Shell server
   Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
 Main PID: 1715 (sshd)
    Tasks: 1 (limit: 4915)
   CGroup: /system.slice/ssh.service
           └─1715 /usr/sbin/sshd -D

OpenBSD

Les parties client et serveur sont incluses dans la base OpenBSD.

$ ssh -V
OpenSSH_7.5, LibreSSL 2.5.2

La partie serveur est activée par défaut, sauf mention contraire à l’installation.

# grep -r sshd /etc/rc.conf*
/etc/rc.conf:sshd_flags=
/etc/rc.conf.local:sshd_flags=NO

# rcctl enable sshd

Configuration

Configuration sshd_config

http://man.openbsd.org/sshd_config

Fichiers de configuration :

/etc/ssh
├── moduli
├── ssh_config
├── sshd_config
├── ssh_host_ecdsa_key
├── ssh_host_ecdsa_key.pub
├── ssh_host_ed25519_key
├── ssh_host_ed25519_key.pub
├── ssh_host_rsa_key
└── ssh_host_rsa_key.pub

La configuration de base que nous utilisons en général (les options commentées sont les valeurs par défaut).

#   $OpenBSD: sshd_config,v 1.100 2016/08/15 12:32:04 naddy Exp $

# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.

# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options override the
# default value.

Port 22
Port 2200
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
#HostKey /etc/ssh/ssh_host_ed25519_key

# Ciphers and keying
#RekeyLimit default none

# Logging
#SyslogFacility AUTH
LogLevel VERBOSE

# Authentication:

#LoginGraceTime 2m
PermitRootLogin no
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

#PubkeyAuthentication yes

# Expect .ssh/authorized_keys2 to be disregarded by default in future.
#AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2

#AuthorizedPrincipalsFile none

#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody

# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes

# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no

# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no

# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no

# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no

# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
UsePAM yes

#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
PrintMotd no
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
#UsePrivilegeSeparation sandbox
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none

# no default banner path
#Banner none

# Allow client to pass locale environment variables
#AcceptEnv LANG LC_*

# override default of no subsystems
Subsystem   sftp    /usr/lib/openssh/sftp-server -l INFO

# Example of overriding settings on a per-user basis
#Match User anoncvs
#   X11Forwarding no
#   AllowTcpForwarding no
#   PermitTTY no
#   ForceCommand cvs server

AllowUsers jdoe alice bob

Match Address 192.0.2.42
    PasswordAuthentication yes
Match User alice bob
    PasswordAuthentication no
Match Group adm
    PasswordAuthentication no

Configuration ssh_config

http://man.openbsd.org/ssh_config

On peut configurer la partie client via le fichier ~/.ssh/config.

On peut ainsi passer certaines options générales :

UseRoaming no
User jdoe
IdentityFile ~/.ssh/id_ed25519
IdentityFile ~/.ssh/id_rsa

On peut aussi passer des options spécifiques à chaque serveur distant sur lequel on va se connecter. On définit ainsi des alias (utilisables ensuite via ssh) et des options correspondantes :

Host foo ssh.example.com
    Hostname ssh.example.com
    Port 2222
    User john

Host sql.example.com
    IdentityFile ~/.ssh/id_bastion_ed25519
    ProxyCommand ssh bastion.example.com -W %h:%p
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null

Host nfs.example.com
    ProxyCommand ssh -W bastion.example.com:2222 john@192.0.2.111

Host switch42
    User admin
    HostName 192.0.2.150
    ProxyCommand sh -c "nc -w1 %h %p 2>/dev/null || ssh bastion.example.com -W %h:%p"
    KexAlgorithms diffie-hellman-group1-sha1

SCP

Le protocole SCP (Secure Copy) est basé sur SSH, il permet de transférer des fichiers entre deux machines distantes de façon sécurisée.

Utilisation simple :

$ scp /foo/FICHIER ssh.example.com:/bar/

Pour envoyer un répertoire, on utilisera l’option -r :

$ scp -r /foo/ ssh.example.com:/bar/

Options utiles pour scp :

  • -P 2222 : utilise le port 2222 pour le serveur distant (malheureusement différent de ssh…)
  • -q : mode silencieux
  • -C : active la compression
  • -i identity_file : utilise une clé SSH spécifique

SFTP

Le protocole SFTP correspond au SSH File Transfer Protocol : c’est une extension du protocole SSH qui permet non seulement de transférer des fichiers (comme SCP) mais aussi d’avoir des fonctionnalités plus avancées (listing de répertoire, suppression de fichiers, etc.) similaire au vieux protocole FTP :

$ sftp ssh.example.com
Connected to ssh.example.com.
sftp> ls
sftp> lls
sftp> pwd
sftp> get FICHIER
sftp> put FICHIER
sftp> bye

chroot SFTP

On peut restreindre un accès SFTP dans un répertoire, les utilisateurs n’auront accès qu’à une vue limitée de l’arborescence du système.

Pour mettre en place un chroot SFTP, on crée un répertoire /home/sftp et un groupe sftp :

# mkdir /home/sftp
# chown root:sftp /home/sftp
# chmod 750 /home/sftp

# groupadd sftp

et on configure via /etc/ssh/sshd_config :

Subsystem sftp internal-sftp

Match group sftp
   ChrootDirectory /home/sftp
   X11Forwarding no
   AllowTcpForwarding no
   ForceCommand internal-sftp

On peut ensuite créer un utilisateur restreint :

# useradd -g sftp -d /jdoe jdoe
# mkdir /home/sftp/jdoe/
# chown jdoe:sftp /home/sftp/jdoe/
# chmod 700 /home/sftp/jdoe/

SFTP Only

On peut restreindre un utilisateur au protocole SFTP. Il faut s’assurer que /usr/lib/sftp-server soit un shell valide et lui définir comme shell par défaut :

# echo '/usr/lib/stfp-server' >> /etc/shells
# usermod -s /usr/lib/sftp-server userna

Clé SSH

Il y a plusieurs types de clé, avec suivant les algorithmes, des tailles de clés variables ou non. L’algorithme que nous conseillons est ed25519 mais attention, ce n’est pas supporté sur des anciennes machines (Debian 7 par exemple) où il faut utiliser l’algorithme RSA (on conseille alors d’utiliser une taille de clé de 4096).

Pour générer une clé SSH ed25519 :

$ ssh-keygen -t ed25519 -a 100
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/jdoe/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/jdoe/.ssh/id_ed25519.
Your public key has been saved in /home/jdoe/.ssh/id_ed25519.pub.
The key fingerprint is:
SHA256:7tdFlczm4VJkEl4yM08O4VOPkGQiU1YR8kKuLsm9v84 jdoe@example.com
The key's randomart image is:
+--[ED25519 256]--+
|        o.*oB&**.|
|         * =+.#Oo|
|          o .+*+o|
|         . . .oo |
|        S    ..  |
|     . =      .  |
|      + +  . .   |
|       o o. .    |
|        o+E.     |
+----[SHA256]-----+

Note : l’option -a 100 spécifie le nombre d’itérations de l’algorithme de dérivation de clé qui protège la clé privée avec la passphrase utilisée. Cela protège la clé privée contre le brute-force de la passphrase. Mais attention, plus ce nombre est grand, plus le déchiffrement de la clé est ralenti. Un bon compromis est 100 en nombre d’itérations.

Pour générer une clé SSH RSA :

$ ssh-keygen -o -t rsa -b 4096 -a 100
Generating public/private rsa key pair.
Enter file in which to save the key (/home/jdoe/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/jdoe/.ssh/id_rsa.
Your public key has been saved in /home/jdoe/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:9tGKNLEbiUyAbhShJ7rncBpn/ydCXZHtJkdIsUoW2TM jdoe@example.com
The key's randomart image is:
+---[RSA 4096]----+
|  o+. .+o=       |
| .o  ...E.o      |
|oo.   + o*       |
|.oo  = oo++.     |
|..   .+.S+. .    |
| .  . .o * o     |
|+ =.    o o      |
| X .. . .        |
|. . .o.o         |
+----[SHA256]-----+

Note : dans le cas de RSA, on utilise l’argument -o afin que la clé privée utilise le nouveau format qui est à la fois standard et plus résistant aux attaques par brute-force.

authorized_keys

Pour autoriser une connexion avec une clé SSH, il faut la placer dans le fichier ~/.ssh/authorized_keys et ajuster les droits :

$ ssh ssh.example.com mkdir -p ~/.ssh
$ ssh ssh.example.com chmod 700 ~/.ssh
$ scp ~/.ssh/id_ed25519.pub ssh.example.com:.ssh/authorized_keys
$ ssh ssh.example.com chmod 600 ~/.ssh/authorized_keys

Pour faire cela de façon plus simple, on peut utiliser le script ssh-copy-id :

$ ssh-copy-id ssh.example.com

Note : pour préciser un port alternatif, on peut utiliser l’option -p NN depuis Debian 8. En Debian 7, il faut utiliser ssh-copy-id "-pNN ssh.example.com"

On peut mettre des restrictions d’accès via le fichier .ssh/authorized_keys, par exemple :

no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa XXXXX commentaires

Agent SSH

Il est important de protéger une clé SSH utilisée par un humain par une passphrase. Pour éviter de saisir sa passphrase à chaque utilisation, on peut utiliser un agent SSH qui va retenir la clé SSH en mémoire.

En général, un agent SSH est lancé par son Window Manager. Sinon, on peut le lancer automatiquement via son ~/.profile :

eval $(ssh-agent) 1> /dev/null

Une fois lancé, l’agent ouvre une socket Unix dans $TMPDIR/ssh-XXXXXXXXXX/agent.PPID et la rend disponible via les variables d’environnement suivantes :

SSH_AUTH_SOCK=/tmp/ssh-IklIVmCGvWgT/agent.1151
SSH_AGENT_PID=1198

On peut alors lancer la commande ssh-add qui va nous demander notre passphrase pour transmettre la clé à l’agent SSH :

$ ssh-add -t 36000
Enter passphrase for /home/jdoe/.ssh/id_ed25519:
Identity added: /home/jdoe/.ssh/id_ed25519 (/home/jdoe/.ssh/id_ed25519)

Note : l’option -t permet de limiter à 10h (36 000 secondes) le temps où l’agent va conserver la passphrase en mémoire. Si l’option n’est pas utilisée, ce temps sera infini, ce que l’on déconseille en général.

On peut également utiliser l’outil keychain qui facilite l’utilisation d’un agent SSH (et d’un agent GPG). Il va notamment lancer les agents si ils ne sont pas encore lancés, et transmettre plusieurs clés SSH si besoin.

$ keychain id_ed25519 id_rsa --timeout 600

 * keychain 2.7.1 ~ http://www.funtoo.org
 * Starting ssh-agent...
 * Starting gpg-agent...
 * Adding 2 ssh key(s): /home/jdoe/.ssh/id_ed25519 /home/jdoe/.ssh/id_rsa
Enter passphrase for /home/jdoe/.ssh/id_ed25519:
 * ssh-add: Identities added: /home/jdoe/.ssh/id_ed25519 /home/jdoe/.ssh/id_rsa (life=600m)

Note : on pourra bien sûr lancer keychain via son ~/.profile

Enfin, il existe d’autres implémentations d’agent SSH, comme le gpg-agent qui permet notamment l’utilisation de token USB pour sécuriser ses clés (Voir HowtoGPG).

Tunnel SSH

Un tunnel SSH permet d’accéder à une ressource distante via une connexion SSH. Cela s’utilise classiquement pour accéder à un service distant non accessible directement.

Tunnel SSH vers un service

Exemple simple : on veut accéder à un service MySQL accessible en local sur un serveur distant. On lance la commande suivante :

$ ssh -L 3306:127.0.0.1:3306 ssh.example.com

Et l’on pourra accéder au service MySQL sur sa propre machine via 127.0.0.1 sur le port 3306.

Si le service MySQL est sur une 3ème machine (accessible depuis le serveur distant), il suffit de préciser son IP avec l’option -L :

$ ssh -L 3306:192.0.2.33:3306 ssh.example.com

On peut bien sûr utiliser un port différent pour sa propre machine, par exemple 8306 :

$ ssh -L 8306:192.0.2.33:3306 ssh.example.com

De même, si l’on veut se « binder » sur une autre IP que 127.0.0.1 sur sa propre machine, on peut le préciser avec l’option -L :

$ ssh -L 127.0.0.33:8306:192.0.2.33:3306 ssh.example.com

Enfin il faut noter que si l’on veut utiliser un port local inférieur à 1024, il faudra lancer la commande en “root” :

# ssh -L 443:127.0.0.1:443 ssh.example.com

Tunnel SSH inverse

Si l’on est derrière une connexion NAT par exemple, on peut ouvrir un tunnel pour permettre une connexion distante depuis une machine accessible en SSH :

$ ssh -R 22000:127.0.0.1:22 ssh.example.com

Depuis ssh.example.com on peut ainsi accéder à la machine derrière le NAT via ssh -p22000 127.0.0.1.

Proxy SOCKS via SSH

On peut lancer un proxy SOCKS passant par un serveur distant ainsi :

$ ssh -D 6789 ssh.example.com

Il reste ensuite à configurer le logiciel qui va utiliser ce proxy SOCKS (4a ou 5) avec l’adresse 127.0.0.1 et le port 6789. C’est ainsi pratique avec un navigateur où l’ensemble du trafic vers le web passera ainsi par le serveur distant.

Astuces

Séquences d’échappement SSH

https://lonesysadmin.net/2011/11/08/ssh-escape-sequences-aka-kill-dead-ssh-sessions/

On peut utiliser des combinaisons de touches spéciales via une connexion SSH pour intéragir avec la connexion en cours.

En tapant Entrée + ~ + ? on obtient la liste des séquences possibles :

Supported escape sequences:
 ~.   - terminate connection (and any multiplexed sessions)
 ~B   - send a BREAK to the remote system
 ~C   - open a command line
 ~R   - request rekey
 ~V/v - decrease/increase verbosity (LogLevel)
 ~^Z  - suspend ssh
 ~#   - list forwarded connections
 ~&   - background ssh (when waiting for connections to terminate)
 ~?   - this message
 ~~   - send the escape character by typing it twice
(Note that escapes are only recognized immediately after newline.)

Voici les séquences les plus utiles :

  • Entrée + ~ + . : forcer à terminer la connexion SSH en cours (utile en cas de perte de connexion…)
  • Entrée + ~ + v : diminue la verbosité, par exemple quand on s’est connecté avec ssh -vvv

Quelques exemples de manipulations possibles (en anglais) : https://omecha.info/blog/ssh-escape-commands-for-fun-and-profit.html

Connexion SSH par rebond

Il se peut qu’on doive passer par une machine pour se connecter en SSH à une machine cible (c’est le principe d’un bastion).

On peut ainsi se connecter avec -o ProxyCommand :

ssh -o ProxyCommand=“ssh -W cible.example.com:22 bastion.example.com” cible.example.com

Dans les versions récentes d’OpenSSH (notamment sur Debian 9) il existe une méthode plus simple :

$ ssh -J bastion.example.com cible.example.com

Note : il ne faut pas utiliser l’option -A pour rebondir car elle est dangereuse, à moins que vous ne vouliez vraiment faire du Agent forwarding

Agent forwarding

Si vous voulez utiliser une clé SSH locale depuis un serveur distant, vous pouvez utiliser l’option -A qui va rendre votre agent local accessible depuis le serveur distant :

$ ssh -A ssh.example.com
$ env | grep ^SSH_A
SSH_AUTH_SOCK=/tmp/ssh-sUSruIwyCa/agent.3265

Note : attention, cette option doit être utilisée en connaissance de cause car l’utilisateur root sur la machine ssh.example.com aura accès à vos clés et donc aux machines distantes auxquelles vous avez accès avec vos clés.

On peut également ajouter les clés SSH présentes sur un serveur distant en faisant :

$ ssh ssh.example.com -t -A ssh-add

VPN over SSH

On peut utiliser OpenSSH comme VPN ! Côté serveur, vous devez :

  • Ajouter PermitTunnel yes
  • Autoriser l’IP Forwarding : sysctl -w net.ipv4.ip_forward=1
  • Si besoin, mettre une règle de NAT, par exemple sous Linux : iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Pour lancer la connexion VPN, on fera :

# ssh -w 42:42 ssh.example.com

On a ensuite un périphérique tun42 utilisable, à configurer des 2 côtés.

  • Côté serveur SSH : ifconfig tun42 172.17.18.2/24
  • Côté client SSH : ifconfig tun42 172.17.18.1/24

On peut alors enfin configurer le routage au niveau client, par exemple sous Linux :

# ip route add 8.8.8.8/32 via 172.17.18.2 dev tun42`

UserKnownHostsFile

OpenSSH se sert du fichier ~/.ssh/known_hosts pour retenir l’empreinte (fingerprint) de chaque connexion effectuée. Cela lui permet de détecter un changement des clés du serveur, notamment une tentative d’usurpation d’un serveur :

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.

Si besoin, on peut supprimer la ligne concernée dans ~/.ssh/known_hosts via la commande :

$ ssh-keygen -f "~/.ssh/known_hosts" -R ssh.example.com

On peut également désactiver cette vérification en utilisant un fichier alternatif :

$ ssh -o UserKnownHostsFile=/dev/null ssh.example.com

On peut également générer à l’avance les fingerpints dans un fichier ~/.ssh/known_hosts2 (utilisé par défaut).

Pour générer les fingerprints, on peut utiliser la commande ssh-keyscan :

$ ssh-keyscan ssh.example.com
ssh.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2nP2WzQ8hkZDiEq5+QSGFhTB7SYfRa7/IG0gMOIoCDXH8b3sfsBUUEL8ZSFaWgNKskUnpgg/fqAhvnDLOPskr3OGXRfrCR68fCqn5H1zBrHB1kpdjPW9ezUe1xoY3hGp6LITANHWpZie1wBjYAzaBO70hNAo4JMCQvZXDsQdyws2DRSuYtiAoG/ZY0+t2VZh3MJLcofv1wNo43M+aHJR2xWmQSE7cWjMlcw/QOmsWJBv1+Kb/nK2Q7buX/byvY8ySu5ydATnyEinzbutZXc/t/FioOtWMeqh6NlD3aPGIpUTmf8ow+c1QwZWOC3T2GWyTD5KVmAZSm77lWkpYFcd1
ssh.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBsUneE642qr/kzKwJcKl9Cgog/kgCqRLZwZs4J7RRt8

Puis on crée un fichier contenant :

example-ssh,ssh.example.com,192.0.2.42 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2nP2WzQ8hkZDiEq5+QSGFhTB7SYfRa7/IG0gMOIoCDXH8b3sfsBUUEL8ZSFaWgNKskUnpgg/fqAhvnDLOPskr3OGXRfrCR68fCqn5H1zBrHB1kpdjPW9ezUe1xoY3hGp6LITANHWpZie1wBjYAzaBO70hNAo4JMCQvZXDsQdyws2DRSuYtiAoG/ZY0+t2VZh3MJLcofv1wNo43M+aHJR2xWmQSE7cWjMlcw/QOmsWJBv1+Kb/nK2Q7buX/byvY8ySu5ydATnyEinzbutZXc/t/FioOtWMeqh6NlD3aPGIpUTmf8ow+c1QwZWOC3T2GWyTD5KVmAZSm77lWkpYFcd1
example-ssh,ssh.example.com,192.0.2.42 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBsUneE642qr/kzKwJcKl9Cgog/kgCqRLZwZs4J7RRt8

Ce fichier contenant les fingerprints peut aussi être placé dans /etc/ssh/ssh_known_hosts ou /etc/ssh/ssh_known_hosts2 et sera ainsi utilisé par défaut par tous les utilisateurs d’une machine.

Une autre technique pour vérifier un fingerprint est d’avoir des enregistrements DNS SSHFP. On peut les générer à l’aide de la commande ssh-keygen :

$ ssh-keygen -r ssh.example.com
ssh.example.com IN SSHFP 1 1 b0db7dbfe0775199662453c9d6eace6f993b9fdc
ssh.example.com IN SSHFP 1 2 13e60f2c4d2848aea91c420b783273afe6c23efd23818ab220f167a53a0be886
ssh.example.com IN SSHFP 2 1 c2ea7d50f05af4cabc8e6add3491a08654127f83
ssh.example.com IN SSHFP 2 2 1222b6f7ad0d3447a31e3cba1af2eaf8aab7316570b63cc3eccdd4d865fee474
ssh.example.com IN SSHFP 3 1 d93dbd0af9c7fd456b3fa4e9094ede031791da84
ssh.example.com IN SSHFP 3 2 3b885c365ae3cebab6dea63b3eb697d2060d9da906e129011841d665a4ccfe4f
ssh.example.com IN SSHFP 4 1 39d521c3d4b6f672149c1cc053014c9ebdfd4727
ssh.example.com IN SSHFP 4 2 0f28d1764793b519c9c74bfb7c6d0dc9b980bdf22c68d1e324d19247d8cbe161

On peut ainsi vérifier à la connexion :

$ ssh -o "VerifyHostKeyDNS ask" ssh.example.com
The authenticity of host 'ssh.example.com (192.0.2.42)' can't be established.
ED25519 key fingerprint is SHA256:sln94vzrKSsTezPvT6pyO/Glavvl7/Ao8Wcd46BeRb0.
Matching host key fingerprint found in DNS.
Are you sure you want to continue connecting (yes/no)?

ControlMaster

OpenSSH peut permettre de réutiliser une connexion en cours pour d’autres connexions via l’option ControlMaster. Si l’on veut activer ce comportement, on pourra ajouter dans ~/.ssh/config :

ControlMaster auto
ControlPath ~/.ssh/ssh_control_%h_%p_%r

SSHFS

SSHFS permet de créer des montages via une connexion SSH :

# apt install sshfs
$ sshfs ssh.example.com:/foo/bar /mnt
$ fusermount -u /mnt/ssh

X Forwarding

SSH peut créer automatiquement un tunnel et gérer la variable $DISPLAY pour afficher en local les applications graphiques distantes. Côté serveur, il faut la présence du package xauth et l’option X11Forwarding yes dans la configuration SSH. On peut alors lancer :

$ ssh -X ssh.example.com
$ xlogo

mosh

https://mosh.org/

En cas de connexion réseau avec une latence ou de la perte de paquets, une alternative à OpenSSH est mosh.

FAQ

Obtenir l’empreinte de la clé publique du serveur

$ ssh-keygen -lf /etc/ssh/clé.pub

Regénérer les clés du serveur

Sous Debian :

# rm -i /etc/ssh/ssh_host_*
# dpkg-reconfigure openssh-server
Creating SSH2 RSA key; this may take some time ...
Creating SSH2 DSA key; this may take some time ...
Restarting OpenBSD Secure Shell server: sshd.

Sous OpenBSD :

# rm -i /etc/ssh/ssh_host_*
# ssh-keygen -A
ssh-keygen: generating new host keys: RSA DSA ECDSA ED25519

À noter que c’est fait à chaque boot (via /etc/rc), si les clés n’existent pas donc une autre solution est de supprimer les clés et de rebooter.

reload/restart le démon ssh sur Debian sans passer par le script d’init

Pour reload :

# start-stop-daemon --stop --signal 1 --quiet --oknodo --pidfile /var/run/sshd.pid --exec /usr/sbin/sshd

Pour redémarrer :

# start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile /var/run/sshd.pid
# start-stop-daemon --start --quiet --pidfile /var/run/sshd.pid --exec /usr/sbin/sshd

Peut-on encore utiliser une clé SSH DSA ?

Les clés SSH avec l’algorithme DSA sont dépréciées depuis Stretch.

Limitation du temps de connexion via SSH

On peut limiter le temps d’une connexion SSH inactive en utilisant la variable d’environnement TMOUT. On peut provoquer une déconnexion automatique au bout d’1h d’activité en positionnant :

export TMOUT=3600

À l’inverse, si l’on veut éviter une déconnexion automatique quand cette variable est positionnée, on peut la supprimer ou l’augmenter :

$ unset TMOUT
$ export TMOUT=999999

Comment lister les clés SSH en mémoire d’un agent SSH ?

On peut utiliser la commande ssh-add -l :

$ ssh-add -l
256 71:fd:ba:ef:aa:94:27:14:05:d8:b6:db:28:e4:65:c2 /home/jdoe/.ssh/id_ed25519 (ED25519)
2048 2b:c8:ae:c0:d3:25:93:83:d4:41:4d:21:1e:80:2f:f4 rsa w/o comment (RSA)

À noter que l’on peut forcer un agent SSH à oublier les clés SSH à l’aide d’une des deux commandes suivantes :

$ ssh-add -D
All identities removed.

$ keychain --clear
 * ssh-agent: All identities removed.
 * gpg-agent: All identities removed.

On peut aussi verrouiller temporairement son agent SSH via :

$ ssh-add -x
Enter lock password:
Again:
Agent locked.

$ ssh-add -l
The agent has no identities.

$ ssh-add -X
Enter lock password:
Agent unlocked.

Comment protéger un serveur SSH des attaques ?

Voici plusieurs méthodes pour protéger son serveur SSH (qui peuvent se cumuler)

  • ne pas ouvrir son port SSH à l’extérieur à l’exception de certaines adresses IP
  • modifier le port d’écoute de son serveur SSH pour diminuer un peu les attaques automatiques (Port 2200 dans sshd_config)
  • utiliser du Port Knocking pour camoufler son port SSH
  • ne pas autoriser les connexions SSH avec un mot de passe (PasswordAuthentication no dans sshd_config)
  • configurer Fail2Ban pour bannir les adresses IP qui se trompent de mot de passe