Expert

Table des matières


Avant-Propos

Dans les bonnes pratiques de la sécurité des systèmes d’information (SSI), les bastions d’administration sont des serveurs utilisés pour l’administration du parc informatique (postes de travail et serveurs de production). Cette documentation présente la configuration minimale de ce type de serveur pour assurer un maximum de sécurité. Nous aborderons les différents éléments de renforcement de la sécurité du serveur, en prenant comme base un serveur de type Red Hat 9 nouvellement installé.

Le bastion d’administration doit être un serveur “hors-SI”. En particulier, il ne doit reposer sur aucune technologie d’authentification centralisée ou de stockage partagé. Seule l’infrastructure de sécurité du laboratoire (syslog, SIEM, etc.) doit être utilisée.

Administration du bastion

Les droits d’administrateur du bastion doivent être réduits au maximum. Idéalement, seul le responsable de la sécurité des systèmes d’information (RSSI) et le responsable du service doivent être habilités à administrer ce serveur. L’administration du serveur doit se faire avec un compte distinct et une clé SSH distincte de celle utilisée pour l’utilisation du bastion, suivant ainsi le modèle de “tiering” de Microsoft.

Utilisation du bastion

Seuls les administrateurs système du laboratoire doivent avoir accès, sans droit d’administrateur, au bastion.

Pas de connexion root

L’utilisation du compte root en accès SSH direct est fortement déconseillée. Il est préférable d’avoir un compte distinct, avec des privilèges sudo (même sans mot de passe), plutôt qu’un compte root accessible. Le compte root ne doit servir que pour les accès physiques aux serveurs en cas d’urgence.

cat /etc/ssh/sshd_config.d/10-core.conf
PermitRootLogin no

Authentification par clé SSH

Les clés privées SSH doivent, de préférence, être stockées sur les postes de travail des administrateurs avec une phrase secrète associée. L’agent forwarding permettra de rebondir à partir du bastion vers les autres serveurs de l’infrastructure. Ainsi, même en cas de compromission du bastion, l’attaquant n’aura pas la possibilité de récupérer simplement des identifiants administrateurs.

cat /etc/ssh/sshd_config.d/10-core.conf
GatewayPorts yes

Double facteur d’authentification

L’utilisation d’une authentification multi-facteur est aujourd’hui la seule méthode permettant un niveau de sécurité suffisant pour se connecter à des éléments aussi sensibles que le bastion. Dans notre cas, nous allons mettre en place une double authentification par clé SSH et TOTP (pam-google-authenticator1).

Installation de pam-google-authenticator

sudo dnf install google-authenticator

Configuration du service PAM

Le service pam gère l’authentification google-authenticator. Pour cela, il faut modifier deux paramètres :

  • Ajouter pam_google_authenticator
  • Supprimer l’authentification par mot de passe

Si on ne désactive pas l’authentification par mot de passe, alors l’authentification deviendra à triple facteur (clé SSH, mot de passe et TOTP). Cela peut être un choix d’architecture.

Dans le cas de pam_google_authenticator, nous allons ajouter l’option nullok qui permet d’autoriser la connexion si aucun TOTP n’a été configuré pour le compte. Nous forcerons ensuite l’enregistrement TOTP lors de la première connexion réussie avec la clé SSH.

cat /etc/pam.d/sshd
#%PAM-1.0
auth required pam_google_authenticator.so nullok
auth required pam_permit.so
auth include postlogin
account required pam_sepermit.so
account required pam_nologin.so
account include password-auth
password include password-auth
session required pam_selinux.so close
session required pam_loginuid.so
session required pam_selinux.so open env_params
session required pam_namespace.so
session optional pam_keyinit.so force revoke
session optional pam_motd.so
session include password-auth
session include postlogin

Configuration de SSH

La seconde étape de notre authentification à double facteur sera l’activation de celle-ci dans ssh. En effet, par défaut, l’authentification via une clé SSH est suffisante pour établir une connexion SSH. Nous allons modifier ce comportement pour forcer une connexion clé + TOTP.

cat /etc/ssh/sshd_config.d/10-mfa.conf
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive

Forcer l’enregistrement

Actuellement, vous pouvez toujours vous connecter sans MFA sur votre bastion tant que vous n’avez pas volontairement décidé de configurer le MFA. Afin de changer ce comportement, nous allons utiliser la directive ForceCommand de ssh.

Notre script sera le suivant. Il vérifiera l’existence d’un fichier .google_authenticator, signe que la double authentification est configurée, et si ce n’est pas le cas, forcera l’enregistrement de l’application.

$ cat /usr/local/bin/check-mfa.sh
#!/bin/sh

if [ ! -e ${HOME}/.google_authenticator ]
then
  echo "Vous êtes sur le point de vous connecter au bunker pour la première fois."
  echo "L'accès à cette machine n'est autorisé qu'avec la double authentification"
	google-authenticator -f -t -d -r 3 -R 15 -w 5 -Q NONE
fi

if [[ $SSH_ORIGINAL_COMMAND ]]; then
    eval "$SSH_ORIGINAL_COMMAND"
    exit
fi

${SHELL}

Ensuite, nous configurons SSH pour exécuter ce script à chaque connexion SSH :

cat /etc/ssh/sshd_config.d/10-mfa.conf
ForceCommand /usr/local/bin/check-mfa.sh

À présent, lors de votre première connexion, vous devez avoir le message suivant :

ssh login@bastion.in2p3.fr
MFA not configured, please follow the procedure
Your new secret key is: [...]
Enter code from app (-1 to skip):

Il suffit d’ajouter manuellement votre secret dans votre application TOTP (FreeOTP, Bitwarden Authenticator, Aegis Authenticator, etc.) et de vérifier que votre enregistrement est correct.

Au prochain essai, l’invite sera :

ssh login@bastion.in2p3.fr
(login@bastion.in2p3.fr) Verification code:

Renforcement des journaux

Afin de simplifier les investigations en cas de compromission du bastion, nous allons renforcer la journalisation. Pour cela, nous allons configurer auditd pour logger l’ensemble des commandes effectuées sur le bastion.

cat /etc/audit/rules.d/ssi.rules
-a exit,always -F arch=b64 -S execve
-a exit,always -F arch=b32 -S execve
sudo augenrules

Ensuite, nous configurons auditd pour envoyer les journaux à syslog :

sudo dnf install audispd-plugins
cat /etc/audit/plugins.d/syslog.conf
active = yes
direction = out
path = /sbin/audisp-syslog
type = always
args = LOG_INFO
format = string

Attention, auditd ne peut pas, par défaut, être redémarré simplement. Le plus simple reste de redémarrer le serveur.

À présent, vos commandes shell devraient apparaître dans /var/log/audit/audit.log et dans votre syslog centralisé.

Sur le reste de l’infrastructure

Pour les administrateurs

  • On reprendra le concept de “no root login” avec des comptes administrateurs locaux sur chaque serveur qui n’accepte que les clés SSH en provenance du bastion avec la directive from=2.
  • Le forward d’agent SSH permettra de lancer des commandes massives sur l’ensemble du parc sans avoir à retaper le mot de passe.
  • Une configuration sudo avec NOPASSWD est envisageable tant que les comptes administrateurs n’ont que la clé SSH comme moyen d’authentification et que seul le bastion peut se connecter au serveur.

Par exemple :

cat .ssh/authorized_keys
from="ip-bastion" ssh-ed25519 AAAAC3Nza...

Pour les bots

Dans le cas où des clés SSH sans mot de passe sont nécessaires pour effectuer des actions automatiques entre serveurs, celles-ci doivent être limitées dans leurs actions via la directive command= de ssh en plus de la directive from=. Il est, de plus, recommandé de créer un compte administrateur dédié avec des droits sudo plus limités que les autres comptes administrateurs.

Si un serveur doit pouvoir effectuer plusieurs commandes différentes, il est possible de placer un wrapper du type :

cat ~bot/.scripts/wrapper.sh
#!/bin/sh
case "$SSH_ORIGINAL_COMMAND" in
    "1")
        echo "option 1"
        ;;
    "2")
        echo "option 2"
        ;;
    *)
        echo "Access denied"
        exit 1
        ;;
esac
cat ~/.ssh/authorized_keys
from="ip-serveur-distant" command="${HOME}/.scripts/wrapper.sh"

Il suffit ensuite, depuis le serveur distant, de lancer la commande :

ssh bot@serveur 1
option 1
ssh bot@serveur 2
option 2

Configurer son environnement

La configuration d’un bastion permet de sécuriser son environnement, mais elle implique des changements de pratiques qui peuvent rapidement devenir contraignants. Il existe cependant des moyens de configurer son environnement de travail pour faciliter l’utilisation d’un bastion.


Limiter la propagation des clés SSH

Comme défini précédemment, l’administration du bastion doit être réalisée avec des clés SSH spécifiques, qui n’ont aucune raison d’être chargées en permanence dans l’agent SSH. Il est possible de configurer son environnement pour éviter que cette clé soit automatiquement chargée. Cela signifie que la phrase de passe (passphrase) sera demandée à chaque connexion SSH, mais :

  • L’administration du bastion doit rester une action exceptionnelle ;
  • Il est dangereux de propager une clé SSH inutile sur plusieurs serveurs.

Pour ce faire, ajoutez une section dans le fichier ~/.ssh/config comme suit :

Host admin-bastion
  User admin
  Hostname bastion.ijclab.in2p3.fr
  AddKeysToAgent no
  IdentityFile ~/.ssh/admin@bastion

La directive AddKeysToAgent no indique que cette clé ne doit pas être automatiquement ajoutée à l’agent SSH.

Gérer la double authentification

Attention : Les configurations décrites dans cette section peuvent être exploitées par des attaquants pour voler des sessions. Il est strictement interdit d’appliquer ce type de configuration sur un poste partagé. Elles peuvent être envisagées sur des postes personnels.

La double authentification au bastion peut représenter un obstacle pour certaines actions nécessitant de multiple connexion. Il est possible de configurer des périodes de grâce pour les administrateurs, c’est-à-dire paramétrer SSH de manière à ne demander la double authentification qu’une seule fois par session. Pour cela, utilisez les options Control* dans le fichier ~/.ssh/config. Ces options permettent de réutiliser une connexion SSH existante plutôt que d’en établir une nouvelle à chaque fois. L’ensemble des connexions seront closes lorsque la connexion principale (première connexion) est fermée.

Host bastion
  User bastion-username
  IdentityFile ~/.ssh/bastion
  ControlMaster auto
  ControlPath ~/.ssh/%r@%h:%p

  1. pam-google-authenticator est un module PAM développé par Google pour réaliser une authentification à double facteur, mais ne repose pas sur des services Google. Le service Google Charts peut être utilisé pour faciliter l’enregistrement des applications TOTP, mais il est optionnel et déconseillé. 

  2. il est aussi possible d’utiliser la directive AllowUsers, elle est positionné dans la configuration sshd et est beaucoup plus restrictive car géré par l’administrateur du serveur et non par l’authorized_keys de l’utilisateur.