22
0
Fork 0
wiki/HowtoOpenSSH.md

903 lines
29 KiB
Markdown
Raw Normal View History

2017-10-20 21:17:44 +02:00
---
2019-06-26 13:42:53 +02:00
categories: openbsd sysadmin
2017-10-26 17:40:15 +02:00
title: Howto OpenSSH
2017-10-19 17:47:17 +02:00
...
* Documentation : <https://www.openssh.com/manual.html>
2017-10-28 01:47:28 +02:00
[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.
2017-10-28 21:21:20 +02:00
2016-12-29 11:25:39 +01:00
## Installation
### Debian
2017-10-28 21:21:20 +02:00
On peut installer les parties client et serveur indépendamment :
2017-10-25 22:42:50 +02:00
~~~
2017-10-25 22:42:50 +02:00
# apt install openssh-client
# ssh -V
2017-10-26 18:34:24 +02:00
OpenSSH_7.4p1 Debian-10+deb9u1, OpenSSL 1.0.2l 25 May 2017
2017-10-28 21:21:20 +02:00
# apt install openssh-server
2017-10-25 22:28:02 +02:00
# nc localhost 22
2017-10-26 17:54:53 +02:00
SSH-2.0-OpenSSH_7.4p1 Debian-10+deb9u1
2017-10-28 21:21:20 +02:00
# 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
2017-10-28 21:21:20 +02:00
Les parties client et serveur sont incluses dans la base OpenBSD.
2017-10-28 21:21:20 +02:00
~~~
$ ssh -V
OpenSSH_7.5, LibreSSL 2.5.2
~~~
2017-10-28 21:21:20 +02:00
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
2017-10-20 20:47:43 +02:00
2017-10-25 22:29:53 +02:00
<http://man.openbsd.org/sshd_config>
2017-10-28 21:21:20 +02:00
Fichiers de configuration :
2017-10-25 22:29:53 +02:00
~~~
/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
~~~
2017-10-29 02:49:06 +02:00
La configuration de base que nous utilisons en général (les options commentées sont les valeurs par défaut).
2017-10-25 22:20:04 +02:00
~~~
2017-10-28 21:21:20 +02:00
# $OpenBSD: sshd_config,v 1.100 2016/08/15 12:32:04 naddy Exp $
2017-10-25 22:20:04 +02:00
2017-10-26 18:05:10 +02:00
# 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.
2017-10-29 01:43:14 +02:00
Port 22
Port 2200
2017-10-26 18:05:10 +02:00
#AddressFamily any
2017-10-25 22:20:04 +02:00
#ListenAddress 0.0.0.0
2017-10-26 18:05:10 +02:00
#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
2017-10-25 22:20:04 +02:00
# Logging
2017-10-26 18:05:10 +02:00
#SyslogFacility AUTH
LogLevel VERBOSE
2017-10-25 22:20:04 +02:00
# Authentication:
2017-10-26 18:05:10 +02:00
#LoginGraceTime 2m
2017-10-28 21:21:20 +02:00
PermitRootLogin no
2017-10-26 18:05:10 +02:00
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
#PubkeyAuthentication yes
# Expect .ssh/authorized_keys2 to be disregarded by default in future.
2017-10-28 21:21:20 +02:00
#AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2
2017-10-26 18:05:10 +02:00
#AuthorizedPrincipalsFile none
#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody
2017-10-25 22:20:04 +02:00
2017-10-26 18:05:10 +02:00
# 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
2017-10-25 22:20:04 +02:00
# Don't read the user's ~/.rhosts and ~/.shosts files
2017-10-26 18:05:10 +02:00
#IgnoreRhosts yes
2017-10-25 22:20:04 +02:00
2017-10-26 18:05:10 +02:00
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
2017-10-25 22:20:04 +02:00
# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no
2017-10-26 18:05:10 +02:00
# 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
2017-10-25 22:20:04 +02:00
2017-10-26 18:05:10 +02:00
#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
2017-10-25 22:20:04 +02:00
X11Forwarding yes
2017-10-26 18:05:10 +02:00
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
2017-10-25 22:20:04 +02:00
PrintMotd no
2017-10-26 18:05:10 +02:00
#PrintLastLog yes
#TCPKeepAlive yes
2017-10-25 22:20:04 +02:00
#UseLogin no
2017-10-26 18:05:10 +02:00
#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
2017-10-28 21:21:20 +02:00
Subsystem sftp /usr/lib/openssh/sftp-server -l INFO
2017-10-26 18:05:10 +02:00
# Example of overriding settings on a per-user basis
#Match User anoncvs
2017-10-28 21:21:20 +02:00
# X11Forwarding no
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs server
2017-10-25 22:20:04 +02:00
2017-10-28 21:21:20 +02:00
AllowUsers jdoe alice bob
2017-10-26 18:05:10 +02:00
2017-10-25 22:20:04 +02:00
Match Address 192.0.2.42
PasswordAuthentication yes
2017-10-25 22:46:26 +02:00
Match User alice bob
2017-10-25 22:20:04 +02:00
PasswordAuthentication no
2017-10-26 18:05:10 +02:00
Match Group adm
PasswordAuthentication no
2017-10-25 22:20:04 +02:00
~~~
2017-10-20 20:47:43 +02:00
2017-10-28 21:21:20 +02:00
### Configuration ssh_config
2017-10-26 18:05:10 +02:00
2017-10-28 21:21:20 +02:00
<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
~~~
2017-10-28 21:21:20 +02:00
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 :
~~~
2017-10-28 21:21:20 +02:00
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
2017-10-28 21:21:20 +02:00
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
~~~
Pour les cas simples d'utilisation de `ProxyCommand`, il est possible d'utiliser `ProxyJump [user@]host[:port]` (équivalent à l'option `-J` en ligne de commande :
~~~
Host private.example.com
ProxyJump bastion.example.com
~~~
2017-10-28 21:21:20 +02:00
## 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 :
~~~
2017-10-28 21:21:20 +02:00
$ scp /foo/FICHIER ssh.example.com:/bar/
~~~
Pour envoyer un répertoire, on utilisera l'option `-r` :
~~~
2017-10-28 21:21:20 +02:00
$ 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
2017-10-29 12:08:25 +01:00
* `-C` : active la compression
2017-10-28 21:21:20 +02:00
* `-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
~~~
2017-10-28 21:21:20 +02:00
### 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.
2017-10-28 21:21:20 +02:00
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
~~~
2017-10-28 21:21:20 +02:00
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
2017-10-28 21:21:20 +02:00
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
2017-10-28 21:21:20 +02:00
# usermod -s /usr/lib/sftp-server userna
~~~
2017-10-25 23:28:50 +02:00
2017-10-28 21:21:20 +02:00
## Clé SSH
2017-10-28 21:21:20 +02:00
Il y a plusieurs types de clé, avec suivant les algorithmes, des tailles de clés variables ou non.
2017-10-29 01:43:14 +02:00
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),
2017-10-28 21:21:20 +02:00
Pour générer une clé SSH *ed25519* :
2017-10-26 18:32:33 +02:00
~~~
2017-10-26 18:32:33 +02:00
$ ssh-keygen -t ed25519 -a 100
Generating public/private ed25519 key pair.
2017-10-29 12:08:25 +01:00
Enter file in which to save the key (/home/jdoe/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
2017-10-28 21:21:20 +02:00
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:
2017-10-28 21:21:20 +02:00
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]-----+
~~~
2017-11-02 14:04:47 +01:00
> *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.
2017-10-28 21:21:20 +02:00
Pour générer une clé SSH *RSA* :
~~~
2017-10-26 18:32:33 +02:00
$ ssh-keygen -o -t rsa -b 4096 -a 100
Generating public/private rsa key pair.
2017-10-29 12:08:25 +01:00
Enter file in which to save the key (/home/jdoe/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
2017-10-28 21:21:20 +02:00
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:
2017-10-28 21:21:20 +02:00
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]-----+
~~~
2017-11-02 14:06:20 +01:00
> *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.
2017-10-20 20:58:02 +02:00
2017-10-28 21:21:20 +02:00
### authorized_keys
2017-10-20 20:58:02 +02:00
2017-10-28 21:21:20 +02:00
Pour autoriser une connexion avec une clé SSH, il faut la placer dans le fichier `~/.ssh/authorized_keys` et ajuster les droits :
2017-10-20 20:58:02 +02:00
~~~
2017-10-28 21:21:20 +02:00
$ 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
2017-10-20 20:58:02 +02:00
~~~
2017-10-20 21:12:10 +02:00
### Agent SSH
2017-10-29 12:08:25 +01:00
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.
2017-10-20 21:12:10 +02:00
2017-10-28 21:21:20 +02:00
En général, un agent SSH est lancé par son Window Manager.
Sinon, on peut le lancer automatiquement via son `~/.profile` :
2017-10-20 21:12:10 +02:00
2017-10-29 12:08:25 +01:00
~~~{.bash}
2017-10-20 21:12:10 +02:00
eval $(ssh-agent) 1> /dev/null
~~~
2017-10-28 21:21:20 +02:00
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 :
2017-10-29 12:08:25 +01:00
~~~{.bash}
2017-10-28 21:21:20 +02:00
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 :
2017-10-28 21:21:20 +02:00
~~~
$ ssh-add -t 36000
2017-10-29 12:08:25 +01:00
Enter passphrase for /home/jdoe/.ssh/id_ed25519:
2017-10-28 21:21:20 +02:00
Identity added: /home/jdoe/.ssh/id_ed25519 (/home/jdoe/.ssh/id_ed25519)
~~~
2017-10-29 12:08:25 +01:00
> *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.
2017-10-28 21:21:20 +02:00
Sous Gnome, si vous utilisez `gnome-keyring-ssh` il se peut que vous ayez l'erreur `Could not add identity` pour votre clé id_ed25519. Il faut alors appliquer le correctif suivant :
~~~
mkdir -p ~/.config/autostart
cp /etc/xdg/autostart/gnome-keyring-ssh.desktop ~/.config/autostart/
echo "X-GNOME-Autostart-enabled=false" >> ~/.config/autostart/gnome-keyring-ssh.desktop
~~~
2017-10-28 21:21:20 +02:00
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
2017-10-29 12:08:25 +01:00
Enter passphrase for /home/jdoe/.ssh/id_ed25519:
2017-10-28 21:21:20 +02:00
* 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`
2017-10-30 10:08:54 +01:00
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)).
2017-10-28 21:21:20 +02:00
## 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 :
2017-10-20 21:12:10 +02:00
~~~
2017-10-28 21:21:20 +02:00
$ ssh -L 3306:127.0.0.1:3306 ssh.example.com
2017-10-20 21:12:10 +02:00
~~~
2017-10-29 12:08:25 +01:00
Et l'on pourra accéder au service MySQL sur sa propre machine via 127.0.0.1 sur le port 3306.
2017-10-20 21:12:10 +02:00
2017-10-28 21:21:20 +02:00
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` :
2017-10-20 21:12:10 +02:00
2017-10-28 21:21:20 +02:00
~~~
$ ssh -L 3306:192.0.2.33:3306 ssh.example.com
~~~
2017-10-20 21:12:10 +02:00
2017-10-28 21:21:20 +02:00
On peut bien sûr utiliser un port différent pour sa propre machine, par exemple 8306 :
2017-10-26 17:58:07 +02:00
2017-10-28 21:21:20 +02:00
~~~
$ ssh -L 8306:192.0.2.33:3306 ssh.example.com
~~~
2016-12-29 11:25:39 +01:00
2017-10-28 21:21:20 +02:00
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` :
2016-12-29 11:25:39 +01:00
~~~
2017-10-28 21:21:20 +02:00
$ ssh -L 127.0.0.33:8306:192.0.2.33:3306 ssh.example.com
2016-12-29 11:25:39 +01:00
~~~
2017-10-28 21:21:20 +02:00
Enfin il faut noter que si l'on veut utiliser un port local inférieur à 1024, il faudra lancer la commande en "root" :
2016-12-29 11:25:39 +01:00
2017-10-28 21:21:20 +02:00
~~~
# ssh -L 443:127.0.0.1:443 ssh.example.com
~~~
2016-12-29 11:25:39 +01:00
### 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 :
~~~
2017-10-29 12:08:25 +01:00
$ 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`.
2017-10-28 21:21:20 +02:00
### Proxy SOCKS via SSH
2016-12-29 11:25:39 +01:00
2017-10-28 21:21:20 +02:00
On peut lancer un proxy SOCKS passant par un serveur distant ainsi :
2016-12-29 11:25:39 +01:00
~~~
2017-10-28 21:21:20 +02:00
$ ssh -D 6789 ssh.example.com
2016-12-29 11:25:39 +01:00
~~~
2017-10-28 21:21:20 +02:00
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
2016-12-29 11:25:39 +01:00
2017-12-21 11:00:58 +01:00
### 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.
2017-10-28 21:21:20 +02:00
### Séquences d'échappement SSH
2016-12-29 11:25:39 +01:00
2017-10-29 12:08:25 +01:00
<https://lonesysadmin.net/2011/11/08/ssh-escape-sequences-aka-kill-dead-ssh-sessions/>
2017-10-28 21:21:20 +02:00
2017-10-29 12:08:25 +01:00
On peut utiliser des combinaisons de touches spéciales via une connexion SSH pour intéragir avec la connexion en cours.
2017-10-28 21:21:20 +02:00
En tapant `Entrée + ~ + ?` on obtient la liste des séquences possibles :
2016-12-29 11:25:39 +01:00
2017-10-25 23:28:50 +02:00
~~~
2017-10-28 21:21:20 +02:00
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.)
2017-10-25 23:28:50 +02:00
~~~
2016-12-29 11:25:39 +01:00
2017-10-28 21:21:20 +02:00
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`
2017-10-19 18:00:22 +02:00
2017-11-13 22:02:35 +01:00
Quelques exemples de manipulations possibles (en anglais) : <https://omecha.info/blog/ssh-escape-commands-for-fun-and-profit.html>
2017-10-28 21:21:20 +02:00
### 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 :
2017-10-19 18:00:22 +02:00
~~~
2017-10-28 21:21:20 +02:00
$ ssh -J bastion.example.com cible.example.com
2017-10-19 18:00:22 +02:00
~~~
2017-10-29 02:49:06 +02:00
> *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)
2017-10-19 18:00:22 +02:00
2017-10-28 21:21:20 +02:00
### 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 :
2017-10-28 21:21:20 +02:00
~~~
$ ssh -A ssh.example.com
$ env | grep ^SSH_A
SSH_AUTH_SOCK=/tmp/ssh-sUSruIwyCa/agent.3265
~~~
2017-10-28 21:21:20 +02:00
> *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
~~~
2017-10-28 21:21:20 +02:00
### 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`
2017-10-29 12:08:25 +01:00
Pour lancer la connexion VPN, on fera :
~~~
2017-10-28 21:21:20 +02:00
# ssh -w 42:42 ssh.example.com
~~~
2017-10-29 12:08:25 +01:00
On a ensuite un périphérique `tun42` utilisable, à configurer des 2 côtés.
2017-10-29 12:08:25 +01:00
- Côté serveur SSH : `ifconfig tun42 172.17.18.2/24`
2017-10-28 21:21:20 +02:00
- Côté client SSH : `ifconfig tun42 172.17.18.1/24`
2017-10-28 21:21:20 +02:00
On peut alors enfin configurer le routage au niveau client, par exemple sous Linux :
2017-10-19 19:50:28 +02:00
~~~
2017-10-28 21:21:20 +02:00
# ip route add 8.8.8.8/32 via 172.17.18.2 dev tun42`
2017-10-19 19:50:28 +02:00
~~~
2017-10-28 21:21:20 +02:00
### UserKnownHostsFile
2017-10-29 12:08:25 +01:00
OpenSSH se sert du fichier `~/.ssh/known_hosts` pour retenir l'empreinte (_fingerprint_) de chaque connexion effectuée.
2017-10-28 21:21:20 +02:00
Cela lui permet de détecter un changement des clés du serveur, notamment une tentative d'usurpation d'un serveur :
2017-10-28 01:47:28 +02:00
2017-10-28 21:21:20 +02:00
~~~
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ 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.
~~~
2017-10-28 01:47:28 +02:00
On peut accepter automatiquement la clé à la première connexion ainsi :
~~~
$ ssh -o "StrictHostKeyChecking=accept-new" ssh.example.com
~~~
Si besoin, on peut supprimer la ligne concernée dans `~/.ssh/known_hosts` via une commande du type :
2017-10-28 21:21:20 +02:00
~~~
$ ssh-keygen -f "~/.ssh/known_hosts" -R ssh.example.com
$ ssh-keygen -f "~/.ssh/known_hosts" -R [ssh.example.com]:2222
2017-10-28 21:21:20 +02:00
~~~
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
~~~
2017-10-29 12:08:25 +01:00
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)?
~~~
2017-10-28 21:21:20 +02:00
### ControlMaster
2017-10-28 21:21:20 +02:00
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
~~~
2017-10-28 01:47:28 +02:00
### 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/>
2018-07-31 10:26:58 +02:00
En cas de connexion réseau avec une latence réseau élevée ou instable (perte de paquets), on peut utiliser **mosh** qui vient se positionner après une connexion SSH en utilisant un port UDP dédiée à une session/utilisateur. Il gère aussi le roaming, c'est-à-dire que l'adresse IP source n'est pas importante pour garder la connexion (bascule ADSL vers LTE par exemple) et que la connexion peut être suspendue plusieurs heures sans problème (appareil en veille, coupure réseau…).
~~~
# apt install mosh
~~~
2018-07-31 10:26:58 +02:00
Pour se connecter basiquement (port SSH 22, utilisateur actuel). Il suffit grosso-modo de remplacer la commande ssh par mosh.
~~~
$ mosh server
~~~
Un exemple plus avancé.
~~~
$ mosh --ssh "ssh -p2222 -l user" server
~~~
2018-11-23 16:10:59 +01:00
Mosh va ouvrir une connexion ssh, puis la quitter pour basculer en UDP sur un port négocié (plage 60001:60999 par défaut).
2018-07-31 10:26:58 +02:00
On peut tout à fait avoir la connexion SSH restreinte par un pare-feu (par exemple il faudra utiliser un VPN pour la connexion SSH), mais avoir la plage de ports UDP publiques.
2017-10-28 01:47:28 +02:00
## 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
~~~
2017-10-28 21:21:20 +02:00
### 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 :
2017-10-29 12:08:25 +01:00
~~~{.bash}
2017-10-28 21:21:20 +02:00
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
~~~
2017-10-28 01:47:28 +02:00
### 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
2017-10-29 12:08:25 +01:00
Enter lock password:
Again:
Agent locked.
$ ssh-add -l
The agent has no identities.
$ ssh-add -X
2017-10-29 12:08:25 +01:00
Enter lock password:
Agent unlocked.
~~~
2018-10-05 23:49:59 +02:00
### Ouvrir un tunnel, en passant par un bastion
Voici un exemple pour exposer localement un service VNC sur le port 5901 qui est accessible uniquement localement sur le port 5906 d'un serveur VNC, qui lui même n'est accessible que par un bastion :
~~~
ssh -J bastion.example.com -L 5906:127.0.0.1:5901 vnc-server.example.com
~~~
### 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