La tunnellisation des données via SSH est assez simple:
ssh -D9999 [email protected]
configure le port 9999 sur votre localhost
en tant que tunnel sur example.com
, mais j'ai un besoin plus spécifique:
localhost
Host1
est accessible à localhost
Host2
accepte uniquement les connexions à partir de Host1
localhost
à Host2
Effectivement, je veux créer un tunnel SSH "multi-sauts". Comment puis-je faire ceci? Idéalement, j'aimerais le faire sans avoir besoin d'être superutilisateur sur tout des machines.
Vous avez essentiellement trois possibilités:
Tunnel de localhost
à Host1
:
ssh -L 9999:Host2:1234 -N Host1
Comme indiqué ci-dessus, la connexion de Host1
à Host2
ne sera pas sécurisée.
Tunnel de localhost
à Host1
et de Host1
à Host2
:
ssh -L 9999:localhost:9999 Host1 ssh -L 9999:localhost:1234 -N Host2
Cela ouvrira un tunnel de localhost
à Host1
et un autre tunnel de Host1
à Host2
. Cependant, le port 9999
à Host2:1234
peut être utilisé par n'importe qui sur Host1
. Cela peut ou peut ne pas être un problème.
Tunnel de localhost
à Host1
et de localhost
à Host2
:
ssh -L 9998:Host2:22 -N Host1
ssh -L 9999:localhost:1234 -N -p 9998 localhost
Cela ouvrira un tunnel de localhost
à Host1
à travers lequel le service SSH sur Host2
pourra être utilisé. Ensuite, un second tunnel est ouvert de localhost
à Host2
via le premier tunnel.
Normalement, je choisirais l'option 1. Si la connexion de Host1
à Host2
doit être sécurisée, choisissez l'option 2. L'option 3 est principalement utile pour accéder à un service sur Host2
accessible uniquement à partir de Host2
.
Il y a une excellente réponse expliquant l'utilisation de la directive de configuration ProxyCommand
pour SSH :
Ajoutez ceci à votre ~/.ssh/config
(voir man 5 ssh_config
pour plus de détails):
Host host2
ProxyCommand ssh Host1 -W %h:%p
Ensuite, ssh Host2
tunnelera automatiquement à travers Host1
(fonctionne également avec le transfert X11, etc.).
Cela fonctionne également pour toute une classe d'hôtes, par exemple. identifié par domaine:
Host *.mycompany.com
ProxyCommand ssh gateway.mycompany.com -W %h:%p
OpenSSH 7.3 introduit } _ une directive ProxyJump
, simplifiant le premier exemple
Host host2
ProxyJump Host1
OpenSSH v7.3 prend en charge un commutateur -J
et une option ProxyJump
, qui autorisent un ou plusieurs hôtes de saut séparés par des virgules. Vous pouvez donc le faire maintenant:
ssh -J jumpuser1@jumphost1,jumpuser2@jumphost2,...,jumpuserN@jumphostN user@Host
Nous avons une passerelle SSH dans notre réseau privé. Si je suis à l'extérieur et que je veux un Shell distant sur une machine à l'intérieur du réseau privé, je devrais me connecter à la passerelle et de là à la machine privée.
Pour automatiser cette procédure, j'utilise le script suivant:
#!/bin/bash
ssh -f -L some_port:private_machine:22 user@gateway "sleep 10" && ssh -p some_port private_user@localhost
Qu'est-ce qui se passe:
Après avoir lu ce qui précède et avoir tout collé, j'ai créé le script Perl suivant (enregistrez-le sous mssh dans/usr/bin et rendez-le exécutable):
#!/usr/bin/Perl
$iport = 13021;
$first = 1;
foreach (@ARGV) {
if (/^-/) {
$args .= " $_";
}
elsif (/^((.+)@)?([^:]+):?(\d+)?$/) {
$user = $1;
$Host = $3;
$port = $4 || 22;
if ($first) {
$cmd = "ssh ${user}${Host} -p $port -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no";
$args = '';
$first = 0;
}
else {
$cmd .= " -L $iport:$Host:$port";
Push @cmds, "$cmd -f sleep 10 $args";
$cmd = "ssh ${user}localhost -p $iport -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no";
$args = '';
$iport ++;
}
}
}
Push @cmds, "$cmd $args";
foreach (@cmds) {
print "$_\n";
system($_);
}
Usage:
Pour accéder à HOSTC via HOSTA et HOSTB (même utilisateur):
mssh HOSTA HOSTB HOSTC
Pour accéder à HOSTC via HOSTA et HOSTB et utiliser des numéros de port SSH autres que ceux par défaut et des utilisateurs différents:
mssh user1@HOSTA:1234 user2@HOSTB:1222 user3@HOSTC:78231
Pour accéder à HOSTC via HOSTA et HOSTB et utiliser le transfert X:
mssh HOSTA HOSTB HOSTC -X
Pour accéder au port 8080 sur HOSTC via HOSTA et HOSTB:
mssh HOSTA HOSTB -L8080:HOSTC:8080
Cette réponse est similaire à kynan, car elle implique l'utilisation de ProxyCommand. Mais il est plus pratique d'utiliser IMO.
Si vous avez installé netcat sur vos machines de saut, vous pouvez ajouter cet extrait à votre ~/.ssh/config:
Host *+*
ProxyCommand ssh $(echo %h | sed 's/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/\2 -l \1/;s/:/ -p /') nc $(echo %h | sed 's/^.*+//;/:/!s/$/ %p/;s/:/ /')
Ensuite
ssh -D9999 Host1+Host2 -l username
fera ce que vous avez demandé.
Je suis venu ici à la recherche du lieu d'origine où j'ai lu cette astuce. Je posterai un lien quand je le trouverai.
ssh -L 9999:Host2:80 -R 9999:localhost:9999 Host1
-L 9999: hôte 2: 80
Signifie bind to localhost: 9999 et tout paquet envoyé à localhost: 9999 le transmet à Host2: 80
-R 9999: localhost: 9999
Signifie que tout paquet reçu par l'hôte 1: 9999 le renvoie à l'hôte local: 9999
J'ai fait ce que je pense tu voulais faire avec
ssh -D 9999 -J Host1 Host2
On me demande les deux mots de passe, puis je peux utiliser localhost: 9999 pour un proxy SOCKS vers Host2. Je pense le plus près de l'exemple que vous avez montré en premier lieu.
vous devriez pouvoir utiliser la redirection de port pour accéder à un service sur Host2
à partir de localhost
. Un bon guide est situé ici . Extrait:
Il existe deux types de transfert de port: le transfert local et le transfert distant. Ils sont également appelés tunnels sortants et entrants, respectivement. La redirection de port local transfère le trafic arrivant sur un port local à un port distant spécifié.
Par exemple, si vous exécutez la commande
ssh2 -L 1234:localhost:23 username@Host
tout le trafic arrivant sur le port 1234 du client sera transféré sur le port 23 du serveur (hôte). Notez que localhost sera résolu par le serveur sshdserver une fois la connexion établie. Dans ce cas, localhost fait donc référence au serveur (hôte) lui-même.
Le transfert de port distant a l'effet inverse: il transfère le trafic arrivant sur un port distant à un port local spécifié.
Par exemple, si vous exécutez la commande
ssh2 -R 1234:localhost:23 username@Host
tout le trafic qui arrive au port 1234 sur le serveur (hôte) sera transféré au port 23 sur le client (localhost).
Dans votre distribution, remplacez localhost
dans l'exemple par Host2
et Host
par Host1
.
Dans cette réponse, je vais passer à travers un exemple concret. Il vous suffit de remplacer les noms d'hôte, noms d'utilisateur et mots de passe des ordinateurs par les vôtres.
Supposons que nous ayons la topologie de réseau suivante:
our local computer <---> server 1 <---> server 2
Pour des raisons concrètes, supposons que nous possédons les noms d'hôte, noms d'utilisateur et mots de passe des ordinateurs suivants:
LocalPC <---> hostname: mit.edu <---> hec.edu
username: bob username: john
password: dylan123 password: doe456
Objectif: nous voulons configurer un proxy SOCKS qui écoute sur le port 9991
de LocalPC
de sorte que chaque fois qu'une connexion sur LocalPC
est établie à partir du port 9991
, elle passe par mit.edu
puis hec.edu
.
Exemple de cas d'utilisation: hec.edu
possède un serveur HTTP uniquement accessible sur http://127.0.0.1:8001 , pour des raisons de sécurité. Nous aimerions pouvoir visiter http://127.0.0.1:8001 en ouvrant un navigateur Web sur LocalPC
.
Dans LocalPC
, ajoutez ~/.ssh/config
:
Host HEC
HostName hec.edu
User john
ProxyCommand ssh [email protected] -W %h:%p
Ensuite, dans le terminal de LocalPC
, exécutez:
ssh -D9991 HEC
Il vous demandera le mot de passe de bob
sur mit.edu
(i.e., dylan123
), puis vous demandera le mot de passe de john
sur hec.edu
(c.-à-d. doe456
).
À ce stade, le proxy SOCKS s'exécute maintenant sur le port 9991
de LocalPC
.
Par exemple, si vous souhaitez visiter une page Web sur LocalPC
à l'aide du proxy SOCKS, vous pouvez le faire dans Firefox:
Quelques remarques:
~/.ssh/config
, HEC
est le nom de la connexion: vous pouvez le changer en tout ce que vous voulez.-D9991
indique à ssh
de configurer un proxy SOCKS4 sur le port 9991
.Si vous pouvez utiliser SSH sur les deux machines, jetez un coup d'œil à la directive ProxyCommand de ssh. Cela vous permettra d'aller directement de localhost à Host2 (en une seule commande si vous utilisez des clés publiques !!). Ensuite, vous pouvez faire ce que vous voulez avec Host2.
Dans mon cas j'ai fait
localhost$ ssh -D 9999 Host1
Host1$ ssh -L 8890:localhost:8890 Host2
où Host2:8890
est exécuté sur un bloc-notes Jupyter.
Ensuite, j'ai configuré Firefox pour utiliser localhost:9999
en tant qu'hôte SOCKS.
Alors maintenant, le cahier fonctionne sous Host2
accessible par Firefox à localhost:8890
sur ma machine.
L'option 2 de meilleure réponse pourrait être utilisée avec des utilisateurs de ssh différents de l'actuel aka: utilisateur @ hôte
export local_Host_port=30000
export Host1_user=xyz
export Host1=mac-Host
export Host1_port=30000
export Host2=192.168.56.115
export Host2_user=ysg
export Host2_port=13306
# Tunnel from localhost to Host1 and from Host1 to Host2
# you could chain those as well to Host3 ... hostn
ssh -tt -L $local_Host_port:localhost:$Host1_port $Host1_user@$Host1 \
ssh -tt -L $Host1_port:localhost:$Host2_port $Host2_user@$Host2