Jak wykonać przelewy Multihop SCP?

85

Chcę skopiować plik z mojego komputera A na serwer C, ale mam dostęp tylko do serwera C przez serwer B.

Zamiast najpierw przenieść na serwer B, zaloguj się, a następnie przenieś na serwer C. Czy można przenieść plik bezpośrednio za pomocą SCP lub podobnych programów?

(Tryb Tramp Emacsa ma tę funkcję do zdalnej edycji plików).

sverrejoh
źródło

Odpowiedzi:

48

Możesz dodać -oopcje scpzamiast .ssh/config.

scp -o ProxyCommand="ssh $jump_host nc $host 22" $local_path $host:$destination_path

$jump_host jest w tym przypadku „serwerem B”.

John Tantalo
źródło
To mój ulubiony sposób, aby to zrobić. Zaniepokojenie .ssh / config dla multihoppingu nie jest najlepszym rozwiązaniem, jeśli uzyskujesz dostęp do tego samego hosta z bramy lub bezpośrednio.
GabrieleV,
Jak by to było w przypadku różnych / niestandardowych nazw użytkowników i portów?
Pablo A
Próbuję tego i muszę wprowadzić hasło. Jak mogę to naprawić? Dzięki.
HQT
44

Zakładając OpenSSH, dodaj do konfiguracji SSH w .ssh / config

Host distant
ProxyCommand ssh near nc distant 22

Spowoduje to, że SSH będzie w stanie połączyć się „bezpośrednio” z maszyną o nazwie odległej poprzez proxy przez maszynę o nazwie near. Następnie może używać aplikacji takich jak scp i sftp na odległym komputerze.

Aby to zadziałało, potrzebujesz 'nc' aka netcat zainstalowanego na komputerze o nazwie near. Ale wiele nowoczesnych systemów już to ma.

Rozwiązanie tar tar jest bardziej skuteczne w przypadku problemów jednorazowych, zakładając, że zapamiętałeś składnię tar i zasady działania.

tialaramex
źródło
Jest to ta sama metoda, której używam ... W tym przykładzie „odległy” to serwer C, a „w pobliżu” to serwer B dla wyjaśnienia ...
Jeremy Bouse
Wiele nowoczesnych maszyn nie ma „nc”: zwykle jest dostępny tylko dla komputerów z systemem Linux i tylko na żądanie (nie jest częścią standardowej instalacji).
Mei
1
ssh ma teraz opcję -W, która robi to automatycznie bez „nc”, ale zastanawiam się, dlaczego nie ma scp -W
kubańczyk
3
W przypadku, gdy nie jestem jedyny, nie było to oczywiste: jeśli nazwa użytkownika włączona nearjest inna niż nazwa użytkownika włączona distant, użytkownik bliski wchodzi ProxyCommand ssh nearuser@near..., a użytkownik zdalny przechodzi do osobnej User distantuserlinii.
Mu Mind
Po prostu wpisz ssh multi hope i naciśnij Google Czuję się szczęśliwy
chandank
19

W przypadku nowszych wersji ssh na serwerze w pobliżu maszyny (B) następujące działania będą działać bez netcata:

Host distant
    ProxyCommand ssh near -W distant:22

Będzie jednak wymagać, aby AllowTcpForwarding miał wartość yes (domyślnie) na maszynie near (B)

edycja: wymaga OpenSSH 5.4+ na B

danblack
źródło
działa jak urok :)
gongzhitaao,
1
A przynajmniej od wersji OpenSSH 7.4p1 istnieje polecenie „ProxyJump”, w którym wystarczy tylko wymienić każdego użytkownika @ host: port oddzielony przecinkami. Miły!
hmijail
ProxyJump jest fajny, ale nie wziął pliku User i IdentityFile z pliku konfiguracyjnego. ProxyCommand -W robi to i działa również z scp.
rickfoosusa
18

Możesz ssh na serwer B używając czegoś takiego

ssh -L 5022:<server C IP>:22 <user_serverB>@<server B IP>

Następnie możesz ssh na serwerze C.

ssh -p 5022 <user_serverC>@localhost 

Podobnie działałoby scp przy użyciu

scp -P 5022 foo.txt <user_serverc>@localhost:

Pamiętaj, aby używać poprawnego przypadku p dla scp i ssh

Saurabh Barjatiya
źródło
5

Jest to możliwe i względnie łatwe, nawet gdy trzeba używać certyfikatów do uwierzytelniania (typowe w środowiskach AWS).

Komenda poniżej skopiuje pliki z remotePathdnia server2bezpośrednio na maszynie localPath. Wewnętrznie żądanie scp jest przekazywane przez serwer proxy server1.

scp -i user2-cert.pem -o ProxyCommand="ssh -i user1-cert.pem -W %h:%p user1@server1" user2@server2:/<remotePath> <localpath>

Odwrotnie działa również (przesyłanie pliku):

scp -i user2-cert.pem -o ProxyCommand="ssh -i user1-cert.pem -W %h:%p user1@server1" <localpath> user2@server2:/<remotePath>

Jeśli zamiast tego używasz uwierzytelniania za pomocą hasła, spróbuj

scp -o ProxyCommand="ssh -W %h:%p user1@server1" user2@server2:/<remotePath> <localpath>

Jeśli używasz tych samych poświadczeń użytkownika na obu serwerach:

scp -o ProxyCommand="ssh -W %h:%p commonuser@server1" commonuser@server2:/<remotePath> <localpath>
donhector
źródło
3

Jeśli chcesz być naprawdę niegodziwy, możesz połączyć łańcuchy ssh i tar, coś w tym rodzaju tar c mydir | ssh server "ssh otherserver | tar x", ale może to napotkać wszystkie problemy.

Najłatwiejszym sposobem byłoby po prostu ustawienie tunelu SSH z wbudowanymi metodami SSH; spójrz na -Dprzełącznik na stronie man i po prostu przekieruj jakiś port do portu ssh drugiego serwera.

towo
źródło
2

Możesz to również zrobić w odwrotnej kolejności i może to być łatwiejsze.

Załóżmy, że masz otwartą sesję ssh na maszynie, do której chcesz wysłać plik. Ten komputer z najdalszym przeskokiem nazwiemy hop2. Twoim hostem „proxy” będzie hop1. Komputer będący źródłem pliku, nazwiemy to źródłem.

origin:~/asdf.txt  --> hop1 --> hop2:~/asdf.txt

Możesz budować tunele udostępniające port lokalny na zdalnym komputerze. W ten sposób definiujemy port do otwarcia na zdalnym komputerze, który będzie przekierowaniem do portu, który ściągnąłeś ze sobą podczas budowy tunelu.

Na hop2:

ssh -R 5555:127.0.0.1:22 <hop1_user>@<hop1_IP>
#this has the effect of building a tunnel from hop2 to hop1, making hop2's port 22 available on hop1 as port 5555

Teraz w tej otwartej sesji tunelowej możesz zrobić to samo od hop1 do file_origin.

Na skoku 1:

ssh -R 6666:127.0.0.1:5555 <origin_user>@<origin_IP>
#this has the effect of building a tunnel from hop1 to origin while also pulling the active tunnel with it, making hop1's port 5555 (hop2's port 22) available on origin as port 6666.

Jesteś teraz tunelowany od hop2 do hop1 do źródła. Nawiasem mówiąc, teraz zarówno port 5555, jak i 6666 są otwarte w momencie nadejścia, które są przekierowaniami do portu 22 hop2. W ramach tej sesji oba poniższe są poprawnymi trasami SCP do hop2:

W miejscu pochodzenia:

scp -P 6666 ~/asdf.txt <hop2_user>@<127.0.0.1>:~/asdf.txt

W ten sposób możesz mieć dowolną liczbę przeskoków pomiędzy nimi, a łatwiej jest pracować pod względem łączenia razem więcej niż dwóch przeskoków.

SYANiDE
źródło
1

Spróbuj dostosować następujący przykład openssh config do konfiguracji, której można użyć na wielu hostach:

Host uat-*
     ProxyCommand ssh bastion-uat nc %h %p

Zakłada to zestaw serwerów zaczynających się od „uat-”, które są dostępne tylko za pośrednictwem serwera „bastion-uat” serwera Jumpbox / Gateway. Prawdopodobnie chcesz również dodać, ForwardAgent yesjeśli używasz klucza do logowania.

Benjamin Goodacre
źródło
Nie używaj ForwardAgent yesdo tego. Przekazywanie agentów nie jest w tym przypadku konieczne, ponieważ żaden klient ssh nie będzie działał na bastionie, a przekazywanie agenta, gdy nie będzie potrzebne, tylko zmniejszy bezpieczeństwo. I myślę, że sshbrakuje w twoim rozkazie. Jeśli sshużywana jest najnowsza wersja, której nie potrzebujesz nc, możesz ssh -W %h:%p bastion-uatzamiast tego wpisać .
kasperd
@kasperd Edytowano, aby uwzględnić ssh. Re ForwardAgent; uruchomi się klient ssh w celu uruchomienia samej komendy nc. Być może chodzi ci o powłokę?
Benjamin Goodacre
1

To nie jest scp (o które poprosił OP), ale uznałem, że bardzo proste rsyncjest kopiowanie z lokalnego na zdalny za pomocą jednego przeskoku za pomocą:

rsync -v -e 'ssh -A -t user@jumpserver ssh -A -t user@destinationserver' /path/to/sourcefile :/path/to/destination

Źródło: http://mjbright.blogspot.com/2012/09/using-rsync-over-multi-hop-ssh.html

Wypróbowałem powyższą sugestię -o ProxyPass i nie chciałem zmieniać konfiguracji dla moich zmieniających się potrzeb. Jak stwierdza autor w powyższym linku, plik docelowy poprzedzający dwukropek (:) jest ważny, aby wskazać określoną ścieżkę na serwerze docelowym. Ponadto, używając rsync, masz opcje porównywania dat, synchronizacji folderów itp. Mam nadzieję, że to komuś pomoże!

texas-bronius
źródło
-2

scp -o 'ProxyJump jumpboxname' somefilename.txt finaldestinationhost: / tmp /.

Ja i
źródło
3
Nie zrzucaj tutaj trochę niewyjaśnionego kodu. Istnieje wiele dobrych odpowiedzi na to pytanie i musisz wnieść wartość dodaną do już istniejących - tak nie jest.
Sven