pliki scp za pośrednictwem hosta pośredniego

84

Mam dostęp do 3 komputerów, A, B i C. Jedyne możliwe połączenia (ssh) to:

A -> B
B <-> C

Muszę pobrać pliki od A do C, aby móc przeskanować pliki od A do B, a następnie przesłać je z B do C. Jednak B nie ma dużo miejsca na dysku, więc nie jest to opcja. Czy istnieje sposób na scp plików z A do C przez B? Uwaga, nie mam dostępu do roota na żadnej maszynie, więc nie sądzę, żebym mógł skonfigurować trwałe tunele, ale poprawcie mnie, jeśli się mylę!

astrofrog
źródło
6
Wiem, że to nie odpowiada na pytanie, ale dla tych, którzy nie wiedzą o rsync lub nie wiedzą, jak go używać do przeskakiwania przez hosta, może to być przydatna wskazówka: użyj opcji „-e” z rsync w ten sposób:A$ rsync <options> -e 'ssh B ssh' source C:destination
Ededified

Odpowiedzi:

107

ProxyJump

Nowości w OpenSSH 7.3:

A$ scp -oProxyJump=B thefile C:destination

(Za kulisami używa tylko ProxyCommand i ssh -W.)

ProxyCommand

Zaktualizowano, aby uwzględnić -W z innych odpowiedzi:

A$ scp -oProxyCommand="ssh -W %h:%p B" thefile C:destination

Jeśli A ma zainstalowanego bardzo starego klienta SSH (bez -Wobsługi) lub jeśli B jest skonfigurowany tak, aby uniemożliwiać przekazywanie TCP (ale nadal pozwala na polecenia powłoki), użyj alternatyw:

A$ scp -oProxyCommand="ssh B socat stdio tcp:%h:%p" thefile C:destination
A$ scp -oProxyCommand="ssh B nc %h %p" thefile C:destination

Rury

A$ tar cf - thefile anotherfile | ssh B "ssh C \"cd destination && tar xvf -\""
A$ (echo thefile; echo anotherfile) | cpio -o | ssh B "ssh C \"cd destination && cpio -i\""

Tylko dla jednego pliku:

A$ ssh B "ssh C \"cd destination && cat > thefile\"" < thefile

„Tunel” przez B

A$ ssh -f -N -L 4567:C:22 B
(continues running in background)

A$ scp -P 4567 thefile localhost:destinationPath

Kiedy skończysz, nie zapomnij zabić wcześniej rozpoczętego sshprocesu (który spadł do tła z powodu -f -N).

  • -fProsi ssh o przejście do tła tuż przed wykonaniem polecenia. Jest to przydatne, jeśli ssh ma prosić o hasła lub hasła, ale użytkownik chce je w tle. Oznacza to -n.
  • -NNie wykonuj polecenia zdalnego. Jest to przydatne tylko w przypadku portów przekierowujących.

Odwróć „tunel” przez B do A

Nie zawsze jednak działa:

A$ ssh -f -N -R 4567:localhost:22 B
(now you can reach A from B, by using localhost:4567)

B$ scp -P 4567 localhost:thefile C:destination
  • -R Określa, że ​​połączenia z danym portem TCP lub gniazdem Unix na zdalnym hoście (serwerze) mają być przekazywane do danego hosta i portu lub gniazda Unix po stronie lokalnej.
grawitacja
źródło
Dzięki bardzo za te przykłady @grawity. Jedno pytanie - czy można odwrócić plik tar na inny plik | ssh B "ssh C \" cd destination && tar xv \ "" ´ w celu skopiowania pobierania z C do A (będąc na A)
dmeu
@dmeu: Tak, to możliwe.
grawity
Jak „zabić” wcześniej rozpoczęty proces ssh, jeśli powiesz, że używam MacOS?
Aero Windwalker
Uwaga: jak zwykle, jeśli chcesz przejść scp z C, choć B, do A, możesz to zrobić A$ scp -oProxyJump=B C:destination thefile.
jvriesem
@Pablo Lepiej użyj -S, a następnie -O wyjdź. Lub ... przynajmniej pkill -f.
grawitacja
24

Wersje scp z początku 2011 roku i później mogą mieć opcję „-3”:

 -3      Copies between two remote hosts are transferred through the local
         host.  Without this option the data is copied directly between
         the two remote hosts.  Note that this option disables the
         progress meter.

Jeśli tak, możesz po prostu uruchomić:

B$ scp -3 A:file C:file
Dan Bloch
źródło
W moim przypadku host A był dostępny tylko z B (który był VPNed). Host C był w tej samej sieci LAN co B. Chciałem pobrać plik z A do C i scp -3 rozwiązał go doskonale.
Joe,
Miałem z tym problem, gdy oba hosty poprosiły o hasło. Wydaje się, że prosi o oba naraz (dwa monity o hasło pojawiły się w tym samym wierszu), a następnie nie akceptuje mojego hasła. W końcu mogłem go uruchomić, wpisując moje hasło wielokrotnie (to samo hasło na obu hostach), ale trudno było je rozgryźć.
Colin D,
8

Prawie wszystkie zostały już powiedziane, ale oto mój ostatni grosz: używam wariantu ProxyCommand bez ncani soc. W oparciu o OpenSSH Proxies i Jumphost Cookbook stworzyłem następującą konfigurację:

  1. Mamy więc następujących graczy:

    • HOME_HOST: skąd kopiujemy plik do hosta docelowego
    • HOP_HOST: kopiujemy przez ten host (zalogowany jako HOP_USER)
    • TARGET_HOST: jest to nasz cel (uwierzytelniony jako TARGET_USER)
  2. Najpierw dodałem mój lokalny klucz publiczny od mojego hosta macierzystego .ssh/id_dsa.pub do hostów .ssh/authorized_keyszarówno hopowych, jak i docelowych. Tak, ten sam klucz publiczny od gospodarza do obu z nich. Zwykle można oczekiwać, że jest to klucz publiczny HOP, który należy dodać do klucza TARGET.

  3. Potem .ssh/configtrochę poprawiłem , dodając następujący wpis:

    Host TARGET_HOST
       User TARGET_USER
       ProxyCommand ssh -W %h:%p HOP_USER@HOP_HOST
    
  4. Po tej operacji kopiowania jest tak proste, jak: scp FILE TARGET_HOST:. Wyświetla podwójne banery zarówno z węzłów przeskoku, jak i docelowego, ale działa.

Oczywiście można użyć wyżej ssh bezpośrednio do celu: ssh TARGET_HOST. Działa z scp i ssh.

Inną bardziej ogólną opcją może być narzędzie sshuttle , które wydaje się być rodzajem przezroczystego serwera proxy (VPN przez ssh). Zatem w twoim przypadku A-> B <-> C pozwala połączyć się z każdym węzłem w sieci C: A-> B- [CDEFG]. Nie potrzebuje administratora, ale wymaga Python 2.7 (3.5 również OK), co nie zawsze jest tym, co mamy. Warto tego spróbować.

SQ9MCP
źródło
7
ssh -L 4321:hostC:22 youruser@hostB

w innej powłoce:

scp -P 4321 localfile [email protected]

To używa przekierowania portów. Jedynym ograniczeniem w tym przypadku jest konieczność skonfigurowania hosta B, aby umożliwić przekierowanie portów. W przeciwnym razie powinno to działać poprawnie.

W sposób objaśniający -Li -Rumożliwiają przekierowanie portów. W -L, pierwszym podanym portem jest port, który ssh rozpocznie nasłuchiwanie na maszynie inicjującej (host A), i przekaże wszystko, co otrzyma na tym porcie, za pośrednictwem połączenia SSH do hosta B, a następnie przekieruje do hosta C na porcie 22.

edytować

Lekko zepsułem składnię. Ustawia forward na twojej maszynie LOCAL.

Brian Vandenberg
źródło
@astrofrog - jeśli jedna z naszych odpowiedzi spełnia twoje potrzeby, prawdopodobnie powinieneś zaakceptować jedną z nich.
Brian Vandenberg
2

Odpowiedź ProxyCommand firmy Grawity zadziałała dla mnie, ale ponieważ jestem mniej zaznajomiony z SSH, wymagało to pewnych eksperymentów. Myślałem, że po prostu przeliteruję odpowiedź Grawity bardziej szczegółowo, aby pomóc innym początkującym w SSH, takim jak ja. Oto definicje bardziej wyraźnego zapisu:

Maszyna A: maszyna, na której jesteś

Serwer B: [email protected] (host skoku lub serwer pośredni)

Serwer C: [email protected] (serwer zdalny, na który chcesz skopiować)

ProxyCommnad

    A$ scp -oProxyCommand="ssh -W %h:%p [email protected]" thefile [email protected]:destination

Konkretny przykład

Przykładowo powiedzmy, że masz dostęp do serwera z adresem IP 0.0.1.2z kontem użytkownika o nazwie bar(Serwer C). Ale aby się do niego dostać, musisz najpierw zalogować się do serwera z adresem IP 0.0.1.1przy użyciu konta użytkownika o nazwie foo(Serwer B). Teraz chcesz skopiować plik baz.txtznajdujący się na danym komputerze (maszynie) do serwera 0.0.1.2„s /home/bar/katalogu. Aby użyć powyższego ProxyCommand w tym przykładzie, wykonaj następujące czynności:

    A$ scp -oProxyCommand="ssh -W %h:%p [email protected]" baz.txt [email protected]:/home/bar/

Możesz także równie łatwo skopiować plik z serwera C, zmieniając kolejność pliku i miejsca docelowego. Na przykład, jeśli baz.txtbył już na serwerze 0.0.1.2zlokalizowanym na, /home/bar/możesz skopiować go na swój komputer, używając:

    A$ scp -oProxyCommand="ssh -W %h:%p [email protected]" [email protected]:/home/bar/baz.txt /destination/path/on/A

Mam nadzieję, że to pomaga ludziom, którzy potrzebują czegoś, co zostało im wyjaśnione bardziej niż inni.

Joseph Carmack
źródło