file scp melalui host perantara


76

Saya memiliki akses ke 3 mesin, A, B, dan C. Satu-satunya kemungkinan koneksi (ssh) adalah:

A -> B
B <-> C

Saya perlu mendapatkan file dari A ke C, jadi saya bisa scp file dari A ke B, dan kemudian scp dari B ke C. Namun, B tidak memiliki banyak ruang disk, jadi ini bukan pilihan. Apakah ada cara untuk scp file dari A ke C via B? Catatan, saya tidak memiliki akses root pada salah satu mesin, jadi jangan berpikir saya bisa mengatur terowongan yang persisten, tetapi perbaiki saya jika saya salah!


4
Saya tahu ini tidak menjawab pertanyaan, tetapi bagi mereka yang tidak tahu tentang rsync, atau tidak tahu bagaimana menggunakannya untuk melompati host, ini bisa menjadi tip yang bermanfaat: gunakan opsi '-e' dengan rsync seperti ini:A$ rsync <options> -e 'ssh B ssh' source C:destination
Eddified

Jawaban:


100

ProxyJump

Baru di OpenSSH 7.3:

A$ scp -oProxyJump=B thefile C:destination

(Di belakang layar, ini hanya menggunakan ProxyCommand dan ssh -W.)

Perintah Proxy

Diperbarui untuk menyertakan -W dari jawaban lain:

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

Jika A memiliki klien SSH yang sangat lama diinstal (tanpa -Wdukungan), atau jika B dikonfigurasi untuk melarang penerusan TCP (tetapi masih memungkinkan perintah shell), gunakan alternatif:

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

Pipa

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\""

Hanya untuk satu file:

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

"Tunnel" melalui B

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

A$ scp -P 4567 thefile localhost:destinationPath

Setelah selesai, jangan lupa untuk mematikan proses yang sebelumnya dimulai ssh(yang telah jatuh ke latar belakang karena -f -N).

  • -fMeminta ssh untuk pergi ke latar belakang sebelum eksekusi perintah. Ini berguna jika ssh akan meminta kata sandi atau frasa sandi, tetapi pengguna menginginkannya di latar belakang. Ini menyiratkan -n.
  • -NJangan jalankan perintah jarak jauh. Ini berguna untuk hanya meneruskan porta.

Membalikkan "terowongan" melalui B ke A

Tidak selalu bekerja:

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 Menentukan bahwa koneksi ke port TCP yang diberikan atau soket Unix pada host (server) jarak jauh harus diteruskan ke host dan port yang diberikan, atau soket Unix, di sisi lokal.

Terima kasih banyak untuk contoh-contoh ini @grawity. Satu pertanyaan - apakah mungkin untuk membalikkan `tar c thefile anotherfile | ssh B "ssh C \" cd tujuan && tar xv \ "" ´ untuk menyalin unduhan dari C ke A (berada di A)
dmeu

@ Dmeu: Ya, itu mungkin.
grawity

Bagaimana cara "membunuh" proses ssh yang dimulai sebelumnya jika mengatakan saya menggunakan MacOS?
Aero Windwalker

Catatan: Seperti biasa, jika Anda ingin scp dari C, meskipun B, ke A, Anda bisa melakukannya A$ scp -oProxyJump=B C:destination thefile.
jvriesem

@Pablo Lebih baik gunakan -S, lalu, dan -O keluar. Atau ... setidaknya pkill -f.
grawity

23

Versi scp dari awal 2011 dan yang lebih baru mungkin memiliki opsi "-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.

Jika sudah begini, Anda bisa menjalankan:

B$ scp -3 A:file C:file

Dalam kasus saya, host A hanya dapat diakses dari B (yang di-VPN). Host C berada di LAN yang sama dengan B. Saya ingin mendapatkan file dari A ke C dan scp -3 menyelesaikannya dengan cemerlang.
Joe

Saya mengalami masalah dengan ini ketika kedua host meminta kata sandi. Tampaknya meminta keduanya sekaligus (dua permintaan kata sandi muncul di baris yang sama) dan kemudian gagal menerima kata sandi saya. Saya akhirnya bisa membuatnya bekerja dengan mengetikkan kata sandi saya berulang kali (kata sandi yang sama pada kedua host), tetapi sulit untuk mencari tahu.
Colin D

8

Hampir semua telah sudah mengatakan tapi di sini adalah sen terakhir saya: Saya menggunakan ProxyCommand varian tanpa ncatau soc. Berdasarkan OpenSSH Proxies dan Jumphost Cookbook, saya membuat konfigurasi berikut:

  1. Jadi kami memiliki pemain berikut:

    • HOME_HOST: dari sinilah kami menyalin file ke host target
    • HOP_HOST: kami menyalin melalui host ini (dicatat sebagai HOP_USER)
    • TARGET_HOST: itu adalah tujuan kami (diautentikasi sebagai TARGET_USER)
  2. Pertama saya menambahkan kunci publik lokal saya dari host rumah saya .ssh/id_dsa.pub ke host .ssh/authorized_keyshop dan target. Ya, kunci publik yang sama dari tuan rumah ke keduanya. Biasanya Anda akan mengharapkan itu adalah kunci publik HOP yang harus Anda tambahkan ke TARGET.

  3. Lalu saya .ssh/configsedikit men - tweak dengan menambahkan entri berikut:

    Host TARGET_HOST
       User TARGET_USER
       ProxyCommand ssh -W %h:%p HOP_USER@HOP_HOST
    
  4. Setelah itu operasi copy adalah yang sederhana seperti: scp FILE TARGET_HOST:. Ini menampilkan spanduk ganda dari node hop dan target tetapi berfungsi.

Tentu saja Anda dapat menggunakan di atas untuk ssh langsung ke sasaran: ssh TARGET_HOST. Ini bekerja dengan scp dan ssh.

Pilihan lain yang lebih umum mungkin adalah utilitas sshuttle yang tampaknya semacam proxy transparan (vpn over ssh). Jadi dalam kasus A-> B <-> C Anda memungkinkan untuk terhubung ke setiap node di jaringan C: A-> B- [CDEFG]. Tidak perlu admin tetapi membutuhkan Python 2.7 (3.5 juga OK) yang tidak selalu seperti yang kita miliki. Layak untuk dicoba.


7
ssh -L 4321:hostC:22 youruser@hostB

di shell lain:

scp -P 4321 localfile youruser@127.0.0.1

Ini menggunakan penerusan porta. Satu-satunya batasan di sini adalah host B perlu dikonfigurasi untuk memungkinkan penerusan port. Kalau tidak, ini akan bekerja dengan baik.

Di jalan penjelasan, -Ldan -Rmemungkinkan Anda untuk meneruskan port. Dalam -L, port pertama yang diberikan adalah port ssh akan mulai mendengarkan pada mesin asal (host A), dan itu akan meneruskan apa pun yang diterimanya pada port tersebut melalui koneksi SSH Anda ke host B, kemudian merutekan ke host C pada port 22.

sunting

Saya sedikit mengacaukan sintaks. Ini mengatur maju pada mesin LOKAL Anda.


@astrofrog - jika salah satu jawaban kami memuaskan kebutuhan Anda, Anda mungkin harus menerimanya.
Brian Vandenberg

1

Jawaban ProxyCommand Grawity berhasil untuk saya, tetapi karena saya kurang terbiasa dengan SSH, perlu beberapa percobaan. Saya pikir saya hanya akan mengeja jawaban Grawity dengan lebih detail untuk membantu pemula lain untuk SSH seperti saya. Berikut adalah definisi untuk notasi yang lebih eksplisit:

Mesin A: mesin yang Anda pakai

Server B: userB@ip.address.for.B (host melompat atau server tengah)

Server C: userC@ip.address.for.C (server jarak jauh yang ingin Anda salin)

ProxyCommnad

    A$ scp -oProxyCommand="ssh -W %h:%p userB@ip.address.for.B" thefile userC@ip.address.for.C:destination

Contoh nyata

Jadi untuk contoh konkret, misalkan Anda memiliki akses ke server dengan IP 0.0.1.2dengan akun pengguna bernama bar(Server C). Tetapi untuk mencapainya Anda harus terlebih dahulu masuk ke server dengan IP 0.0.1.1dengan akun pengguna bernama foo(Server B). Sekarang Anda ingin menyalin file baz.txtyang terletak pada mesin Anda saat ini (Machine A) ke server 0.0.1.2's /home/bar/direktori. Untuk menggunakan ProxyCommand di atas untuk contoh ini Anda akan menjalankan yang berikut:

    A$ scp -oProxyCommand="ssh -W %h:%p foo@0.0.1.1" baz.txt bar@0.0.1.2:/home/bar/

Anda juga dapat dengan mudah menyalin file dari Server C dengan mengalihkan urutan file dan tujuan. Jadi misalnya, jika baz.txtsudah ada di server yang 0.0.1.2terletak di /home/bar/maka Anda dapat menyalinnya ke mesin Anda menggunakan:

    A$ scp -oProxyCommand="ssh -W %h:%p foo@0.0.1.1" bar@0.0.1.2:/home/bar/baz.txt /destination/path/on/A

Semoga ini bisa membantu orang yang membutuhkan sesuatu yang dijabarkan lebih banyak daripada yang lain.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.