Bagaimana cara saya melakukan transfer Multihop SCP?

85

Saya ingin menyalin file dari mesin saya ke server C, tetapi hanya memiliki akses ke server C melalui server B.

Alih-alih pertama-tama mentransfer ke server B, masuk dan kemudian transfer ke server C, Apakah mungkin untuk mentransfer file secara langsung dengan SCP atau program serupa?

(Mode trac Emacs memiliki fitur ini untuk mengedit file dari jarak jauh).

sverrejoh
sumber

Jawaban:

48

Anda dapat menambahkan -oopsi scpbukan .ssh/config.

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

$jump_host adalah "server B" Anda dalam hal ini.

John Tantalo
sumber
Ini adalah cara yang saya sukai untuk melakukan ini. Mengganti .ssh / config untuk multihopping bukanlah solusi terbaik jika Anda mengakses host yang sama baik dari gateway maupun secara langsung.
GabrieleV
Bagaimana hal ini terjadi dengan nama pengguna dan port yang berbeda / ubahsuaian?
Pablo A
Saya mencoba ini dan harus memasukkan kata sandi. Bagaimana saya bisa memperbaikinya? Terima kasih.
hqt
44

Dengan asumsi OpenSSH, tambahkan ke konfigurasi SSH Anda di .ssh / config

Host distant
ProxyCommand ssh near nc distant 22

Ini akan menyebabkan SSH dapat menghubungkan "langsung" ke mesin bernama jauh dengan proxying melalui mesin bernama dekat. Kemudian dapat menggunakan aplikasi seperti scp dan sftp ke mesin yang jauh.

Agar ini berfungsi, Anda perlu 'nc' alias netcat diinstal pada mesin yang bernama near. Tetapi banyak sistem modern sudah memilikinya.

solusi tar towo lebih efektif untuk masalah satu-shot, dengan asumsi Anda telah menghafal sintaks tar dan aturan operasi.

tialaramex
sumber
Ini adalah metode yang sama yang saya gunakan ... Dalam contoh ini 'jauh' akan menjadi server C dan 'dekat' akan menjadi server B untuk klarifikasi ...
Jeremy Bouse
Banyak mesin modern tidak memiliki 'nc': biasanya tersedia hanya untuk mesin Linux dan hanya berdasarkan permintaan (bukan bagian dari instalasi standar).
Mei
1
ssh sekarang memiliki opsi -W, yang melakukan ini secara otomatis tanpa 'nc', tapi saya bertanya-tanya mengapa tidak ada scp -W
kubanczyk
3
Jika saya bukan satu-satunya yang tidak jelas: jika nama pengguna aktif nearberbeda dengan nama pengguna aktif distant, pengguna terdekat masuk ProxyCommand ssh nearuser@near..., dan pengguna jauh masuk ke User distantuserbaris terpisah .
Mu Mind
Cukup ketik ssh multi harapan dan tekan Google Saya merasa beruntung
chandank
19

Dengan versi ssh terbaru di server dekat (B) mesin, yang berikut ini akan berfungsi tanpa netcat:

Host distant
    ProxyCommand ssh near -W distant:22

Namun itu akan membutuhkan AllowTcpForwarding menjadi yes (default) pada mesin near (B)

sunting: membutuhkan OpenSSH 5.4+ pada B

danblack
sumber
bekerja seperti pesona :)
gongzhitaao
1
Dan setidaknya pada OpenSSH 7.4p1, ada perintah "ProxyJump" di mana seseorang hanya perlu membuat daftar setiap pengguna @ host: port dipisahkan dengan koma. Bagus!
hmijail
ProxyJump bagus, tetapi tidak mengambil Pengguna dan IdentityFile dari file konfigurasi. ProxyCommand -W melakukan ini dan juga bekerja dengan scp.
rickfoosusa
18

Anda dapat ssh ke server B menggunakan sesuatu seperti

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

Kemudian Anda dapat ssh ke server C menggunakan

ssh -p 5022 <user_serverC>@localhost 

Demikian pula scp akan bekerja menggunakan

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

Ingatlah untuk menggunakan huruf p yang benar dengan scp dan ssh

Saurabh Barjatiya
sumber
5

Itu mungkin dan relatif mudah, bahkan ketika Anda perlu menggunakan sertifikat untuk otentikasi (tipikal dalam lingkungan AWS).

Perintah di bawah ini akan menyalin file dari remotePathpada server2langsung ke mesin Anda di localPath. Secara internal permintaan scp diproksi via server1.

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

Cara sebaliknya juga berfungsi (mengunggah file):

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

Jika Anda menggunakan otentikasi kata sandi, coba dengan

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

Jika Anda menggunakan kredensial pengguna yang sama di kedua server:

scp -o ProxyCommand="ssh -W %h:%p commonuser@server1" commonuser@server2:/<remotePath> <localpath>
donhector
sumber
3

Jika Anda ingin benar-benar jahat, Anda bisa rantai ssh dan tar, semacamnya tar c mydir | ssh server "ssh otherserver | tar x", tetapi ini bisa mengalami semua masalah.

Cara yang lebih mudah adalah dengan membuat terowongan SSH dengan metode bawaan SSH; lihat -Dswitch di halaman manual dan teruskan beberapa port ke port ssh server lain.

towo
sumber
2

Anda juga dapat melakukan ini secara terbalik dan mungkin lebih mudah.

Misalkan Anda memiliki sesi ssh dibuka dengan mesin yang ingin Anda kirimi file. PC terjauh-hop ini, kita akan menyebutnya hop2 ini. Host "proxy" Anda adalah hop1. PC yang merupakan asal file, kami akan memanggil asal itu.

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

Anda dapat membangun terowongan yang menyediakan port lokal pada PC jarak jauh. Dengan demikian, kami menetapkan port untuk dibuka pada PC jarak jauh, yang akan menjadi pengalihan ke port yang Anda tumpangi saat membangun terowongan.

Di 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

Sekarang di sesi terowongan yang dibuka, Anda dapat melakukan hal yang sama dari hop1 ke file_origin.

Di hop1:

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.

Anda sekarang terowongan dari hop2 ke hop1 ke asal. Secara kebetulan, sekarang kedua port 5555 dan 6666 terbuka pada asalnya, yang dialihkan ke port 22 hop2. Dalam sesi ini, kedua berikut adalah rute scp yang valid ke hop2:

Asal:

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

Dengan cara ini, Anda dapat memiliki beberapa jumlah hop yang sewenang-wenang di antaranya, dan lebih mudah untuk digunakan dalam hal merantai bersama lebih dari dua hop.

SYANiDE
sumber
1

Cobalah mengadaptasi contoh berikut ini konfigurasi openssh untuk pengaturan yang dapat digunakan untuk banyak host:

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

Ini menganggap seperangkat server yang dimulai dengan "uat-" yang hanya dapat diakses melalui server jumpbox / gateway "bastion-uat". Anda mungkin juga ingin menambahkan ForwardAgent yesjika Anda menggunakan kunci untuk masuk.

Benjamin Goodacre
sumber
Jangan gunakan ForwardAgent yesuntuk ini. Penerusan agen tidak diperlukan dalam kasus ini karena tidak ada klien ssh yang akan berjalan di benteng, dan meneruskan agen ketika tidak diperlukan hanya akan mengurangi keamanan. Dan saya pikir sshhilang dari perintah Anda. Jika sshversi terbaru sedang digunakan yang tidak Anda butuhkan nc, Anda bisa mengetik ssh -W %h:%p bastion-uat.
kasperd
@kasperd Diedit untuk memasukkan ssh. ForwardGener; klien ssh akan berjalan untuk menjalankan perintah nc itu sendiri. Mungkin Anda mengacu pada shell?
Benjamin Goodacre
1

Ini bukan scp (yang diminta OP), tapi saya merasa sangat mudah digunakan rsyncuntuk menyalin dari lokal ke jarak jauh melalui satu hop dengan:

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

Sumber: http://mjbright.blogspot.com/2012/09/using-rsync-over-multi-hop-ssh.html

Saya telah mencoba saran -o ProxyPass di atas dan tidak ingin mengubah konfigurasi untuk kebutuhan saya yang berubah. Seperti yang dinyatakan penulis di tautan di atas, file tujuan yang mendahului titik dua (:) penting untuk menunjukkan jalur yang ditentukan ada di server tujuan. Juga, menggunakan rsync, Anda memiliki opsi untuk membandingkan tanggal, sinkronisasi folder, dll. Saya harap ini membantu seseorang!

texas-bronius
sumber
-2

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

Saya dan
sumber
3
Jangan hanya membuang sedikit kode yang tidak dapat dijelaskan di sini. Ada banyak jawaban bagus untuk pertanyaan ini dan Anda perlu menambahkan nilai pada yang sudah ada - ini tidak.
Sven