--- categories: OpenBSD sysadmin title: Howto OpenSSH ... * Documentation : SSH est un protocole permettant de se connecter sur une machine à travers le réseau de manière sécurisée. Nous utilisons l'implémentation la plus répandue : [OpenSSH](https://www.openssh.com/). Ce protocole existe en plusieurs versions et nous utilisons uniquement la version 2. La version 1 comporte des failles de sécurité et ne doit plus être utilisée. ## Installation ### Debian On peut installer la partie client et la partie 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 ~~~ ### OpenBSD OpenSSH étant développé au sein d'OpenBSD, la partie cliente et la partie serveur sont incluses dans la base. L'activation de la partie serveur dépend du choix qui a été fait lors de l'installation. ## Configuration SSH ### Configuration minimale ~~~ /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 qu'on utilise (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 #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 without-password #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 # Example of overriding settings on a per-user basis #Match User anoncvs # X11Forwarding no # AllowTcpForwarding no # PermitTTY no # ForceCommand cvs server AllowUsers johndoe janedoe alice bob Match Address 192.0.2.42 PasswordAuthentication yes Match User alice bob PasswordAuthentication no Match Group adm PasswordAuthentication no ~~~ > **Note** : Les clés DSA sont dépréciées depuis Stretch. ### Log verbeux pour SFTP Pour augmenter la verbosité du sous-système sftp-server, notamment loguer les commandes SFTP, il suffit de passer l'option -l à l'appel de sftp-server dans `sshd_config` : ~~~ Subsystem sftp /usr/libexec/openssh/sftp-server -l INFO ~~~ ### SFTP chroot Voici un ensemble de commandes pouvant être utilisé pour mettre en place un accès SFTP pour un ou plusieurs utilisateurs, qui n'auront accès qu'à une vue limitée de l'arborescence du système : ~~~ # Répertoire dans lequel SSHD va se chrooter mkdir /home/sftp chmod 755 /home/sftp # Les utilisateurs du groupe sftp (ici account1) disposeront de l'accès SFTP restreint groupadd sftp useradd -g sftp -d /account1 account1 mkdir /home/sftp/account1/ chown account1:sftp /home/sftp/account1/ chmod 700 /home/sftp/account1/ ~~~ Dans le fichier `/etc/ssh/sshd_config` : ~~~ Subsystem sftp internal-sftp Match group sftp ChrootDirectory /home/sftp X11Forwarding no AllowTcpForwarding no ForceCommand internal-sftp ~~~ ### SFTP Only Mettre shell `/usr/lib/sftp-server` pour l'utilisateur et s'assurer que ce shell est bien présent dans `/etc/shells` ~~~ # usermod -s /usr/lib/sftp-server userna # echo '/usr/lib/stfp-server' >> /etc/shells ~~~ ## Administration SSH ### Créer une clé ssh Il y a plusieurs types de clé, avec suivant les algorithmes, des tailles de clés variables ou non. L'algorithme à préférer est *ed25519* mais il faut faire attention sur quelle machine la clé va être utilisée car les très vieilles versions d'OpenSSH ne le supporte pas. C'est notamment le cas sur Debian Wheezy. Dans ce cas là on préférera l'algorithme *rsa*. Dans le cas de *ed25519*, la taille de la clé est fixe. Pour *rsa*, 2048 est la taille minimale, 4096 est recommandée. **Il est important de mettre un mot de passe pour protéger sa clé privée.** On peut aussi utiliser l'option `-a NOMBRE` pour spécifier le nombre d'itérations de l'algorithme de dérivation de clé qui protège la clé privée avec le mot de passe utilisé. Cela protège la clé privé contre brute-force du mot de passe. 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 ~~~ $ ssh-keygen -t ed25519 -a 100 Generating public/private ed25519 key pair. Enter file in which to save the key (/home/user/.ssh/id_ed25519): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/user/.ssh/id_ed25519. Your public key has been saved in /home/user/.ssh/id_ed25519.pub. The key fingerprint is: SHA256:7tdFlczm4VJkEl4yM08O4VOPkGQiU1YR8kKuLsm9v84 user@example.com The key's randomart image is: +--[ED25519 256]--+ | o.*oB&**.| | * =+.#Oo| | o .+*+o| | . . .oo | | S .. | | . = . | | + + . . | | o o. . | | o+E. | +----[SHA256]-----+ ~~~ Dans le cas de *rsa*, on précise la taille. On donne aussi [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 qui est plus résistant aux attaques par brute-force. Cet argument n'est pas nécessaire avec *ed25519* car il est par défaut. ~~~ $ ssh-keygen -o -t rsa -b 4096 -a 100 Generating public/private rsa key pair. Enter file in which to save the key (/home/user/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/user/.ssh/id_rsa. Your public key has been saved in /home/user/.ssh/id_rsa.pub. The key fingerprint is: SHA256:9tGKNLEbiUyAbhShJ7rncBpn/ydCXZHtJkdIsUoW2TM user@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]-----+ ~~~ ### .ssh/config Il est possible de configurer des sortes d'*alias* pour son utilisateur unix via le fichier `~/.ssh/config` Un exemple plutôt complet (on n'a pas besoin forcément de décrire tout ça) sans être exhaustif : ~~~ Host www00 Hostname www00.example.com Port 2222 User johndoe IdentityFile ~/.ssh/id_ed25519 ProxyCommand ssh bastion -W %h:%p ~~~ ### Agent SSH Il est très important (comprendre vital) de protéger sa clé ssh avec un mot de passe lors de sa création. Taper son mot de passe à chaque connexion peut-être pesant, on peut donc passer par l'agent ssh qui va le retenir en mémoire (de la même manière que sudo par exemple). Pour l'utiliser il convient de rajouter dans son fichier `~/.profile` (ou équivalent) la ligne : ~~~ eval $(ssh-agent) 1> /dev/null ~~~ Ensuite pour rajouter la clé dans un agent il suffit de taper la commande ~~~ $ ssh-add /home/user/.ssh/id_secure ~~~ Néanmoins, contrairement à sudo où l'accès est temporaire, dans le cas présent l'agent garde les clés de manière illimitée ce qui n'est pas forcément bon. On pourra donc utiliser l'option [-t](http://man.openbsd.org/ssh-agent#t) pour spécifier une durée. On peut lire dans des tutoriels d'utiliser l'option -A de ssh(1) pour se connecter à des machines via une autre machine. Cependant cela permet à l'utilisateur *root* de la machine sur laquelle vous mettez votre agent de se connecter, en utilisant vos clés, aux machines auxquelles vous avez accès. On privilégiera donc d'utiliser l'option -J de ssh(1) pour faire un rebond. > **Note** : Il existe d'autres implémentations de l'agent SSH, tel que gpg-agent qui gère aussi les clés SSH. ### 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 ~~~ ## Restriction de l'accès d'une clé ssh Pour autoriser une clé SSH en limitant les accès via `.ssh/authorized_keys` : ~~~ no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa XXXXX commentaires ~~~ ### VPN over SSH Côté serveur SSH : - Ajouter "PermitTunnel yes" dans la config ssh - sysctl -w net.ipv4.ip_forward=1 - iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE Puis se connecter de root vers root : ~~~ # ssh -w 42:42 ssh.example.com ~~~ On a ensuite un périphérique "tun42" utilisable des 2 côtés à configurer. Serveur SSH : `ifconfig tun42 172.17.18.2/24` En local : `ifconfig tun42 172.17.18.1/24` On peut alors router au niveau IP : ~~~ # ip route add 8.8.8.8/32 via 172.17.18.2 dev tun42` ~~~ ## Connexion SSH par rebond Il se peut qu'on doive passer par une machine pour se connecter à une machine cible (c'est le principe d'un [bastion](https://fr.wikipedia.org/wiki/Bastion_(informatique))) : ~~~ $ ssh -J bastion machine-cible ~~~ À noter que cela nécessite une version récente d'OpenSSH (celle présente dans Stretch est ok, mais pas celle de Jessie) ### Tunnel SSH #### Pour une ressource donnée Si on veut accéder via la machine 192.0.2.4 à un service https hébergé sur 192.0.2.5 mais que seule la machine 192.0.2.6 y accède on peut lancer la commande : ~~~ $ ssh -L 192.0.2.4:9000:192.0.2.5:443 192.0.2.6 ~~~ On peut ensuite faire pointer son navigateur sur https://192.0.2.4:9000. #### Pour tout le trafic web On lance la commande ~~~ $ ssh -D 6789 proxy ~~~ Puis on configure son navigateur pour utiliser un proxy SOCKS (4a ou 5) avec comme adresse 127.0.0.1 et port 6789. ### Séquences d'échappement On peut les utiliser pour communiquer avec le client ssh dans le terminal. La séquence la plus connue permet de tuer une session qui ne répondait plus (perte de connexion internet, problème sur le serveur ou autre). Il faut taper sur la touche entrée puis sur `~` et `.`. D'autres séquences d'échappement sont possibles, voir [cet article](https://lonesysadmin.net/2011/11/08/ssh-escape-sequences-aka-kill-dead-ssh-sessions/amp/).