855 lines
27 KiB
Markdown
855 lines
27 KiB
Markdown
---
|
||
categories: OpenBSD sysadmin
|
||
title: Howto OpenSSH
|
||
...
|
||
|
||
* Documentation : <https://www.openssh.com/manual.html>
|
||
|
||
[OpenSSH](https://www.openssh.com/) 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](HowtoOpenBSD) 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](HowtoOpenSSH#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).
|
||
|
||
Attention, lors de la génération de votre paire de clés, si vous ne conservez pas le nom et l'emplacement par défaut ( qui est sous la forme `~/.ssh/id_{rsa,ed25519}`) alors la clé ne sera pas utilisée par le client SSH. Il faudra alors lui indiquer de l'utiliser de manière explicite avec avec l'argument *-i* pour spécifier la clé privée, ou le définir dans le [fichier de configuration de SSH](#configuration-ssh_config),
|
||
|
||
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`](http://man.openbsd.org/ssh-keygen#o) afin que la clé privée utilise le nouveau format qui est à la fois [standard](https://tools.ietf.org/html/rfc4716) 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` :
|
||
|
||
~~~{.bash}
|
||
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 :
|
||
|
||
~~~{.bash}
|
||
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](http://man.openbsd.org/ssh-agent#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](https://www.funtoo.org/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](HowtoGPG#agent-gpg)).
|
||
|
||
|
||
## 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
|
||
|
||
### Loguer/exécuter script avant chaque connexions SSH
|
||
|
||
Grâce au fichier placé dans ~~~/etc/ssh/sshrc~~~, juste avant toutes connexions ssh (rsync, sftp, ssh, ...), le contenu sera exécuté avant la session ssh ouverte.
|
||
|
||
### 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](https://fr.wikipedia.org/wiki/Bastion_(informatique))).
|
||
|
||
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](HowtoOpenSSH#agent-forwarding)
|
||
|
||
### Agent forwarding
|
||
|
||
Si vous voulez utiliser une [clé SSH](HowtoOpenSSH#cle-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](https://github.com/libfuse/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 :
|
||
|
||
~~~{.bash}
|
||
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](HowtoFail2Ban) pour bannir les adresses IP qui se trompent de mot de passe
|