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


Je veux accéder à un ordinateur, disons machine A qui est basé sur 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 depuis cet ordinateur depuis cet ordinateur.

Voici ce que je fais maintenant:

  1. Connectez-vous à une autre machine universitaire, par exemple machine B

    (Cette machine B est accessible via SSH depuis 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


70
2018-06-22 15:03


origine




Réponses:


Oui, en utilisant ProxyCommand dans votre configuration SSH.

Créez un fichier de configuration SSH dans votre répertoire personnel (sauf si vous souhaitez que cela soit à l’échelle du système), ~/.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

Maintenant, vous pouvez atteindre la machine A directement en utilisant

ssh user@internalmachine

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

  • SCP pour copier des fichiers.

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

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

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

Remarques

Changement hostname.or.IP.address.internal.machine et le port (22) à la machine que vous souhaitez atteindre comme si vous le feriez du unibroker machine.

Selon les versions de netcat sur l'hôte unibroker, le -q0 l'option doit être omise. Concernant 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 de machine interne sont vérifiés / authentifiés l'un après l'autre (à la fois pour la vérification de la paire de clés / mot de passe et de la clé de l'hôte).

Explication

Cette approche de l'utilisation de ProxyCommand et '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 à partir de mon client et que je peux utiliser mon authentification par clé publique sans utiliser une autre clé sur le courtier.

Chaque Host définit le début d'une nouvelle section hôte. Hostname est le nom d'hôte ou l'adresse IP cible de cet hôte. User est ce que vous fourniriez en tant que partie d'utilisateur dans ssh user@hostname.

ProxyCommand sera utilisé comme tuyau vers la machine cible. En utilisant SSH sur la première machine et en configurant directement un simple 'netcat' (nc) à la cible à partir de là, il s’agit simplement d’un texte en clair transmis à la machine interne par le courtier entre ceux-ci. le -q les options consistent à faire taire toute sortie (juste une préférence personnelle).

Assurez-vous que netcat est installé sur le courtier (généralement disponible par défaut sur Ubuntu) - soit netcat-openbsd Install netcat-openbsd ou netcat-traditionnel Install netcat-traditional.

Notez que vous utilisez toujours SSH avec le cryptage deux fois ici. Bien que le canal netcat soit en clair, votre client SSH sur votre PC configurera un autre canal crypté avec l’ordinateur cible final.


77
2018-06-22 15:24



J'ai dû supprimer l'option -q0 car elle n'était pas supportée par la machine que j'utilisais. A part ça, tout a fonctionné. Ceci est une astuce FANTASTIQUE. Merci beaucoup. :) - Gerry
J'ai rencontré un problème, votre réponse fonctionne bien pour moi depuis le terminal, mais je ne peux pas le faire en utilisant l'interface graphique, il est écrit: message d'erreur non géré, expiré lors de la connexion. - Vikash B
@VikashB Eh bien, ça devrait vraiment marcher. Envisagez de créer une nouvelle question pour gérer votre situation spécifique. - gertvdijk
J'ai fait ici la question: askubuntu.com/questions/688567/… - Vikash B
Pour compléter le mot sage de @gertvdijk, il y a un super wikibook sur le sujet de ssh proxies et jump hosts cela peut servir de référence inestimable. - Travis Clarke


Hop en une seule fois

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

ssh -t user@machineB ssh user@machineA

Noter la -t au premier ssh commander. Sans elle, cela é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.
[...]

Cela obligera à attribuer un vrai TTY

En contrepartie, la configuration, la vérification et l'authentification se font désormais à la machine B, ce que je n'aime vraiment pas dans ma situation pour des raisons de sécurité. J'aime ma paire de clés sur mon propre PC et authentifie et vérifie la machine cible finale à partir de mon propre PC. De plus, vous ne pouvez utiliser que le shell interactif pour SSH, ce qui ne concerne pas d'autres outils comme SCP ou le gestionnaire de fichiers de votre interface graphique.

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


36
2018-06-22 15:47



Pourquoi ne pas avoir une seule réponse avec les solutions «One Off» et Permanent? - demure
@demure Voilà comment les sites StackExchange fonctionnent ... Voir: Quelle est l'étiquette officielle pour répondre à une question deux fois? dit "Il est préférable d'afficher deux réponses différentes, plutôt que de les regrouper en une seule réponse.". Et je ne considère pas que ce soit la même solution. Ce n'est pas ce qui rend cette approche différente, à mon avis, de manière permanente / temporaire. - gertvdijk
travaux ! Je vous remercie ! - nikosdi


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 seul coup avec des clés résidant uniquement sur votre ordinateur.


14
2017-07-29 13:49



Terriblement formaté par défaut: - SSH Help
C'est plus propre que d'introduire netcat dans le mix. De plus, la clé SSH privée n’a pas besoin d’exister sur le B machine non plus. - danemacmillan


Vous pouvez utiliser le -J option 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 (sortie en août 2016). Il est disponible dans Ubuntu 16.10 et versions ultérieures.


11
2018-01-16 16:19



+1 car cela fonctionne même si vous devez spécifier un fichier de clé pour machineA - Grief


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 un accès à une machine interne (A) via un courtier (B), mais sans permettre à l'utilisateur d'accéder à B pour améliorer la sécurité. Cela a fonctionné:

Remplacez le shell de connexion

Remplacez le shell de connexion (utilisez chsh) pour extuser sur le courtier avec le script suivant (stocké dans un fichier):

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

Si aucun mot de passe de connexion n’a été défini dans extuser @ B pour l’utilisateur distant et dans interneuser @ A pour extuser @ B, alors l’exécution de la commande suivante amènera directement l’utilisateur distant à A

ssh extuser@B

Pointe: Créez la configuration nécessaire author_keys sans mot de passe dans extuser @ B avant de passer au shell de connexion personnalisé. Après le changement, puisque ce compte est inaccessible à quiconque via un shell, seul un sudoer @ B peut apporter des modifications au fichier authorized_keys en le modifiant directement.

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

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


1
2018-06-08 18:27



Approche très intéressante. Cependant, les principaux inconvénients sont les suivants: 1) L'utilisation est limitée à l'utilisation SSH standard (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é de l'hôte ne peut pas être effectuée depuis le poste de travail vers l'hôte cible final (depuis 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'usurpation d'identité de l'utilisateur par un administrateur (ce qui n'est pas possible normalement). - gertvdijk
Tous les points sont vrais, merci d'avoir élaboré. Cependant, le but principal est de fournir à un utilisateur ssh un accès à A sans se connecter à 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) accès à la clé privée de extuser @ B (pas de l'utilisateur de confiance en dehors), et l'a configuré, en premier lieu! - Sunthar


C'est une suggestion très utile. Après avoir gâché pendant des heures, j'ai trouvé cette note, et a confirmé que cela fonctionne exactement comme documenté. Pour se connecter via MachineA à MachineB, à partir de machineC 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 fois, d'abord pour le mot de passe sur MachineA, puis la deuxième fois pour MachineB. Notez également que cela suppose que l'utilisateur "xuser" soit défini sur tous trois machines. Sinon, utilisez simplement la syntaxe ssh: "yuser @ MachineA ...". Notez également que si vous le souhaitez, vous pouvez utiliser les adresses IP brutes en quad. Ceci est utile si vous reliez via un réseau local privé qui utilise des adresses IP non exposées au monde - c.-à-d. pas dedans votre fichier hôte local ou tout DNS. Pour obtenir un fichier de MachineB, sur un ordinateur distant, Vous pouvez passer de MachineB à MachineA, puis de MachineA à un ordinateur distant. (Par exemple, le machineC distante peut envoyer une requête ping à MachineA, mais pas à MachineB.) Mise en garde: J'ai testé avec Fedora et WindowsXP, MachineA est une boîte exécutant ICS (Internet Connection Sharing), tandis que MachineB et machineC distant sont des boîtiers Fedora-Linux. Cette suggestion a résolu un problème clé pour moi - c.-à-d. accès à distance limité et surveillé au réseau local de mon site distant. Notez également que lorsque vous vous déconnectez de MachineB, vous devriez voir deux "Connection à xxx.xxx.xxx.xxx fermé". messages.


0
2018-04-16 22:34



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 -t est toujours nécessaire. - Felipe Alvarez
@FelipeAlvarez Vous devez toujours vous soucier de saisir le deuxième mot de passe si vous ne faites pas confiance à la machine B pour vous connecter sans mot de passe à A! - Michael