Comment configurer un raccourci pour une connexion SSH via un tunnel SSH

22

Les serveurs de production de mon entreprise (FOO, BAR ...) sont situés derrière deux serveurs de passerelle (A, B). Pour me connecter au serveur FOO, je dois ouvrir une connexion ssh avec le serveur A ou B avec mon nom d'utilisateur JOHNDOE, puis depuis A (ou B) je peux accéder à n'importe quel serveur de production ouvrant une connexion SSH avec un nom d'utilisateur standard (appelons-le WEBBY).

Donc, chaque fois que je dois faire quelque chose comme:

ssh johndoe@a
...
ssh webby@foo
...
# now I can work on the server

Comme vous pouvez l'imaginer, c'est un problème lorsque je dois utiliser scpou si j'ai besoin d'ouvrir rapidement plusieurs connexions.

J'ai configuré une clé ssh et j'utilise également .ssh / config pour certains raccourcis.

Je me demandais si je pouvais créer une sorte de configuration ssh pour taper

ssh foo

et laissez SSH ouvrir / transférer toutes les connexions pour moi. C'est possible?

modifier

La réponse de womble est exactement ce que je cherchais, mais il semble que je ne puisse pas utiliser netcat pour le moment car il n'est pas installé sur le serveur de passerelle.

weppos:~ weppos$ ssh foo -vv
OpenSSH_5.1p1, OpenSSL 0.9.7l 28 Sep 2006
debug1: Reading configuration data /Users/xyz/.ssh/config
debug1: Applying options for foo
debug1: Reading configuration data /etc/ssh_config
debug2: ssh_connect: needpriv 0
debug1: Executing proxy command: exec ssh a nc -w 3 foo 22
debug1: permanently_drop_suid: 501
debug1: identity file /Users/xyz/.ssh/identity type -1
debug2: key_type_from_name: unknown key type '-----BEGIN'
debug2: key_type_from_name: unknown key type 'Proc-Type:'
debug2: key_type_from_name: unknown key type 'DEK-Info:'
debug2: key_type_from_name: unknown key type '-----END'
debug1: identity file /Users/xyz/.ssh/id_rsa type 1
debug2: key_type_from_name: unknown key type '-----BEGIN'
debug2: key_type_from_name: unknown key type 'Proc-Type:'
debug2: key_type_from_name: unknown key type 'DEK-Info:'
debug2: key_type_from_name: unknown key type '-----END'
debug1: identity file /Users/xyz/.ssh/id_dsa type 2
bash: nc: command not found
ssh_exchange_identification: Connection closed by remote host
Simone Carletti
la source

Réponses:

36

Comme une version plus concrète de la réponse de Kyle, ce que vous voulez mettre dans votre ~/.ssh/configdossier est:

host foo
  User webby
  ProxyCommand ssh a nc -w 3 %h %p

host a
  User johndoe

Ensuite, lorsque vous exécutez "ssh foo", SSH tentera de se connecter à SSH johndoe@a, d'exécuter netcat( nc), puis d'effectuer une connexion SSH à webby@footravers ce tunnel. La magie!

Bien sûr, pour ce faire, netcat doit être installé sur le serveur de passerelle; ce package est disponible pour toutes les principales distributions et OS.

womble
la source
Excellent! J'essayais de comprendre cela, je n'avais jamais rencontré cette situation auparavant. Je vais garder ma réponse là, au cas où cela pourrait aider quelqu'un d'autre avec une situation moins spécifique à l'avenir.
Kyle Brandt
J'ai mis à jour ma question d'origine, y compris la sortie détaillée de ma connexion. Il semble que je ne puisse pas utiliser netcat. Doit-il être disponible par défaut?
Simone Carletti
Pas toujours, avez-vous le pouvoir de l'installer? Vous pourriez peut-être le faire aussi avec telnet, je n'ai jamais essayé ça ...
Kyle Brandt
Vous pouvez également télécharger netcat dans votre répertoire personnel et le compiler là-bas. Vous pouvez alors simplement utiliser le chemin complet dans la commande proxy, c'est-à-dire / home / userName / bin / nc
Kyle Brandt
Je viens de vérifier les paramètres du système. Sur Ubuntu, netcat semble être disponible par défaut, malheureusement les serveurs de passerelle sont alimentés par OpenSUSE. Je vais également envisager d'installer netcat sur les serveurs de passerelle.
Simone Carletti
7

Vous pouvez utiliser la directive ProxyCommand dans votre fichier ~ / .ssh / config, par exemple pour utiliser netcat comme relais:

host server2
    ProxyCommand ssh server1 nc server2 22

Vous utiliseriez simplement 'ssh server2'. Les informations de page de manuel pour cette directive se trouvent dans 'man ssh_config'

Kyle Brandt
la source
5

Je préfère une approche différente qui maintient un tunnel pré-authentifié vers le serveur de passerelle. Dans ~/.ssh/config:

Host a
    ControlMaster auto
    ControlPath ~/.ssh/control-master/%r@%h:%p

Puis dans .bashrc:

s () {
        if ( ssh -O check a 2>&1 > /dev/null 2>&1 )
        then
                ssh -t a ssh $1
        else
                if [[ -S ~/.ssh/control-master/insyte@a:22 ]]
                then
                        echo "Deleting stale socket..."
                        rm ~/.ssh/control-master/insyte@a:22
                fi
                echo "Opening master session..."
                if ssh -Nf a
                then
                         ssh -t a ssh $1
                fi
        fi
 }

Donc, pour vous connecter à foo:

s foo

La première fois que vous vous connectez, il vous authentifiera contre "a" et ouvrira un tunnel ssh persistant et en arrière-plan. Les appels suivants à "s" s'ouvriront presque instantanément à travers le tunnel pré-authentifié.

Fonctionne très bien.

Insyte
la source
2

Ce type de fonctionnalité existe dans les versions plus récentes d'OpenSSH et peut être utilisé en faisant

ssh -W server2 server1

server2est votre destination prévue et server1votre hôte proxy. Vous pouvez rendre cela plus facile en utilisant l' ProxyCommandoption dans votre configuration ssh, quelque chose comme:

host = *.example.com
user = packs
port = 22
ProxyCommand ssh -W %h:%p server1
Scott Pack
la source
Il semble que pour que cela fonctionne, vous avez besoin d'OpenSSH 5.4+ aux trois emplacements: bureau, intermédiaire, destination. (Eh bien, le premier et le dernier, certainement).
Steve Bennett
@SteveBennett: J'utilise cette méthode depuis un moment maintenant, cela fonctionne très bien. J'ai dû revenir à la méthode netcat sur quelques systèmes RHEL5, ce qui était ennuyeux.
Scott Pack
2

Lorsque netcatn'est pas disponible sur le proxy, essayez cette astuce:

host foo
  User webby      
  ProxyCommand ssh a 'exec 3<>/dev/tcp/foo/22; cat <&3 & cat >&3;kill $!'

host a
  User johndoe

Vous devriez alors pouvoir ssh foo.

De plus, si vous avez une version récente de ssh sur un (c'est-à-dire avec la -Wcommande de transfert d'entrée et de sortie standard), vous pourrez peut-être utiliser:

host foo
  User webby
  ProxyCommand ssh -W foo:%p a

host a
  User johndoe

Enfin, juste parce que je l'ai trouvé cool (et non pas parce que cela fonctionnera dans votre cas particulier, en raison des différences de nom d'utilisateur), le blog d'un ami montre comment rendre ce genre de chose dynamique et chaîner récursivement des proxys SSH (ainsi que certaines choses) qui ne fonctionnent pas bien):

host */*
  ProxyCommand ssh ${$(dirname %h)/\%%/@} nc ${$(basename %h)#*%%} %p

Et puis ssh machine1/machine2devrait vous donner un obus machine2, tunnel à travers machine1.

Je me demande si l'utilisation de sedcommandes personnalisées au lieu de dirnameet basenamepourrait ne pas résoudre le problème avec des noms d'utilisateur différents?

Paul Price
la source
2

Cela peut être accompli en faisant ssh -At johndoe@a ssh webby@foo. La -Acommande transfère votre agent ssh (afin que vous puissiez éviter d'avoir à vous authentifier de nouveau sur le proxy), tandis que le -tassure qu'un terminal existe sur le proxy. La fonction bash suivante peut être utile:

ssh-bounce () {
    local cmd=""
    for i in "$@"; do
        cmd+="ssh -At $i "
    done
    $cmd
}
Marcin
la source
C'est de loin la solution la plus simple. Maintenant, il lui faut juste 35 autres votes positifs. (Btw the -A ne fait rien pour moi.)
Steve Bennett
0
weppos:~ weppos$ ssh foo -vv
[..]
bash: nc: command not found

Netcat n'est pas installé sur a. Lorsque vous exécutez ssh host "command arg", commandest exécuté sur host, pas sur votre ordinateur local.

Markdrayton
la source
Oui je sais. C'est exactement ce que j'ai rapporté dans un commentaire à la réponse de womble. :)
Simone Carletti
0

Depuis OpenSSH 7.3 (2016-08-01), l' ProxyJumpoption et l' -Jindicateur de ligne de commande correspondant sont disponibles pour permettre une indirection plus simple via un ou plusieurs bastions SSH ou «hôtes de saut».

Cela supprime la dépendance à la nccommande externe telle que trouvée dans la solution de Womble .

ssh -J johndoe@a webby@foo 

établira une connexion SSH de votre poste de travail au serveur de passerelle en atant qu'utilisateur johndoe et créera un tunnel sur la session SSH pour héberger foo pour l'utilisateur Webby.

Pour simplifier la création de définitions d'hôte pour votre ~/.ssh/configet votre , vous pouvez simplement exécuterssh foo

Host a
    User johndoe

Host foo
    User Webby 
    ProxyJump a
HBruijn
la source