Bastion SSH (avec clés ed25519 et 2FA)

Environnement

Installation du système

Installer une Debian minimale à partir d'une ISO netinstall (n'installer aucune fonctionnalité, excepté le serveur openSSH))

Installation et configuration du serveur SSH (clés et 2FA)

Mettre à jour le système et installer le serveur OpenSSH (si non installé auparavant) :

apt update
apt dist-upgrade
apt install openssh-server

Vérifier que le serveur SSH fonctionne :

ss -plnt
LISTEN     0     128     0.0.0.0:26578     0.0.0.0:*
LISTEN     0     128        [::]:26578        [::]:*  

Se connecter au serveur en SSH :

ssh user@bastion

Configurer le serveur SSH à l'aide de cette procédure.

Installer le 2FA :

apt install libpam-google-authenticator

Ajouter les lignes suivantes dans le fichier "/etc/pam.d/sshd" :

echo "# Authentification 2FA" >> /etc/pam.d/sshd
echo "auth required pam_google_authenticator.so" >> /etc/pam.d/sshd

Modifier la ligne suivante dans le fichier "/etc/ssh/sshd_config" :

sed -i 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/' /etc/ssh/sshd_config

Redémarrer le serveur SSH :

systemctl restart sshd.service

Configurer le 2FA (/!\ lancer la commande sous le compte ciblé par la connexion SSH afin de créer le fichier .google_authenticator dans le dossier personnel) :

google-authenticator
Do you want authentication tokens to be time-based (y/n) y

Your new secret key is: AC75MF5F4SD65F4DS4F3DSSD35
Your verification code is 782414
Your emergency scratch codes are:
  12345678
  91011121
  31415161
  71819202
  12223242

Do you want me to update your "/home/user/.google_authenticator" file? (y/n) y

Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y

By default, a new token is generated every 30 seconds by the mobile app.
In order to compensate for possible time-skew between the client and the server,
we allow an extra token before and after the current time. This allows for a
time skew of up to 30 seconds between authentication server and client. If you
experience problems with poor time synchronization, you can increase the window
from its default size of 3 permitted codes (one previous code, the current
code, the next code) to 17 permitted codes (the 8 previous codes, the current
code, and the 8 next codes). This will permit for a time skew of up to 4 minutes
between client and server.
Do you want to do so? (y/n) n

If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting? (y/n) y

Modifier la ligne suivante dans le fichier "/etc/pam.d/sshd" :

sed -i 's/@include common-auth/#@include common-auth/' /etc/pam.d/sshd

Ajouter les lignes suivantes dans le fichier "/etc/ssh/sshd_config" pour utiliser l'authentification par clé puis par 2FA :

echo "AuthenticationMethods publickey,keyboard-interactive" >> /etc/ssh/sshd_config

Redémarrer le serveur SSH :

systemctl restart sshd.service

Configuration du proxy SSH

Ajouter toutes les clés privées à ssh-agent :

ssh-add -c ~/.ssh/*

Lister les clés ajoutées :

ssh-add -l

Supprimer toutes les clés de ssh-agent :

ssh-add -D

ssh-agent va tester toutes les clés lors de la tentative d'authentification ce qui peut conduire à une erreur si le paramètre MaxAuthTries du fichier /etc/ssh/sshd_config du bastion est faible (dans notre cas 3). Il faut ajouter la directive "IdentitiesOnly yes" pour chaque hôte dans le fichier local ~/.ssh/config :

nano ~/.ssh/config
Host *
        IdentitiesOnly=yes

Dans le fichier "~/.ssh/config", ajouter la directive "ProxyJump bastion" à tous les hôtes qui devront être accessibles via le bastion :

nano ~/.ssh/config
# Serveur 01
Host serveur_01
    ProxyJump bastion
        HostName 192.168.0.1
        IdentityFile ~/.ssh/serveur_01
        Port 22
        User user

Tunnel SSH vers RDP

La commande est la suivante :

ssh -L 33389:[Windows Server RDP address]:3389 [address ssh server] -l [ssh username] -N -4

Exemple :

ssh -L 33389:172.18.2.6:3389 bastion -N -4

Sources

Configuration et durcissement du serveur OpenSSH :

https://linux-audit.com/audit-and-harden-your-ssh-configuration/

https://github.com/arthepsy/ssh-audit

2FA :

https://www.linode.com/docs/security/authentication/use-one-time-passwords-for-two-factor-authentication-with-ssh-on-ubuntu-16-04-and-debian-8/

https://www.linuxbabe.com/ubuntu/two-factor-authentication-ssh-key-ubuntu-18-04

https://www.digitalocean.com/community/tutorials/how-to-set-up-multi-factor-authentication-for-ssh-on-ubuntu-16-04

Proxy SSH :

https://blog.octo.com/le-bastion-ssh/

https://www.ssh.com/ssh/agent

https://superuser.com/questions/187779/too-many-authentication-failures-for-username

Tunnel SSH :

https://www.saotn.org/tunnel-rdp-through-ssh/