848 lines
26 KiB
Markdown
848 lines
26 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).
|
|
|
|
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 humain par une passphrase.
|
|
Pour éviter de taper 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](http://man.openbsd.org/ssh-agent#t) permet de limiter à 10h 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, notamment `gpg-agent`.
|
|
|
|
|
|
## 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 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/amp/>
|
|
|
|
On peut utiliser des combinaisons de touches spéciales via une connexion SSH pour intéragir sur 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`
|
|
|
|
### 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 le connexion VPN, on fera :
|
|
|
|
~~~
|
|
# ssh -w 42:42 ssh.example.com
|
|
~~~
|
|
|
|
On a ensuite un périphérique `tun42` utilisable des 2 côtés à configurer.
|
|
|
|
- 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 le 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 l'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 :
|
|
|
|
~~~
|
|
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
|
|
|