ssh -L przekierowuje wiele portów


129

Obecnie prowadzę kilka:

sudo ssh -L PORT:IP:PORT root@IP

gdzie IP jest celem zabezpieczonej maszyny, a PORT reprezentuje porty, które przekazuję.

Dzieje się tak, ponieważ używam wielu aplikacji, do których nie mogę uzyskać dostępu bez tego przekazywania. Po wykonaniu tej czynności mogę uzyskać dostęp przez localhost:PORT.

Główny problem pojawił się teraz, kiedy mam 4 z tych portów, które muszę przekazać.

Moim rozwiązaniem jest otwarcie 4 powłok i ciągłe przeszukiwanie historii wstecz w celu wyszukania dokładnie, które porty mają zostać przekierowane itp., A następnie uruchomienie tego polecenia - po jednej w każdej powłoce (konieczność wpisywania haseł itp.).

Gdybym tylko mógł zrobić coś takiego:

sudo ssh -L PORT1+PORT2+PORT+3:IP:PORT+PORT2+PORT3 root@IP

to już by naprawdę pomogło.

Czy istnieje sposób, aby to ułatwić?

Odpowiedzi:


195

-LOpcja może być podana wiele razy w ciągu tego samego polecenia. Za każdym razem z różnymi portami.


20
Na początku nie rozumiałem tej odpowiedzi. Dlatego zamieszczam tutaj przykład na wypadek, gdyby ktoś cierpiał tak samo. Autor miał na myśli „ssh -L port0: ip: port0 -L port1: ip: port1 ...”
Mong H. Ng

96

Co dokładnie na odpowiedział NaN , podajesz wiele argumentów -L. Robię to cały czas. Oto przykład przekierowania wielu portów:

ssh remote-host -L 8822:REMOTE_IP_1:22 -L 9922:REMOTE_IP_2:22

Uwaga : wygląda to tak samo, jak w -L localhost:8822:REMOTE_IP_1:22przypadku braku określenia localhost.

Teraz możesz teraz (z innego terminala) zrobić:

ssh localhost -p 8822

do podłączenia do REMOTE_IP_1portu22

i podobnie

ssh localhost -p 9922

do połączenia REMOTE_IP_2portu22

Oczywiście nic nie stoi na przeszkodzie, aby zawrzeć to w skrypcie lub zautomatyzować, jeśli masz wiele różnych hostów / portów do przesłania i do niektórych konkretnych.

Mam nadzieję że to pomoże.


Świetne uzupełnienie odpowiedzi Nan. Dzięki.
AFP_555

1
Uważaj na to: „Uwaga: to jest to samo, co -L localhost: 8822: REMOTE_IP_1: 22, jeśli nie określisz localhost”. Dzieje się tak tylko wtedy, gdy ustawienie GatewayPorts ma wartość „nie”, co jest wprawdzie wartością domyślną. Ale biorąc pod uwagę konsekwencje, jeśli tak nie jest, powinieneś zweryfikować ustawienie lub, jeszcze lepiej, być jawnym i użyć „-L localhost: 8822 ...”.
David

Zgadzam się z @David By default, anyone (even on different machines) can connect to the specified port on the SSH client machine. However, this can be restricted to programs on the same host by supplying a bind address: ssh -L 127.0.0.1:80:intra.example.com:80 gw.example.com ssh.com/ssh/tunneling/example
Karl Pokus

24

Możesz użyć następującej funkcji bash (po prostu dodaj ją do swojego ~/.bashrc):

function pfwd {
  for i in ${@:2}
  do
    echo Forwarding port $i
    ssh -N -L $i:localhost:$i $1 &
  done  
}

Przykład użycia:

pfwd hostname {6000..6009}

2
Użyj -fdo biegania w tle
Karl Pokus

Ehmmm ... dlaczego chcesz to zrobić w ten sposób?
Anton Bessonov

14

Osoby, które przekazują wiele portów przez ten sam host, mogą ustawić coś takiego w swoim ~ / .ssh / config

Host all-port-forwards Hostname 10.122.0.3 User username LocalForward PORT_1 IP:PORT_1 LocalForward PORT_2 IP:PORT_2 LocalForward PORT_3 IP:PORT_3 LocalForward PORT_4 IP:PORT_4

i staje się to proste ssh all-port-forwards.


Podoba mi się to podejście.
BMW

8

jbchichoko i yuval podali realne rozwiązania. Ale odpowiedź jbchichoko nie jest elastyczną odpowiedzią jako funkcją, a otwarte tunele przez odpowiedź yuval nie mogą zostać zamknięte, ctrl+cponieważ działają w tle. Poniżej podaję moje rozwiązanie rozwiązujące obie wady:

Definiowanie funkcji w ~/.bashrclub~/.zshrc :

# fsshmap multiple ports
function fsshmap() {
  echo -n "-L 1$1:127.0.0.1:$1 " > $HOME/sh/sshports.txt
  for ((i=($1+1);i<$2;i++))
  do
    echo -n "-L 1$i:127.0.0.1:$i " >> $HOME/sh/sshports.txt
  done
  line=$(head -n 1 $HOME/sh/sshports.txt)
  cline="ssh "$3" "$line
  echo $cline
  eval $cline
}

Przykład uruchomienia funkcji:

fsshmap 6000 6010 hostname

Wynik tego przykładu:

Możesz uzyskać dostęp 127.0.0.1:16000~16009 tak samo jakhostname:6000~6009


3

Jedną z zalet logowania do serwera z przekierowaniem portów jest ułatwienie korzystania z Jupyter Notebook. Ten link zawiera doskonały opis, jak to zrobić. Chciałbym tutaj zrobić podsumowanie i rozwinięcie, abyście wszyscy mogli się odnieść.

Sytuacja 1. Zaloguj się z lokalnego komputera o nazwie Host-A (np. Własnego laptopa) do zdalnej maszyny roboczej o nazwie Host-B.

ssh user@Host-B -L port_A:localhost:port_B
jupyter notebook --NotebookApp.token='' --no-browser --port=port_B

Następnie możesz otworzyć przeglądarkę i wpisać: http: // localhost: port_A /, aby wykonać pracę na Host-B, ale zobaczyć to w Host-A.

Sytuacja 2. Zaloguj się z lokalnego komputera o nazwie Host-A (np. Własnego laptopa) do zdalnego komputera logowania o nazwie Host-B i stamtąd zaloguj się do zdalnego komputera roboczego o nazwie Host-C. Zwykle dzieje się tak w przypadku większości serwerów analitycznych na uczelniach i można to osiągnąć za pomocą dwóch ssh -Lpołączonych z -t.

ssh -L port_A:localhost:port_B user@Host-B -t ssh -L port_B:localhost:port_C user@Host-C
jupyter notebook --NotebookApp.token='' --no-browser --port=port_C

Następnie możesz otworzyć przeglądarkę i wpisać: http: // localhost: port_A /, aby wykonać pracę na Host-C, ale zobaczyć to w Host-A.

Sytuacja 3. Zaloguj się z lokalnego komputera o nazwie Host-A (np. Własnego laptopa) do zdalnego komputera logowania o nazwie Host-B i stamtąd zaloguj się na zdalnej maszynie o nazwie Host-C i na koniec zaloguj się do zdalnego komputera roboczego Host- RE. Zwykle tak nie jest, ale może się kiedyś zdarzyć. Jest to rozszerzenie sytuacji 2 i tę samą logikę można zastosować na większej liczbie maszyn.

ssh -L port_A:localhost:port_B user@Host-B -t ssh -L port_B:localhost:port_C user@Host-C -t ssh -L port_C:localhost:port_D user@Host-D
jupyter notebook --NotebookApp.token='' --no-browser --port=port_D

Następnie możesz otworzyć przeglądarkę i wpisać: http: // localhost: port_A / aby wykonać pracę na Host-D, ale zobaczyć to w Host-A.

Zauważ, że port_A, port_B, port_C, port_D mogą być liczbami losowymi, z wyjątkiem wspólnych numerów portów wymienionych tutaj . W sytuacji 1 port_A i port_B mogą być takie same, aby uprościć procedurę.


Przypomnienie, ten sam port na różnych serwerach to różne porty. Dlatego zawsze może to ułatwić, podając identyczny numer portu!
Fei Yao

3

W mojej firmie zarówno ja, jak i członkowie mojego zespołu potrzebujemy dostępu do 3 portów nieosiągalnego serwera „docelowego”, więc utworzyłem stały tunel (czyli tunel, który może działać w tle w nieskończoność, patrz parametry -fi -N) z serwera osiągalnego do cel. W wierszu poleceń osiągalnego serwera wykonałem:

ssh root@reachableIP -f -N  -L *:8822:targetIP:22  -L *:9006:targetIP:9006  -L *:9100:targetIP:9100

Użyłem użytkownika, rootale Twój własny będzie działał. Będziesz musiał wprowadzić hasło wybranego użytkownika (nawet jeśli jesteś już połączony z osiągalnym serwerem z tym użytkownikiem).

Teraz port 8822 dostępnej maszyny odpowiada portowi 22 docelowego (dla ssh / PuTTY / WinSCP), a porty 9006 i 9100 na osiągalnej maszynie odpowiadają tym samym portom docelowym (obsługują dwie usługi sieciowe w moim przypadku ).


1

Opracowałem loco do pomocy przy przekazywaniu ssh. Może być używany do lokalnego udostępniania portów 5000 i 7000 na tych samych portach:

pip install loco

loco listen SSHINFO -r 5000 -r 7000

1

Jeśli potrzebujesz prostego rozwiązania działającego w tle i łatwego do zabicia - użyj gniazda sterującego

# start
$ ssh -f -N -M -S $SOCKET -L localhost:9200:localhost:9200 $HOST
# stop
$ ssh -S $SOCKET -O exit $HOST

1

Oto rozwiązanie zainspirowane rozwiązaniem Yuvala Atzmona.

Ma kilka zalet w stosunku do początkowego rozwiązania:

  • najpierw tworzy pojedynczy proces w tle, a nie jeden na port
  • generuje alias, który pozwala ci zabić twoje tunele
  • wiąże się tylko z 127.0.0.1, co jest trochę bezpieczniejsze

Możesz go używać jako:

  • tnl your.remote.com 1234
  • tnl your.remote.com {1234,1235}
  • tnl your.remote.com {1234..1236}

I wreszcie zabij ich wszystkich tnlkill.

function tnl {
  TUNNEL="ssh -N "
  echo Port forwarding for ports:
  for i in ${@:2}
  do
    echo " - $i"
    TUNNEL="$TUNNEL -L 127.0.0.1:$i:localhost:$i"
  done
  TUNNEL="$TUNNEL $1"
  $TUNNEL &
  PID=$!
  alias tnlkill="kill $PID && unalias tnlkill"
}

-1

Możesz użyć tej funkcji zsh (prawdopodobnie działa też z bashem) (wstaw ją ~/.zshrc):

ashL () {
    local a=() i
    for i in "$@[2,-1]"
    do
        a+=(-L "${i}:localhost:${i}")
    done
    autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -NT "$1" "$a[@]"
}

Przykłady:

ashL db@114.39.161.24 6480 7690 7477

ashL db@114.39.161.24 {6000..6050} # Forwards the whole range. This is simply shell syntax sugar.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.