Serveur Bastion: utilisez le transfert TCP VS en plaçant la clé privée sur le serveur

10

Nous avons le serveur bastion B. Nous devons SSH de A à B à C, en utilisant une clé privée.

Quelle est la meilleure option:

  • Mettez la clé SSH privée sur le serveur B. Nous lisons que c'est une mauvaise idée de le faire dans un environnement de production.

    D' ici :

    Ne placez jamais vos clés privées SSH sur l'instance de bastion. Utilisez plutôt le transfert d'agent SSH pour vous connecter d'abord au bastion, puis à d'autres instances dans des sous-réseaux privés. Cela vous permet de conserver votre clé privée SSH uniquement sur votre ordinateur.

  • Utilisez le transfert d'agent SSH . Pour configurer le transfert d'agent, je dois autoriser le transfert TCP. Lors de la configuration du transfert d'agent, un fichier socket est créé sur l'hôte de transfert, qui est le mécanisme par lequel la clé peut être transférée vers la destination. Dans les paramètres du Bastion sur AWS:

    TCP forward: Si vous définissez cette valeur sur true, le transfert TCP (tunnel SSH) sera activé. Cela peut être très utile, mais c'est également un risque pour la sécurité, nous vous recommandons donc de conserver le paramètre par défaut (désactivé) sauf si requis.

    Aussi d' ici :

    Le transfert d'agent SSH est considéré comme dangereux

Qu'est-ce qui est mieux? Qu'en est-il de l'alternative du deuxième lien: ProxyCommand , je comprends que cela aide avec le problème du fichier de socket, mais je pense toujours que je dois activer le transfert TCP, est-il donc suffisamment sécurisé?

user2503775
la source
2
Avec ProxyCommand, vous n'avez pas besoin d'activer le transfert TCP. Le transfert est effectué par ssh sur l'hôte intermédiaire.
wurtel
Merci. Le fichier de configuration devait-il être? dans mon ordinateur ou dans le Bastion?
user2503775
Sur votre système local, où vous ssh hostbentrerez la commande, afin qu'il puisse rechercher hostb dans la configuration locale et savoir qu'il doit se connecter via hosta. Ça ne pourrait pas faire ça si vous mettez la config sur hosta ...
wurtel
Où la clé privée du serveur C sera-t-elle stockée? aussi dans ma maquette? J'utilise Keepass avec keeAgent
user2503775
2
Je crains que vous ne confondiez le transfert TCP avec le transfert d' agent . Ce sont des choses différentes.
MLu

Réponses:

13

Utilisez ProxyCommand ou ProxyJump

Je recommanderais d'utiliser ProxyCommand(ou mieux encore ProxyJumpcar la syntaxe est plus facile mais nécessite openssh 7.3+ je pense du côté client), et vous n'avez pas besoin de déployer de clé privée sur le Bastion, tout reste local.

Exemple avec ProxyJump

Sur votre ordinateur client, vous écrivez un fichier ~/.ssh/configavec un contenu similaire à ci-dessous:

Host bastion
  HostName bastion.example.com
  User bastion-user
  Port 22
  IdentityFile ~/.ssh/id_bastion

Host srvC
  HostName srvC.local
  User server-user
  IdentityFile ~/.ssh/id_protected_lan
  ProxyJump bastion

Ensuite ssh srvC, vous serez connecté à C via B (bastion) sans transfert d'agent ni déploiement de la clé privée sur le bastion.

Dans l'exemple ci-dessus, "bastion" est un alias pour votre hôte Bastion et srvC est un alias pour votre serveur C. Dans le, HostNamevous devez mettre soit des adresses IP, soit un vrai nom de domaine complet pour vos hôtes. Pour les utilisateurs, vous devez mettre à jour le Userpour le nom de connexion correct sur le Bastion et le serveur C. Enfin, IdentityFilec'est facultatif si vous utilisez un agent local (par exemple KeeAgent ou ssh-agent), mais s'il n'est pas en cours d'exécution, il le sera également travailler et vous demander pour chaque mot de passe clé.

Déployer les clés publiques

Bien sûr, vous devez déployer les clés publiques sur bastion et srvC. Vous pouvez utiliser (le signe $ est juste pour illustrer l'invite, ne le tapez pas):

$ ssh-copy-id -i ~/.ssh/id_bastion.pub \
   -o PreferredAuthentications=password \
   -o PubkeyAuthentication=no \
   bastion
$ ssh-copy-id -i ~/.ssh/id_protected_lan.pub \
   -o PreferredAuthentications=password \
   -o PubkeyAuthentication=no \
   srvC

Remarque: ce qui précède ne fonctionnera que si l'authentification par mot de passe est toujours autorisée. Après le déploiement ci-dessus et en vérifiant que tout fonctionne comme prévu, vous devez interdire l'authentification par mot de passe sur les 2 serveurs.

Exemple avec ProxyCommand au lieu de ProxyJump

Si vous disposez d'une ancienne version d'OpenSSH qui ne prend pas en charge ProxyJump(côté client), remplacez:

ProxyJump bastion

par

ProxyCommand ssh -q -W %h:%p bastion

Pour autant que je sache, c'est similaire.

Huygens
la source
Je vous remercie! Je travaille avec Linux, mais certains membres de l'équipe travaillent sur Windows. Cela devrait aussi fonctionner là-bas, n'est-ce pas?
user2503775
Quel client SSH vont-ils utiliser? OpenSSH (via WSL, ou cygwin ou etc.) ou PuTTY (ou un autre outil basé sur PuTTY) comme MobaXterm?
Huygens
Certains d'entre eux utilisent PuTTy et d'autres utilisent ssh via Git Shell.
user2503775
@ user2503775 Je ne l'ai jamais essayé avec PuTTY, mais cela semble possible en utilisant l'approche ProxyCommand, voir ici: stackoverflow.com/a/28937185
Huygens
1
Merci beaucoup pour la réponse détaillée!
user2503775
5

J'ai vu la réponse à propos de ProxyJump. Parlons de ProxyCommand .

Mais attendez, attendez! Je peux vous écrire comment pirater le serveur qui utilise le transfert d'agent, ce serait beaucoup plus facile de comprendre la différence!

Hackons!

Pour les étapes de base: vous pouvez lire mon article ici

Les étapes de base sont les suivantes:

  1. Créer des utilisateurs de bastion
  2. Désactiver la connexion root
  3. Bloquer les tentatives de piratage
  4. Changer de port
  5. Configurer le pare-feu
  6. Configurer SELinux

Comment utiliser AgentForwarding

-Créer la configuration dans ~ / .ssh / config

  Host bast
        Hostname BASTION_IP
        ForwardAgent yes
        User bastion

-Ajoutez votre clé d'authentification à ssh-agent

ssh-add ~/.ssh/name_rsa

-Connectez-vous au bastion hos

ssh bast

-Connectez le serveur d'applications du bastion

 ssh app@IP -p PORT

Le piratage!

Vous pouvez, bien, me poser la question:

  • Mon serveur est-il sécurisé? Et la réponse est assez simple:

    • NON!
  • Pourquoi?

    • Parce que vous utilisez le transfert d'agent SSH!
  • Et où est le problème?

    • Parce que le transfert d'agent est dangereux et considéré comme nuisible.
  • Pourquoi?

    • Expliquons tout à l'intérieur: lorsque vous connectez l'hôte bastion, votre glorieux agent ssh est transféré. Cela signifie que le socket sera configuré pour que quelqu'un puisse utiliser ces données de socket pour accéder à vos serveurs. Imaginez que votre serveur bastion soit compromis, si quelqu'un a des autorisations suffisantes sur votre serveur Linux, il / elle utilisera simplement vos informations de socket. En conséquence, tout votre serveur est accessible. Je sais que la fenêtre de compromis est très petite, car cela dépend du temps que vous êtes connecté à l'hôte bastion. Mais voulez-vous vraiment prendre le risque lorsque vous avez d'autres options comme ProxyCommand? Par conséquent, utilisez simplement ProxyCommand!

Comment pirater les serveurs si vous avez compromis l'hôte bastion?

Suivre la cible

Dans le répertoire / tmp, vous pouvez voir quelque chose comme ça:

[root@localhost tmp]# ll
total 12
drwx------  2 bastion bastion 4096 Sep  7 17:35 ssh-mKX88v0Vlo

Ouvrons le fichier temporaire

[root@localhost tmp]# cd ssh-mKX88v0Vlo/
[root@localhost ssh-mKX88v0Vlo]# ll
total 0
srwxr-xr-x 1 bastion bastion 0 Sep  7 17:35 agent.10507

Voyons les connexions à cet identifiant de processus.

netstat -nxp | grep  10507

résultat:

unix  [ ]   STREAM     CONNECTED     501384   10507/sshd: bastion

et qui est connecté?

lsof -i -a -p 10507

résultat:

COMMAND  PID   USER  FD  TYPE DEVICE SIZE/OFF NODE NAME
sshd    10507 bastion  3u  IPv4 501301  0t0  TCP *IP*:ssh->*IP*:8279 (ESTABLISHED)

Nous pouvons également voir les fichiers socket:

cd /proc/10507/fd/
ls

résultat:

lrwx------ 1 root root 64 Sep  7 17:46 0 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 1 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 10 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:46 14 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:46 15 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:46 2 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 3 -> socket:[501994]
lrwx------ 1 root root 64 Sep  7 17:46 4 -> socket:[502069]
lrwx------ 1 root root 64 Sep  7 17:46 5 -> socket:[502072]
l-wx------ 1 root root 64 Sep  7 17:46 6 -> /run/systemd/sessions/1836.ref
lr-x------ 1 root root 64 Sep  7 17:46 7 -> pipe:[502079]
l-wx------ 1 root root 64 Sep  7 17:46 8 -> pipe:[502079]
lrwx------ 1 root root 64 Sep  7 17:46 9 -> socket:[502080]

Et que se passe-t-il lorsque le client sera connecté au serveur distant? Voyons voir:

lrwx------ 1 root root 64 Sep  7 17:46 0 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 1 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 10 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:48 11 -> socket:[502267]
lrwx------ 1 root root 64 Sep  7 17:46 14 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:46 15 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:46 2 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 3 -> socket:[501994]
lrwx------ 1 root root 64 Sep  7 17:46 4 -> socket:[502069]
lrwx------ 1 root root 64 Sep  7 17:46 5 -> socket:[502072]
l-wx------ 1 root root 64 Sep  7 17:46 6 -> /run/systemd/sessions/1836.ref
lr-x------ 1 root root 64 Sep  7 17:46 7 -> pipe:[502079]
l-wx------ 1 root root 64 Sep  7 17:46 8 -> pipe:[502079]
lrwx------ 1 root root 64 Sep  7 17:46 9 -> socket:[502080]

Nous pouvons même voir si le fichier socket est utilisé en utilisant netstat:

unix  3 [ ]  STREAM  CONNECTED  502267  10561/sshd: 
                     bastion  /tmp/ssh-oVoMXC6vb8/agent.10561
unix  3  [ ] STREAM     CONNECTED     502072   10561/sshd:  bastion 

Voler les informations de socket et l'adresse IP

Maintenant, nous devons voler les informations de socket pendant que la session de l'hôte bastion est ouverte . Oh, nous avons également besoin de l' IP du serveur de destination , alors utilisez simplement netstat:

netstat -tn

La dernière étape pour utiliser le fichier de socket transféré

eval "$(ssh-agent -s)"
SSH_AUTH_SOCK=/tmp/ssh-EAKxOdL4fl/agent.10507

Vérifiez si la clé est chargée .

ssh-add -l

le résultat devrait être quelque chose comme ça :

2048 SHA256:2Psdl..B5KQ /home/usr/.ssh/name_rsa (RSA)

Le serveur est piraté, comment résoudre le problème de sécurité?

Commande proxy

Host app
    Hostname *.*.*.*
    IdentityFile ~/.ssh/your_rsa
    User *******
    Port ****
    ProxyCommand ssh -W %h:%p bast

Host bast
     Hostname *.*.*.*
     ForwardAgent no
     User ******

Pour les opérations de base: comment transférer des fichiers via les serveurs (de client à serveur, de serveur à client), vous pouvez lire sur mon post ici

Conclusion

  • Si vous utilisez l'hôte bastion, n'utilisez pas AgentForwarding mais utilisez ProxyCommand
  • Toujours utiliser un utilisateur non root pour l'authentification
  • Utilisez un pare-feu et bloquez toutes les connexions inutiles.
  • Utilisez SELinux (en général)
  • Bloquer l'adresse IP qui essaie de se connecter plusieurs fois avec des informations d'identification incorrectes
  • Si ce n'est pas nécessaire, ne donnez pas l'autorisation sudo à l'utilisateur
  • Surveillez votre serveur
  • Mettez à jour votre serveur pour les correctifs de sécurité

Plus d'informations, voir mon blog . De plus, j'ai quelques captures d'écran, donc cela peut vous être utile.

grep
la source
Merci beaucoup! en fait, nous utilisons également l'authentificateur Google lors de la connexion.
user2503775
Je reçois une erreur lorsque vous essayez d'appeler l' application ssh: channel 0: open failed: administratively prohibited: open failed. stdio forwarding failed. . Avez-vous une idée pourquoi?. Au journal sécurisé, je vois:refused local port forward: originator 127.0.0.1 port 65535, target *app-ip* port 22
user2503775
Info cool. Un petit conseil pour améliorer la lisibilité de votre réponse. Ne copiez / collez pas le contenu de votre blog ici. Fournissez le lien et juste un résumé. Mettez ensuite en surbrillance la vraie partie de la réponse (qui pour vous utilise ProxyCommand). Je vous ai vu en quelque sorte essayé au début mais étant donné la partie copier / coller, c'était un peu déroutant. Quoi qu'il en soit +1
Huygens
@ user2503775 Ce devrait être un problème différent, pas de commande de transfert / proxy ssh-agent. Ouvrons une nouvelle question avec des journaux.
grep
J'ai fait: serverfault.com/questions/958768/…
user2503775
4

Utilisez simplement le transfert d'agent SSH comme la plupart des autres.

  • Les clés seront dans l' agent ssh sur votre ordinateur portable.
  • Vous vous connectez à bastion, authentifié via l'agent.
  • De là, connectez-vous à votre hôte cible, avec une demande d'authentification renvoyée à votre ordinateur portable .

Avantage: aucune clé stockée sur le bastion ne peut être mal utilisée.

J'espère que ça t'as aidé :)

MLu
la source
Salut, c'est essentiellement ce que le PO décrit dans sa deuxième puce. Je vous conseille de vérifier le deuxième lien fourni dans la question.
Huygens
@Huygens true j'ai remarqué maintenant. J'ai chevauché cela alors qu'il mélange le transfert TCP avec le transfert d'agent.
MLu
En effet, c'est mélangé :-)
Huygens
Ce n'est pas mélangé. Je comprends la différence. J'ai modifié la question pour la clarifier.
user2503775
J'ai écrit une réponse, comment pirater le transfert d'agent (il n'y a pas de clé mais il y a un socket ouvert). Généralement, le transfert d'agent est correct car la possibilité de voler les clés est très faible - tout d'abord, vous devez pirater l'hôte bastion. Quoi qu'il en soit, vous pouvez voir ma réponse: serverfault.com/a/958466/476642
grep