Comment puis-je SSH à la machine A via B en une seule commande?

103

Je souhaite accéder à un ordinateur, disons à la machine A, située dans le réseau de mon université. Cependant, cet ordinateur n’est accessible que via le réseau interne de l’université, je ne peux donc pas utiliser SSH directement sur cet ordinateur depuis chez moi.

Voici ce que je fais maintenant:

  1. Connectez-vous à une autre machine universitaire, disons la machine B

    (Cette machine B est accessible via SSH à partir de mon ordinateur personnel.)

  2. Utilisez SSH sur B pour vous connecter à A.

Y a-t-il un moyen de le faire plus rapidement? Utiliser une seule commande ssh.

Nikosdi
la source
liées: ssh via plusieurs hôtes
Trevor Boyd Smith

Réponses:

97

Oui, en utilisant ProxyCommanddans votre configuration SSH.

Créez un fichier de configuration SSH dans votre répertoire de base (à moins que vous ne souhaitiez configurer ce système dans son intégralité) ~/.ssh/config:

Host unibroker          # Machine B definition (the broker)
Hostname 12.34.45.56    # Change this IP address to the address of the broker
User myusername         # Change this default user accordingly 
                        # (`user@unibroker` can overwrite it)

Host internalmachine    # Machine A definition (the target host)
ProxyCommand ssh -q unibroker nc -q0 hostname.or.IP.address.internal.machine 22

Vous pouvez maintenant accéder directement à la machine A en utilisant

ssh user@internalmachine

Notez également que vous disposez désormais d'un nom de cible d'hôte SSH unique, que vous pouvez également utiliser dans d'autres applications. Par exemple:

  • SCP pour copier des fichiers.

    scp somefile user@internalmachine:~/
    
  • Dans vos applications graphiques:

    utiliser sftp://user@internalmachine/comme emplacement pour naviguer sur la machine.

    Basé sur KDE (Dolphin): utilisation fish://user@internalmachine/

Remarques

Modifiez hostname.or.IP.address.internal.machineet le port ( 22) sur la machine que vous souhaitez atteindre, comme si vous le vouliez unibroker.

Selon les versions de netcat sur l'hôte unibroker, l' -q0option doit être omise. En ce qui concerne l'authentification; vous configurez essentiellement deux connexions SSH à partir de votre poste de travail. Cela signifie que l'hôte unibroker et l'hôte internalmachine sont vérifiés / authentifiés l'un après l'autre (pour la vérification de la paire de clés / mot de passe et la clé de l'hôte).

Explication

Cette approche de l'utilisation de ProxyCommandet 'netcat' n'est qu'un moyen de le faire. J'aime cela, car mon client SSH parle directement à la machine cible pour que je puisse vérifier la clé de l'hôte auprès de mon client et que je puisse utiliser l'authentification de ma clé publique sans utiliser une autre clé sur le courtier.

Chacun Hostdéfinit le début d'une nouvelle section hôte. Hostnameest le nom d'hôte ou l'adresse IP cible de cet hôte. Userest ce que vous fourniriez en tant que partie utilisateur ssh user@hostname.

ProxyCommandsera utilisé comme tuyau vers la machine cible. En utilisant SSH sur la première machine et en configurant directement un simple 'netcat' ( nc) vers la cible à partir de là, il ne s'agit en fait que d'un texte en clair transmis à la machine interne par le courtier entre ceux-ci. Les -qoptions sont de désactiver toute sortie (juste une préférence personnelle).

Assurez-vous que Netcat est installé sur le courtier (généralement disponible par défaut sous Ubuntu) - netcat-openbsdInstallez netcat-openbsd ou netcat-traditionalInstallez netcat-traditional .

Notez que vous utilisez toujours SSH avec le cryptage deux fois ici. Alors que le canal netcat est en texte clair, votre client SSH sur votre PC configurera un autre canal crypté avec la machine cible finale.

Gertvdijk
la source
4
J'ai dû supprimer l'option -q0 car elle n'était pas supportée par la machine que j'utilisais. Autre que cela, tout a fonctionné. Ceci est un conseil fantastique. Merci beaucoup. :)
Gerry
J'ai rencontré un problème, votre réponse fonctionne correctement pour moi depuis le terminal, mais je ne peux pas le faire en utilisant le sftp gui, il est indiqué: message d'erreur non géré, expiré lors de la connexion.
Vikash B
@VikashB Eh bien, cela devrait vraiment fonctionner. Envisagez de créer une nouvelle question pour gérer votre situation spécifique.
gertvdijk
J'ai fait la question suivante: askubuntu.com/questions/688567/…
Vikash B
1
Pour compléter les propos avisés de @gertvdijk, il existe un excellent livre de prières sur le proxy ssh et les hôtes de saut qui peut servir de référence inestimable.
Travis Clarke
51

Hop d'un coup

Une alternative évidente à l'approche ProxyCommand que j'ai fournie dans mon autre réponse serait de "sauter" directement sur la machine cible:

ssh -t user@machineB ssh user@machineA

Notez le -tsur la première sshcommande. Sans cela, il échouera:

Pseudo-terminal will not be allocated because stdin is not a terminal.
ssh_askpass: exec(/usr/bin/ssh-askpass): No such file or directory
Permission denied, please try again.
[...]

Il va obliger à attribuer un vrai TTY

L'inconvénient est que toute la configuration, la vérification et l'authentification ont maintenant lieu sur la machine B, ce que je n'aime pas du tout dans ma situation pour des raisons de sécurité. J'aime mon clavier sur mon propre PC et authentifie et vérifie la machine cible finale à partir de mon propre PC. En outre, vous ne pouvez utiliser le shell interactif que pour SSH, ce qui ne traitera pas d'autres outils tels que SCP ou l'utilisation de votre gestionnaire de fichiers GUI.

Pour toutes les raisons susmentionnées, je recommande fortement l’approche ProxyCommand , mais pour une connexion rapide, cela fonctionne bien.

Gertvdijk
la source
Pourquoi ne pas avoir une réponse à la fois avec les solutions uniques et permanentes?
demure
5
@ demure C'est comme ça que fonctionnent les sites StackExchange ... Voir: Quelle est l'étiquette officielle pour répondre à une question deux fois? dit « Il est préférable de poster deux réponses différentes, que de les mettre en une réponse. » . Et je ne considère pas que ce soit la même solution. Permanent / temporairement n'est pas ce qui rend cette approche différemment, à mon avis.
gertvdijk
D’autres guides disent d’utiliser, en outre, le commutateur -A, mais indiquent que cela a des implications en matière de sécurité. Savez-vous ce que signifie transférer ou non la connexion de l'agent d'authentification?
Diagon
@ gertvdijk super ninja ici! vous avez les deux meilleures solutions. Je n'ai jamais vu ça auparavant. super cool. Bien mieux que de créer une solution longue avec des solutions N (ce que je vois habituellement).
Trevor Boyd Smith le
C'est beaucoup plus pratique que de configurer une configuration qui gênerait également les autres ssh.
Nikhil Sahu
37

Vous pouvez utiliser l' -Joption de ligne de commande:

ssh -J user@machineB user@machineA

De man ssh:

-J [user@]host[:port]
     Connect to the target host by first making a ssh connection to
     the jump host and then establishing a TCP forwarding to the
     ultimate destination from there.  Multiple jump hops may be
     specified separated by comma characters.  This is a shortcut to
     specify a ProxyJump configuration directive.

Il a été introduit dans OpenSSH version 7.3 (publié en août 2016). Il est disponible dans Ubuntu 16.10 et versions ultérieures.

Erik Sjölund
la source
3
+1 parce que cela fonctionne même si vous devez spécifier le fichier clé machineA
Deuil
1
+1, c'est la meilleure version comparée à ma réponse ProxyCommand si tous vos hôtes exécutent une version OpenSSH suffisamment récente.
gertvdijk
Le serveur OpenSSH doit-il être installé sur les machines A et B dans ce cas? Ai-je bien compris?
Mikhail
17

Essayez d'utiliser

Host <visible hostname alias>
        Controlmaster auto
        User <user>
        hostname <visible hostname>
        port <port>
        IdentityFile ~/.ssh/<id file>

Host <private LAN hostname alias>
     ProxyCommand ssh -q -W <private LAN hostname>:<private LAN port> <visible hostname alias>

dans votre ~ / .ssh / config et faites tout en un avec les touches uniquement sur votre ordinateur.

Aide SSH
la source
1
C'est plus propre que d'introduire netcat dans le mix. De plus, la clé privée SSH n'a pas besoin d'exister sur la Bmachine.
danemacmillan
1

C'est une suggestion très utile. Après des heures de travail, j'ai trouvé cette note et confirmé que cela fonctionnait exactement comme indiqué. Pour vous connecter via MachineA à MachineB, à partir de la machine distante:

par exemple: [xuser @ machineC ~] ssh -t MachineA ssh MachineB

Le "-t" est critique, ssh échoue s'il n'est pas présent. Vous serez invité à deux reprises, un mot de passe sur MachineA, puis une seconde fois sur MachineB. Notez également que cela suppose que l'utilisateur "xuser" soit défini sur les trois ordinateurs. Sinon, utilisez simplement la syntaxe ssh: "yuser @ MachineA ...". Notez également que vous pouvez utiliser des adresses IP brutes quadruples en pointillés, si vous le souhaitez. Ceci est utile si vous vous connectez à un réseau local privé qui utilise des adresses IP non exposées au monde - c'est-à-dire. pas dans votre fichier hôte local, ni dans aucun DNS. Pour obtenir un fichier de MachineB, vers une machine distante, vous pouvez passer de MachineB à MachineA, puis de MachineA vers une machineC distante. (Par exemple, la machineC distante peut envoyer un ping à MachineA, mais pas à MachineB.) Avertissement: j'ai testé avec Fedora et Windows XP, MachineA est un XP-Box exécutant ICS (Internet Connection Sharing), tandis que MachineB et machineC distante sont des boîtes Fedora-Linux. Cette suggestion a résolu un problème clé pour moi - c'est-à-dire. accès à distance restreint et surveillé à mon réseau distant. Notez également que lorsque vous vous "déconnectez" de MachineB, vous devriez voir deux "Connexion à xxx.xxx.xxx.xxx fermée". messages.

Mcl
la source
Si vous configurez et configurez l'authentification par clé publique, vous n'avez pas à vous soucier de la saisie de vos mots de passe. Mais -test toujours nécessaire.
Felipe Alvarez
@FelipeAlvarez Vous devez toujours vous inquiéter de la saisie du deuxième mot de passe si vous ne faites pas confiance à la machine B pour vous connecter sans mot de passe à A!
Michael
1

ProxyCommand est une solution propre pour un cas où vous autorisez l'accès au shell dans les deux systèmes. Nous voulions donner aux utilisateurs distants l'accès à une machine interne (A) par le biais d'un courtier (B), mais sans lui permettre d'accéder au shell à B pour améliorer la sécurité. Cela a fonctionné:

Remplacer le shell de connexion

Remplacez le shell de connexion (utilisez chsh) extusersur le courtier par le script suivant (stocké dans un fichier):

#!/bin/sh   # this is essential to avoid Exec format error
ssh internaluser@A

Si aucun identifiant de mot de passe n'a été défini dans extuser @ B pour l'utilisateur distant et dans internaluser @ A pour extuser @ B, l'exécution de la commande suivante mènera directement l'utilisateur distant à A

ssh extuser@B

Conseil : Créez la configuration nécessaire avec mot_de_passe_auto-autorisée, authorised_keys dans extuser @ B avant de passer au shell de connexion personnalisé. Après la modification, étant donné que ce compte est inaccessible à tous via un shell, seul un sudoer @ B peut modifier le fichier allowed_keys en le modifiant directement.

sudo vi ~extuser/.ssh/authorized_keys
sudo touch ~extuser/.hushlogin

La dernière ligne est de supprimer l'affichage de la bannière de connexion de B, afin que l'utilisateur distant ait un accès transparent à A.

Sunthar
la source
Approche très intéressante. Cependant, les principaux inconvénients sont les suivants: 1) L' utilisation est limitée à l'utilisation standard de SSH (pas de support SFTP / SCP). 2) Un utilisateur ne peut pas sélectionner un autre hôte cible autre que l'hôte unique (car codé en dur dans le shell de connexion). 3) La validation de la clé d'hôte ne peut pas être effectuée d'un poste de travail à l'hôte cible final (car l'utilisation du binaire SSH du courtier) . 4) Les clés privées permettant aux utilisateurs d'accéder à l'hôte cible final résident sur le courtier plutôt que sur l'utilisateur. Cela permet l'emprunt d'identité de l'utilisateur par un administrateur (ce qui n'est normalement pas possible).
gertvdijk
Tous les points sont vrais, merci d'avoir élaboré. Cependant, le but principal est de fournir à un utilisateur de confiance un accès ssh à A sans connexion à B. Comme seul l'administrateur peut ajouter la clé publique de l'utilisateur de confiance sur B (via sudo, sans connexion), cela implique déjà que l'utilisateur a ( admin) l’accès à la clé privée de extuser @ B (pas de l’utilisateur de confiance extérieur) et l’a configurée, en premier lieu!
Sunthar le
1

Vous voulez dire que vous avez besoin de plusieurs cavaliers :)

Récemment, j'ai rencontré ce problème avec jumper1 jumper2 et ma dernière machine, comme pour mon sol

script local:

#!/bin/bash
sshpass -p jumper1Passwd ssh -t jumper1@jumper1IP ./Y00.sh

puis sur le 1er cavalier (qui est mon routeur), j'ai placé un script nommé Y00.sh:

ssh -tt jumper2@jumper2 -i ~/.ssh/id_rsa sshpass -p finalPassWord ssh -tt final@final

Vous pouvez les remplacer par votre adresse IP et vos mots de passe, bonne chance!

Z-Y00
la source