Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
pratique:informatique:bastionssh [07/05/2025 10:47] Zatalyzpratique:informatique:bastionssh [09/05/2025 17:14] (Version actuelle) – [Configuration côté utilisatrice] Zatalyz
Ligne 7: Ligne 7:
 En cours d'écriture, gros brouillon. En cours d'écriture, gros brouillon.
 </WRAP> </WRAP>
 +
 +Pré-requis :
 +  * Savoir gérer SSH : génération de clé, configuration de sshd, usage de ''.ssh/config''
  
 ===== Attention à la fausse sécurité ===== ===== Attention à la fausse sécurité =====
Ligne 17: Ligne 20:
  
 Le Bastion 1 est un serveur en ligne des plus classique. Ce sera le seul point d'accès pour les divers Bastions 2. Les bastions 2, eux, sont en réalité sur les hyperviseurs et donnent accès au réseau local. Cela demande par contre que les Bastion 2 soient vu comme des composants critiques ; une élevation de privilège "là" pourrait avoir de sacrés conséquences.  Le Bastion 1 est un serveur en ligne des plus classique. Ce sera le seul point d'accès pour les divers Bastions 2. Les bastions 2, eux, sont en réalité sur les hyperviseurs et donnent accès au réseau local. Cela demande par contre que les Bastion 2 soient vu comme des composants critiques ; une élevation de privilège "là" pourrait avoir de sacrés conséquences. 
 +
 +==== Conventions ====
 +
 +Dans l'exemple, nous aurons 
 +  * "alice", utilisatrice "de base" (pas de droit à bidouiller sur les bastions !). Elle est membre du groupe "jump"
 +  * "lapin", the sysadmin qui bidouille les bastions. Il est membre du groupe "wheel"
 +  * "101.1.1.1" est l'adresse du Bastion1 (oui cette ip est foireuse, et osef).
 +  * "202.1.1.2" est l'adresse du Bastion2 (et oui, je devrais sans doute aussi faire ça en ipv6).
 +  * 10.0.0.10, 10.0.0.11 et 10.0.0.12 sont des serveurs derrière le Bastion2 et sur un réseau local.
 +
 +
 +==== Configuration côté Bastion1 ====
 +Ce bastion, le premier de la chaine, est donc celui auquel on se connecte depuis "n'importe où" (mais avec la bonne clé et la bonne utilisatrice). Il est situé quelque part sur les zinternets (adresse ip publique et dans un datacenter). 
 +
 +  * Port personnalisé (non 22)
 +  * Désactivation des authentifications inutiles (mot de passe, PAM, etc.)
 +  * `AllowUsers` ou `Match User` pour restreindre les accès
 +  * Désactivation du shell si non nécessaire (`PermitTTY no`, `ForceCommand`, etc.)
 +  * Ajout des clés dans `~/.ssh/authorized_keys`
 +  * Autoriser uniquement les connexions sortantes SSH vers Bastion2 (port personnalisé)
 +  * Bloquer les autres sorties SSH/TCP si possible
 +  * Paramétrer sshguard, fail2ban/réaction
 +  * Activation de la journalisation SSH
 +
 +=== Pour les passagères ===
 +Ceci concerne les utilisatrices qui ne font que passer, et donc qui n'auront aucun moyen de s'arrêter ici.
 +
 +  * Désactiver le shell
 +
 +=== Pour les admins ===
 +Là c'est différent : les admins ne rebondissent pas, elles peuvent avoir un shell, et peuvent tout péter. 
 +
 +==== Configuration côté Bastion2 ====
 +Ce bastion est l'entrée pour le réseau local. Il sert donc des adresses locale ensuite. 
 +
 +Même trucs que sur Bastion1, en fait.
 +
 +  * Autoriser uniquement les connexions vers le réseau local ou vers des IPs précises (serveur final)
 +
 +=== sshd_config ===
 +
 +Concernant le port ssh, dans le cas que je traite, Bastion2 est derrière une box. Cette dernière n'accepte les connexions ssh que sur un port exotique (par exemple le port 2242) mais redirige ensuite en local sur le port 22 de la machine du bastion. Donc pas besoin de modifier le port sur cette dernière. C'est aussi possible de le faire directement avec le pare-feu sur une machine exposée sur internet, mais plus pénible, dans ce cas autant directement utiliser un autre port pour ssh sur la machine.
 +
 +<code bash /etc/ssh/sshd_config.d/bastion>
 +# Protocole et sécurité de base
 +Protocol 2
 +StrictModes yes
 +# CHANGER : Port 22
 +
 +# Chiffrement et algorithmes
 +HostKey /etc/ssh/ssh_host_ed25519_key
 +KexAlgorithms sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com,mlkem768x25519-sha256
 +Ciphers chacha20-poly1305@openssh.com,aes128-gcm@openssh.com,aes256-gcm@openssh.com
 +MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com
 +PubkeyAcceptedAlgorithms ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,sk-ssh-ed25519@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com
 + 
 +# Authentification
 +PermitRootLogin no
 +AllowGroups wheel jump
 + 
 +PasswordAuthentication no
 +PermitEmptyPasswords no
 +KbdInteractiveAuthentication no
 +PubkeyAuthentication yes
 +UsePAM yes
 +
 +# Paramètres de session et de connexion
 +MaxAuthTries 6
 +LoginGraceTime 30
 +ClientAliveInterval 3m
 +ClientAliveCountMax 5
 + 
 +# Comportement à la connexion, environnement
 +PrintLastLog yes
 +PrintMotd no
 +PermitUserEnvironment no
 +AcceptEnv LANG LC_*
 +
 +# Interdiction de session interactive
 +PermitTTY no
 +X11Forwarding no
 +AllowTcpForwarding no
 +PermitTunnel no
 +# Bloque tout shell interactif
 +ForceCommand /bin/false
 +
 +# Journalisation
 +LogLevel VERBOSE
 +
 +# Match précise qui a droit à quoi
 +Match Group jump
 +     # AllowTcpForwarding nécessaire pour que ce soit transmis, 
 +     # Renseigner ensuite les adresses et ports.
 +     AllowTcpForwarding yes
 +     PermitOpen 10.0.0.10:22
 +     PermitOpen 10.0.0.11:22
 +     PermitOpen 10.0.0.12:22
 +
 +Match Group wheel
 +    PermitTTY yes
 +    ForceCommand none
 +</code>
 +
 +<WRAP center round tip 100%>
 +On peut aussi ajouter dans notre config ssh ce bloc : 
 +<code>
 +# Par défaut, interdire tous le monde
 +DenyUsers *
 +
 +# Réautoriser les utilisateurs depuis Bastion1 uniquement
 +Match Address 101.1.1.1
 +    AllowGroups wheel jump
 +</code>
 +Vérifier comment ça réagit, je tâtonne. Potentiellement ça interdit vraiment sauf si on vient du bastion. 
 +
 +Si on veut un accès direct aux sysadmin : 
 +
 +<code>
 +# Par défaut, interdire tous le monde
 +AllowGroups wheel
 +
 +# Réautoriser les utilisateurs depuis Bastion1 uniquement
 +Match Address 101.1.1.1
 +    AllowGroups wheel jump
 +</code>
 +Mais j'aime pas. Je ne le sens pas.
 +</WRAP>
 +
 +=== Nftables ===
 +
 +Il faut aussi paramétrer nftables pour n'accepter que les connexions ssh en provenance de Bastion1. Une config complète [[pratique:informatique:parefeu:nftables#sur_hyperviseur_expose_sur_internet|est dispo ici]], ce qui nous intéresse est dans ces lignes 
 +
 +<code bash /etc/nftables.conf>
 +# Autoriser SSH si :
 +# - source = Bastion1 (externe). mettre son ip, c'est pas 101.1.1.1
 +# - OU source dans le LAN 192.168.1.0/24 (UNIQUEMENT quand on est derrière une box)
 +# SSH ne sera sans doute pas sur le port 22, adapter...
 +ip saddr { 101.1.1.1, 192.168.1.0/24 } tcp dport 22 ct state new accept
 +
 +</code>
 +
 +=== Créer les utilisatrices ===
 +Il faut permettre à Alice de passer en rebondissant et sans s'arrêter, et à Lapin de creuser son trou.
 +
 +Tout en root/sudo : 
 +<code>
 +groupadd wheel
 +groupadd jump
 +useradd alice -m -G jump
 +mkdir /home/alice/.ssh
 +nano /home/alice/.ssh/authorized_keys 
 +# Mettre la clé publique dans ce fichier
 +chown -R alice: /home/alice/.ssh
 +chmod 0700 /home/alice/.ssh/
 +chmod 0600 /home/alice/.ssh/authorized_keys
 +
 +useradd lapin -m -G sudo,wheel  -s /bin/bash
 +passwd lapin
 +mkdir /home/lapin/.ssh
 +nano /home/lapin/.ssh/authorized_keys 
 +# Mettre la clé publique dans ce fichier
 +chown -R lapin: /home/lapin/.ssh
 +chmod 0700 /home/lapin/.ssh/
 +chmod 0600 /home/lapin/.ssh/authorized_keys</code>
 +
 +=== L'hyperviseur a-t-il les bonnes adresses ? ===
 +Bastion2 étant l'hyperviseur, il peut avoir sa façon (unique) de gérer les adresses, suivant le pont etc. Pour vérifier si la VM "192.168.1.10" est réellement joignable sous ce nom :
 +<code>ip route get 192.168.1.10
 +ping 192.168.1.10
 +ip neigh</code>
 +
 +Si ça ne trace pas la route, si ça ne ping pas... la dernière commande liste les ip voisines, ça peut donner des pistes.
 +==== Configuration côté Serveur final ====
 +  * sshd_config
 +  * Accepter uniquement des connexions depuis Bastion2
 +
 +<code bash sshd_config/perso>
 +# Protocole et sécurité de base
 +Protocol 2
 +StrictModes yes
 + 
 +# Chiffrement et algorithmes
 +HostKey /etc/ssh/ssh_host_ed25519_key
 +KexAlgorithms sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com
 +Ciphers chacha20-poly1305@openssh.com,aes128-gcm@openssh.com,aes256-gcm@openssh.com
 +MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com
 +PubkeyAcceptedAlgorithms ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,sk-ssh-ed25519@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com
 + 
 +# Authentification
 +PermitRootLogin no
 +AllowGroups wheel
 + 
 +PasswordAuthentication no
 +PermitEmptyPasswords no
 +KbdInteractiveAuthentication no
 +PubkeyAuthentication yes
 +UsePAM yes
 + 
 +# Paramètres de session et de connexion
 +MaxAuthTries 6
 +LoginGraceTime 30
 +ClientAliveInterval 3m
 +ClientAliveCountMax 5
 + 
 +# Comportement à la connexion, environnement
 +PrintLastLog yes
 +PrintMotd no
 +PermitUserEnvironment no
 +AcceptEnv LANG LC_*
 +
 +# Redirections et accès à distance
 +AllowTcpForwarding no
 +X11Forwarding no
 +</code>
 +
 +=== Cas particulier d'un tunnel ===
 +Dans un cas particulier, j'ai hélas besoin de pouvoir parfois utiliser un [[pratique:informatique:box_fai|tunnel]] (fichue box qui ne se gère pas direct en ssh). On peut ajouter ceci depuis le serveur qui va permettre le tunnel : 
 +
 +<code>
 +Match User alice
 +    AllowTcpForwarding yes
 +    PermitTunnel yes
 +</code>
 +=> seul l'utilisatrice "alice" pourra faire ce tunnel. 
 +
 +Les bastions ont aussi besoin de permettre ce tunnel : 
 +<code>
 +Match User alice
 +    PermitOpen 192.168.1.42:80
 +    AllowTcpForwarding yes
 +</code>
 +
 +==== Configuration côté utilisatrice ====
 +Combien de clés ssh différentes faut-il générer ?
 +  * Une clé par serveur cible
 +  * Une clé pour accéder à la maintenance des bastions (pour les personnes autorisées bien sûr).
 +
 +On différencie bien l'usage du bastion (qui sert juste à "rebondir" jusqu'au serveur final), et l'administration de ces derniers (méga critique : qui a accès au bastion en tant qu'admin peut ensuite y faire plein de choses).
 +
 +On peut ensuite avoir des clés différentes pour chaque serveur cible, par contre cela demande d'adapter sa façon de travailler. Personnellement je préfère utiliser une clé pour un ensemble de serveur de la même galaxie. 
 +
 +En dehors des clés, le seul truc réellement à bidouiller est le fichier "~/.ssh/config" qui simplifiera l'administration. On continuera ensuite de faire "ssh serveur_final" pour aller sur ce dernier, et toute la magie opérera en coulisse.
 +
 +Génération des clés : 
 +<code>ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_alice -C "alice"
 +ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_lapin -C "lapin"</code>
 +
 +  * -t : type, donc ed25519.
 +  * -f : précise le nom du fichier ; permet de retrouver plus facilement ce qui sert "où"
 +  * -C : ajoute un commentaire ; sans rien préciser ce sera votre utilisateur@host du système où vous êtes. 
 +
 +Copier les clés sur les bastions dans "~/.ssh/authorized_keys" (chacun son home). 
 +
 +<code bash ~/.ssh/config></code>
 +
 +=== La partie Alice (au pays des serveurs) ===
 +Alice n'a accès (au final) qu'aux VM ; mais elle doit passer par les deux bastions pour ça. 
 +
 +Génération de sa clé : 
 +<code>ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_alice -C "alice"</code>
 +
 +Copier la clé **publique** sur la/les VM auxquelles elle a accès ainsi que dans les deux bastions, dans ''/home/alice/.ssh/authorized_keys''
 +
 +Son fichier de config avec un seul bastion (tout en local, donc adresse locale !!!). Ça, ça marche.
 +<code bash ~/.ssh/config>
 +# Bastion2 
 +Host bastion2
 +    HostName 192.168.1.22
 +    User alice
 +    IdentityFile ~/.ssh/id_ed25519_alice
 +    ForwardAgent no
 +    
 +# Accès à la VM finale (via les deux bastions)
 +Host vm-finale
 +    HostName 192.168.1.11
 +    User alice
 +    IdentityFile ~/.ssh/id_ed25519_alice
 +    ProxyJump bastion2
 +</code>
 +
 +<WRAP center round todo 60%>
 +<code bash ~/.ssh/config>
 +# Bastion1 - 1er saut
 +Host bastion1
 +    HostName 101.1.1.1
 +    User alice
 +    IdentityFile ~/.ssh/id_ed25519_alice
 +    ForwardAgent no
 +
 +# Bastion2 - 2e saut
 +Host bastion2
 +    HostName 192.168.1.2
 +    User alice
 +    IdentityFile ~/.ssh/id_ed25519_alice
 +    ProxyJump bastion1
 +    ForwardAgent no
 +
 +# Accès à la VM finale (via les deux bastions)
 +Host vm-finale
 +    HostName 192.168.1.11
 +    User alice
 +    IdentityFile ~/.ssh/id_ed25519_alice
 +    ProxyJump bastion2
 +
 +</code>
 +</WRAP>
 +
 +
 +Pour se connecter : 
 +  ssh vm-finale
 +
 +<WRAP center round tip 100%>
 +Attention si on utilise un script (genre [[pratique:informatique:ansible|Ansible]] pour créer les utilisatrices. Une utilisatrice admin sur la VM ne doit PAS être admin sur le bastion. 
 +</WRAP>
 +
  
  
pratique/informatique/bastionssh.1746607653.txt.gz · Dernière modification : 07/05/2025 10:47 de Zatalyz