Przekaż ruch SSH przez środkową maszynę


110

Tunelowanie SSH jest dla mnie bardzo mylące. Zastanawiam się, czy mogę to zrobić w systemie Linux.

Mam 3 maszyny ..

A. My local machine at home.
B. Machine at work that I can SSH into (middle man).
C. My desktop at work that I can only SSH into from machine B.

Więc mogę SSH od A -> B i od B -> C, ale nie od A -> C.

Czy istnieje sposób skonfigurowania tunelu SSH od A do B, więc kiedy uruchamiam inne polecenia SSH, działają one tylko z mojej lokalnej maszyny A? Zasadniczo próbuję sklonować repozytorium git z pracy do domu (i nie mogę zainstalować git na komputerze B).

Ponadto, po instalacji .. Jak mogę to również rozbroić?


Wydaje mi się, że gdzieś jest jakieś duplikat, ale moja wyszukiwarka jest dziś słaba.
quack quixote



Jeśli używasz Linuksa na komputerze A, użyj narzędzia o nazwie sshuttle, które pozwala selektywnie przekazywać cały ruch dla C przez tunel A-> B (zakładając, że C jest widoczne z B).
dołącz

Odpowiedzi:


128

Umieść to w swoim .ssh/configpliku na hościeA (szczegóły w man 5 ssh_config ):

# .ssh/config on hostA:
Host hostC
    ProxyCommand ssh hostB -W %h:%p

Teraz następujące polecenie będzie automatycznie tunelowane przez hostB

hostA:~$ ssh hostC

Możesz chcieć dodać opcje takie jak -oCiphers=arcfouri -oClearAllForwardings=yesprzyspieszyć, ponieważ owijanie sshwewnątrz sshjest obliczeniowo droższe, a dodatkowy wysiłek i opakowanie nie musi być tak bezpieczne, gdy tuneluje już zaszyfrowany ruch.


Jeśli używasz OpenSSH wcześniejszej niż 5.3, -Wopcja nie jest dostępna. W takim przypadku możesz zaimplementować powyższe za pomocą netcat ( nc):

ProxyCommand ssh hostB nc %h %p  # or netcat or whatever you have on hostB

1
To jest genialne! Dziękuję Ci. To rozwiązuje problem, który zjadł mnie przez ostatnie 2 dni: hostC znajduje się za firewallem i ma dane, do których chcę uzyskać dostęp z hostA, laptopa, który może być w dowolnym miejscu na świecie. hostB znajduje się również za tą samą zaporą ogniową co hostC, ale ma otwarty port SSH dla świata. Dlatego mogę ssh z hostC -> hostB. Konfiguruję tunel zwrotny SSH między hostC i hostB, więc mogę także ssh z hostB -> hostC (przekazywany przez localhost). Z twoją sztuczką mogę przejść z hostA -> hostC! Działa płynnie z SCP i Fugu na OSX! Dziękuję Ci!
AndyL,

-WOpcja powinna być używana zamiast ncopcji.
vy32

Który SSH powinien obsługiwać -W, tylko ten na hoście A (źródłowy), czy też na hoście B (środkowy komputer)?
gioele

Aby uzyskać informacje, jeśli masz wiele hostów, do których musisz dotrzeć za pośrednictwem tego samego hostB, możesz zadeklarować wiele Host hostClinii powyżej, ProxyCommanddzięki czemu bardzo łatwo uzyskasz dostęp do kilku hostów za pośrednictwem środkowego serwera.
fduff

7

Edycja: To niewłaściwe podejście. Zamiast tego zobacz odpowiedź ephemienta . Ta odpowiedź będzie działać, ale jest potencjalnie mniej bezpieczna i zdecydowanie mniej niesamowita.

Wygląda na to, że potrzebujesz takiego rozwiązania:

ssh -L localhost:22:machinec:22 machineb

To zapewni ci powłokę machineb. Zostaw to w spokoju; zminimalizuj okno terminala.

Teraz, za każdym razem, gdy nawiążesz połączenie ssh localhost, zostaniesz połączony machinecprzez machineb. Kiedy skończysz z tunelem, po prostu zamknij terminal, w którym uruchomiłeś powyższe polecenie.

Pamiętaj, że do uruchomienia polecenia potrzebne są uprawnienia administratora.


+1 Dzięki, Wesley. To jest prawdziwa odpowiedź tunelowania ssh. Oto artykuł na ten temat: securityfocus.com/infocus/1816
Larry K

3
Ogólnie rzecz biorąc, jest to dość złe ... ale musiałem to zrobić ze starożytnymi wersjami OpenSSH lub innymi klientami ssh. Możesz wybrać wysoki port, taki jak 8022: w ten sposób nie zakłóca to żadnej usługi ssh na localhost i nie wymaga uruchamiania jako root. Po prostu dodaj -p 8022do swoich poleceń ssh. Z git jest to łatwe: użyj identyfikatora URI ssh://localhost:8022/path/to/repo.git.
ephemient

3

Wygląda na to, że potrzebujesz aliasu powłoki na A, który powoduje, że ssh występuje na C

  1. Zakładam, że na A możesz wpisać ssh me @ b „ssh me @ c nazwa hosta” i odzyskać „C”
  2. Utwórz alias sshc, który rozwija sshc foo w ssh me @ b "ssh me @ c foo"
  3. Dokładną składnię tworzenia aliasu znajdziesz na stronie superuser.com

1
Może być konieczne dodanie -topcji zewnętrznego ssh, jeśli chcesz interaktywną powłokę, ponieważ sshzakłada -Tona, że ​​otrzyma polecenie.
ephemient

1

Do interaktywnej powłoki możesz użyć tego prostego polecenia:

ssh -J <user>@<hostB> <user>@<hostC>

Opcje -J służą do skoku .


0

Jeśli Twój pracodawca zapewnia VPN, zalecam korzystanie z niego zamiast tego.

W ten sposób nie będziesz musiał specjalnie konfigurować żadnych aplikacji (nawet ssh) i zobaczysz dowolną maszynę za zaporą. Ponadto cały Twój ruch będzie szyfrowany przez oprogramowanie VPN, które zwiększy bezpieczeństwo każdego przypadkowo lub celowo niezaszyfrowanego ruchu.


6
Czasami to VPN jest powodem, dla którego potrzebujemy tych sztuczek ...
Louis

0

YASS Jeszcze jedno proste rozwiązanie

ssh -f -L 2222:HostC_IP_or_Name:22 userOnB@hostB sleep 10 &&
    ssh -o HostKeyAlias=HostC -p 2222 userOnC@localhost
  • Pierwsze polecenie otwórz połączenie ssh z HostB i powiedz Hostowi, aby przekazywał połączenia z localhost: 2222 do HostC: 22 .
  • -fparametr powiedzieć SSH, aby przejść do tła po nawiązaniu połączenia
  • Drugie polecenie otwiera po prostu połączenie klienta z hostem lokalnym: 2222
  • Opcja HostKeyAlias nie jest wymagana, ale może pomóc w zapobieganiu połączeniu z niewłaściwym hostem
  • Uwaga: polecenie sleep 10jest potrzebne do utrzymania połączenia, dopóki drugie polecenie ssh nie użyje przekierowanego portu. Następnie pierwszy ssh zostanie zamknięty, gdy drugi ssh opuści przekierowany port.

możesz teraz uruchamiać kolejne sesje ssh:

ssh -o HostKeyAlias=HostC -p 2222 userOnC@localhost

Wariant:

ssh -f -L 2222:HostC_IP_or_Name:22 userOnB@hostB sleep 10 &&
    ssh -M -S ~/.ssh/ssh_HostC22userOnC.sock -o HostKeyAlias=HostC -p 2222 userOnC@localhost

kolejne sesje ssh można otworzyć, uruchamiając:

ssh -S ~/.ssh/ssh_HostC22userOnC.sock userOnC@localhost

Główną zaletą użycia parametrów -M i -S jest to, że tylko jedno połączenie jest otwarte z HostA do HostC, kolejna sesja nie zostanie ponownie uwierzytelniona i uruchomiona znacznie szybciej.


0

Przypadek specjalny, mieszane platformy Nix:

  hostA (linux) -> HostB (solaris) -> HostC (linux)

Jeśli potrzebujesz aplikacji X na hoście HostC, a przeskok pośredni jest na polu Solaris ... w tym przypadku znalazłem netcat (nc) potrzebny na ProxyCommand w następujący sposób:

hostA: ~ $ vi .ssh / config:

Host host C
    ProxyCommand ssh hostB nc% h% p # gdzie nc to netcat

Następnie działa automatyczne tunelowanie:

hostA: ~ $ ssh hostC

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.