Jak scp z drugim zdalnym hostem

83

Zastanawiam się, czy istnieje sposób na SCP pliku z hosta remote2 bezpośrednio z mojej maszyny lokalnej, przechodząc przez hosta remote1.

Sieci zezwalają na połączenia z hostem zdalnym2 tylko z hosta zdalnego1. Ponadto ani host zdalny1 ani host zdalny2 nie mogą scpować na moją maszynę lokalną.

Czy jest coś takiego:

scp user1@remote1:user2@remote2:file .

Pierwsze okno: ssh remote1więc scp remot2:file ..

Druga powłoka: scp remote1:file .

Pierwsze okno: rm file; logout

Mógłbym napisać skrypt wykonujący wszystkie te kroki, ale jeśli istnieje bezpośredni sposób, wolałbym go użyć.

Dzięki.

EDYCJA: Myślę o otwieraniu tuneli SSH, ale nie wiem, jaką wartość umieścić gdzie.

W tej chwili, aby uzyskać dostęp remote1, mam następujące informacje $HOME/.ssh/configna moim komputerze lokalnym.

Host remote1
   User     user1
   Hostname localhost
   Port     45678

Po włączeniu remote1, aby uzyskać dostęp remote2, jest to standardowy lokalny DNS i port 22. Co powinienem założyć remote1i / lub zmienić localhost?

Danosaure
źródło

Odpowiedzi:

95

Nie znam żadnego sposobu na skopiowanie pliku bezpośrednio jednym poleceniem, ale jeśli możesz zgodzić się na uruchomienie instancji SSH w tle, aby po prostu pozostawić otwarty tunel przekierowania portów, możesz skopiować plik jednym poleceniem.

Lubię to:

# First, open the tunnel
ssh -L 1234:remote2:22 -p 45678 user1@remote1
# Then, use the tunnel to copy the file directly from remote2
scp -P 1234 user2@localhost:file .

Zauważ, że łączysz się tak, jak user2@localhostw rzeczywistym scppoleceniu, ponieważ jest to port 1234 na hoście lokalnym, na którym pierwsza sshinstancja nasłuchuje połączeń przekazywanych remote2. Zauważ również, że nie musisz uruchamiać pierwszego polecenia dla każdej kolejnej kopii pliku; możesz po prostu zostawić go uruchomionego.

Dolda2000
źródło
1
Dzięki, wydaje mi się, że jest blisko tego, czego potrzebuję. Utworzyłem więc tunel, odcisk palca pasuje do tego z serwera, ale pojawia się błąd „Odmowa uprawnień (publickey)”. Myślę, że muszę zapytać mojego administratora sieci / systemu, dlaczego to nie działa.
Danosaure
3
Dzięki! Musiałem zmienić -p 45678się -p 22jak mój remote1 SSH nasłuchuje na porcie 22
Montaro
Musiałem też użyć -p 22zamiast -p 45678. U mnie też scp -P 1234 ...nie działa. Dostaję ssh: connect to host localhost port 1234: Connection refused. Kiedy próbowałem scp -P 22 ..., działa, ale kopiuje plik do, remote 1a nie na moją maszynę lokalną ( remote2).
sinner
Jakieś narzędzie interfejsu użytkownika do tego samego?
ExploringApple
70

Podwójnie ssh

Nawet w złożonym przypadku możesz obsłużyć transfer plików za pomocą jednej linii poleceń, po prostu za pomocą ssh;-)
I jest to przydatne, jeśli remote1nie możesz się połączyć localhost:

ssh user1@remote1 'ssh user2@remote2 "cat file"' > file

tar

Ale tracisz właściwości pliku (własność, uprawnienia ...).

Jednak tarjest Twoim przyjacielem, jeśli chcesz zachować te właściwości pliku:

ssh user1@remote1 'ssh user2@remote2 "cd path2; tar c file"' | tar x

Możesz także skompresować, aby zmniejszyć przepustowość sieci:

ssh user1@remote1 'ssh user2@remote2 "cd path2; tar cj file"' | tar xj

A tartakże umożliwia przesyłanie katalogu rekurencyjnego przez podstawowe ssh:

ssh user1@remote1 'ssh user2@remote2 "cd path2; tar cj ."' | tar xj

ionice

Jeśli plik jest duży i nie chcesz przeszkadzać innym ważnym aplikacjom sieciowym, możesz przeoczyć ograniczenie przepustowości sieci zapewniane przez narzędzia scpi rsync(np. scp -l 1024 user@remote:fileNie wykorzystuje więcej niż 1 Mb / s).

Ale obejście polega ionicena zachowaniu jednego wiersza poleceń:

ionice -c2 -n7 ssh u1@remote1 'ionice -c2 -n7 ssh u2@remote2 "cat file"' > file

Uwaga: ionicemoże nie być dostępne w starych dystrybucjach.

ooo
źródło
Dzięki za cały opis, ale myślę, że rozwiązanie Dolda2000 jest łatwiejsze. Próbowałem tego, ale nie mogłem tego rozgryźć.
Danosaure
5
To spektakularnie dobra odpowiedź i zasługuje na więcej głosów. Poza tym jest to o wiele łatwiejsze niż akceptowana odpowiedź, moim zdaniem.
Rik Smith-Unna
2
Zgadzam się, że to lepsze rozwiązanie niż przyjęta odpowiedź. W ten sposób połączenie jest automatycznie czyszczone.
Doug,
Dziękuję, bardzo miła odpowiedź! A co na odwrót, kopiowanie z lokalnego na zdalny?
DomTomCat
31

To wystarczy:

scp -o 'Host remote2' -o 'ProxyCommand ssh user@remote1 nc %h %p' \ 
    user@remote2:path/to/file .

Aby przeskoczyć plik remote2bezpośrednio z hosta , dodaj dwie opcje ( Hosti ProxyCommand) do swojego pliku ~ / .ssh / config (zobacz również odpowiedź na superużytkowniku). Następnie możesz biegać:

scp user@remote2:path/to/file .

z lokalnego komputera bez zastanawiania się remote1.

John Manak
źródło
Niezłe podejście! Chociaż -o 'Host remote2'nie wydaje się to być naprawdę wymagane podczas uruchamiania z wiersza poleceń (tj. Aby skopiować raz bez dotykania ~ / .ssh / config)
Mike
To samo tutaj. To działa dla mnie bez -o 'Host remote2'. Dzięki.
sinner
7

Dzięki openssh w wersji 7.3 i nowszych jest to łatwe. Użyj opcji ProxyJump w pliku konfiguracyjnym.

# Add to ~/.ssh/config 
Host bastion
    Hostname bastion.client.com
    User userForBastion
    IdentityFile ~/.ssh/bastion.pem

Host appMachine
    Hostname appMachine.internal.com
    User bastion
    ProxyJump bastion                   # openssh 7.3 version new feature ProxyJump
    IdentityFile ~/.ssh/appMachine.pem. #no need to copy pem file to bastion host  

Polecenia do uruchomienia w celu zalogowania lub skopiowania

ssh appMachine   # no need to specify any tunnel. 
scp helloWorld.txt appMachine:.   # copy without intermediate jumphost/bastion host copy.** 

oczywiście możesz określić host bastion Jump za pomocą opcji "-J" polecenia ssh, jeśli nie jest skonfigurowany w pliku konfiguracyjnym.

Uwaga SCP ma nie wydaje się wspierać flagę „-J” jak teraz. (Nie mogłem znaleźć na stronach podręcznika. Jednak powyżej scp działa z ustawieniem pliku konfiguracyjnego)

user3851404
źródło
1
Nie ma potrzeby dodawania serwera bastion do pliku konfiguracyjnego, jeśli jest on używany tylko do proxy (tj. Nie ma innego IdentityFile itp.), Po prostu dodaj ProxyJump bastion.client.com do sekcji appMachine.
Tomer Cohen,
1

Jest nowa opcja scpdodania ostatnio dla dokładnie tej samej pracy, która jest bardzo wygodna -3.

TL; DR W przypadku obecnego hosta, który ma już skonfigurowane uwierzytelnianie w plikach konfiguracyjnych ssh, po prostu wykonaj:

scp -3 remote1:file remote2:file

Twój scpmusi pochodzić z najnowszych wersji.

Wszystkie inne wymienione techniki wymagają skonfigurowania uwierzytelniania od remote1 do remote2 lub odwrotnie, co nie zawsze jest dobrym pomysłem.
Argument -3oznacza, że ​​chcesz przenieść pliki z dwóch zdalnych hostów, używając bieżącego hosta jako pośrednika, a ten host faktycznie przeprowadza uwierzytelnianie na obu zdalnych hostach, więc nie muszą mieć do siebie dostępu.
Musisz tylko skonfigurować uwierzytelnianie w plikach konfiguracyjnych ssh, co jest dość łatwe i dobrze udokumentowane, a następnie po prostu uruchom polecenie w TL; DR

Źródłem tej odpowiedzi jest https://superuser.com/a/686527/713762

FazeL
źródło
0

Ta konfiguracja działa dla mnie dobrze:

Host jump
   User username
   Hostname jumphost.yourorg.intranet
Host production
   User username
   Hostname production.yourorg.intranet
   ProxyCommand ssh -q -W %h:%p jump

Potem polecenie

scp myfile production:~

Kopiuje plik myfile na maszynę produkcyjną .

anydoby
źródło
0

Mały dodatek do rozwiązania Olibre , z którym pracowałem używając tego źródła.

Tak jak masz trzy sposoby użycia tardo kopiowania ze zdalnego hosta do lokalnego, poniższe działa w przypadku kopiowania z lokalnego hosta do zdalnego hosta w podwójnych sytuacjach ssh: (uruchom je w katalogu, z którego pliki mają być skopiowane, w przeciwnym razie użyj pełnej ścieżki /Nazwa pliku)

Prześlij pojedynczy plik bez kompresji:

tar c filename |  ssh user1@remote1 'ssh -Y user2@remote2 "path2 && tar x"'

Prześlij pojedynczy plik z kompresją:

tar cj filename |  ssh user1@remote1 'ssh -Y user2@remote2 "path2 && tar xj"'

Rekurencyjny transfer katalogu:

tar cj . |  ssh user1@remote1 'ssh -Y user2@remote2 "path2 && tar xj"'

&& w tym miejscu zapobiega uruchomieniu polecenia, jeśli pierwsza połowa polecenia nie działa - na przykład jeśli brakuje katalogu lub występuje błąd w nazwach ścieżek źródłowych / docelowych.

Aparna
źródło