rsync hack untuk memantulkan file antara dua server yang tidak terhubung

8

Inilah hubungannya:

[Server1] <---> [my desktop] <---> [Server2]

Server1 dan server2 tidak diizinkan untuk berbicara langsung dengan satu sama lain (jangan tanya). Desktop saya, bagaimanapun dapat mengakses kedua server melalui ssh.

Saya perlu menyalin file dari server1 ke server2.

Secara tradisional saya telah menggunakan hack ssh + tar, seperti:

ssh -q root@Server1 'tar -vzc /path/to/files ' | ssh -q root@Server2 'tar -vzx -C /'

Dan itu bekerja dengan baik, tapi saya ingin mengambil langkah lebih jauh dan membuat rsync bekerja antara dua server melalui desktop saya.

Sekarang saya tahu bahwa saya dapat memulai sebuah ssh port-forward tunnel di satu terminal dan kemudian rsync melewati tunnel tersebut di jendela lain, tetapi saya tidak ingin repot-repot dengan terminal kedua atau membuat dan memecah port forward tunnel yang terpisah. yang saya inginkan adalah:

  • Perintah one liner untuk rsync file dari Server1 ke server2 MELALUI desktop saya
  • semua pada SATU baris perintah, satu jendela terminal
  • Saya ingin port forward tunnel hanya ada untuk kehidupan perintah rsync.
  • Saya tidak ingin scp, saya ingin rsync.

Adakah yang punya trik untuk melakukan itu?

EDIT: Ini perintahnya! Kerja bagus semua orang: 1. Untuk jalur kunci rsa, tidak dapat menggunakan tildae, harus menggunakan "/ root /". 2. Inilah perintah terakhir:

ssh -R 2200:SERVER2:22 root@SERVER1 "rsync -e 'ssh -p 2200 -i /root/.ssh/id_rsa_ROOT_ON_SERVER2' --stats --progress -vaz /path/to/big/files root@localhost:/destination/path"

Boom melanjutkan dinamit.

regulatre
sumber
Ini sangat bagus. Satu hal yang perlu diubah adalah menonaktifkan verifikasi kunci host. Anda memiliki kunci SSH untuk otentikasi TTYless, tetapi karena server tidak pernah berbicara satu sama lain, mereka tidak dapat memverifikasi kunci host. Jadi yang terbaik untuk menonaktifkannya: -o StrictHostKeyChecking = tidak setelah flag -p atau -i.
Amala

Jawaban:

5

Jika Anda senang menyimpan salinan data di mesin perantara maka Anda cukup menulis skrip yang memperbarui salinan lokal menggunakan server1 sebagai referensi kemudian memperbarui cadangan di server2 menggunakan salinan lokal sebagai referensi:

#!/bin/sh
rsync user@server1:/path/to/stuff /path/to/loca/copy -a --delete --compress
rsync /path/to/loca/copy user@server2:/path/to/where/stuff/should/go -a --delete --compress

Menggunakan skrip sederhana berarti Anda menginginkan satu perintah untuk melakukan segalanya. Ini tentu saja bisa menjadi keamanan tidak-tidak jika data sensitif (Anda, atau orang lain di perusahaan Anda, mungkin tidak ingin salinan mengambang di laptop Anda). Jika server1 bersifat lokal bagi Anda maka Anda bisa menghapus salinan lokal setelahnya (karena akan lebih cepat untuk merekonstruksi melalui LAN lokal lain kali).

Membangun terowongan sehingga server dapat berbicara secara efektif satu sama lain secara lebih langsung harus dimungkinkan seperti:

  1. Pada server 2 buat salinan / bin / sh sebagai / usr / local / bin / shforkeepalive. Gunakan tautan simbolis daripada salinan maka Anda tidak perlu memperbaruinya setelah pembaruan keamanan yang menambal / bin / sh.
  2. Pada server 2 buat skrip yang tidak melakukan apa-apa selain loop sleep selama beberapa detik kemudian menggemakan sejumlah kecil teks, dan minta ini menggunakan "copy" dari sh:

    #!/usr/local/bin/shforkeepalive
    while [ "1" != "0" ]; do
            echo Beep!
            sleep 5
    done
    

    ( echomungkin tidak diperlukan, karena sesi tidak akan cukup lama untuk time-out bahkan jika SSHd dikonfigurasi untuk mengabaikan paket tetap hidup dari klien ssh)

  3. Sekarang Anda dapat menulis skrip pada laptop Anda yang memulai terowongan terbalik di latar belakang, memberi tahu server1 untuk menggunakan rsync untuk melakukan operasi penyalinan, kemudian membunuh terowongan terbalik dengan mematikan skrip pengulangan (yang akan menutup sesi SSH):

    #!/bin/sh
    ssh user@server2 -L2222:127.0.0.1:22 /usr/local/bin/keepalivesctipt &
    ssh user@server1 -R2222:127.0.0.1:2222 rsync /path/to/stuff [email protected]:/destination/path/to/update -a --delete --compress -e 'ssh -p 2222'
    ssh user@server2 killall shforkeepalive
    

Cara kerjanya:

  • Baris 1: standar "perintah untuk digunakan untuk menafsirkan skrip ini" penanda
  • Baris 2: mulai koneksi SSH dengan terowongan terbalik dan jalankan skrip keepalive melalui itu untuk tetap terbuka. Trailing & memberitahu bash untuk menjalankan ini di latar belakang sehingga baris berikutnya dapat berjalan tanpa menunggu sampai selesai
  • Baris 3: mulai terowongan yang akan terhubung ke terowongan di atas sehingga server1 dapat melihat server2, dan jalankan rsync untuk melakukan salin / perbarui melalui pengaturan ini
  • Baris 4: bunuh skrip keep-hidup setelah operasi rsync selesai (dan panggilan SSH kedua kembali), yang akan dan sesi ssh pertama.

Ini tidak terasa bersih, tetapi harusnya berhasil. Saya belum menguji di atas sehingga Anda mungkin perlu men-tweak itu. Membuat perintah rsync sebagai skrip baris tunggal pada server1 dapat membantu dengan mengurangi kebutuhan untuk melarikan diri karakter seperti 'pada perintah ssh panggilan.

BTW: Anda mengatakan "jangan tanya" mengapa kedua server tidak dapat melihat satu sama lain secara langsung, tetapi seringkali ada alasan bagus untuk ini. Server rumah saya dan server tempat cadangan onlinenya tidak dapat login satu sama lain (dan memiliki kata sandi + kunci yang berbeda untuk semua pengguna) - ini berarti bahwa jika salah satu dari keduanya diretas, itu tidak dapat digunakan sebagai rute mudah untuk meretas yang lain sehingga cadangan online saya lebih aman (seseorang yang jahat menghapus data saya dari live tidak dapat menggunakan kemampuannya untuk memperbarui cadangan untuk menghapus cadangan tersebut, karena tidak memiliki kemampuan langsung untuk menyentuh situs cadangan utama). Kedua server dapat terhubung ke server perantara di tempat lain - server langsung diatur untuk mendorong cadangannya (melalui rsync) ke mesin perantara di pagi hari dan server cadangan diatur (beberapa saat kemudian untuk memungkinkan langkah satu selesai) untuk menghubungkan dan kumpulkan pembaruan (sekali lagi melalui rsyc diikuti oleh langkah snapshotting untuk mempertahankan beberapa usia cadangan). Teknik ini mungkin dapat digunakan dalam keadaan Anda juga, dan jika demikian saya akan merekomendasikannya sebagai cara yang jauh lebih bersih dalam melakukan sesuatu.

Sunting: Menggabungkan hack saya dengan Harun untuk menghindari semua mucking dengan salinan / bin / sh dan skrip keep-hidup terpisah pada server2, skrip ini pada laptop Anda harus melakukan seluruh pekerjaan:

#!/bin/sh
ssh user@server2 -L2222:127.0.0.1:22 sleep 60 &
pid=$!
trap "kill $pid" EXIT 
ssh user@server1 -R2222:127.0.0.1:2222 rsync /path/to/stuff [email protected]:/destination/path/to/update -a --delete --compress -e 'ssh -p 2222'

Seperti di atas, rsync terhubung ke localhost: 2222 yang meneruskan terowongan ke localhost laptop Anda: 2222 yang meneruskan melalui terowongan lain ke server2 localhost: 22.

Sunting 2: Jika Anda tidak keberatan server1 memiliki kunci yang memungkinkannya untuk mengotentikasi dengan server2 secara langsung (meskipun tidak dapat melihat server2 tanpa terowongan) Anda dapat menyederhanakan lebih lanjut dengan:

#!/bin/sh
ssh user@server1 -R2222:123.123.123:22 rsync /path/to/stuff [email protected]:/destination/path/to/update -a --delete --compress -e 'ssh -p 2222'

di mana 123.123.123.123 adalah alamat publik untuk server2, yang dapat digunakan sebagai salin + tempel satu-liner alih-alih skrip.

David Spillett
sumber
Ini adalah sejumlah besar data (20 + gb) dan saya lebih memilih untuk mengalirkannya keluar-masuk pada saat yang sama daripada menyimpan secara lokal. Saya ingin melakukan streaming data melalui PC saya tanpa menyimpan apa pun. Anda benar tentang "jangan tanya", itu untuk alasan yang baik, meskipun pita.
regulatre
Plesae lihat hasil edit baru pada pertanyaan asli
regulatre
Saya pikir edit terakhir saya (diposting detik sebelum komentar Anda sesuai dengan stempel waktu sehingga kami mungkin mengetik pada saat yang sama) dapat memberi Anda satu baris yang Anda cari.
David Spillett
HOORAY !!! Berhasil! 1. untuk kunci rsa, tidak bisa menggunakan tildae, harus menggunakan "/ root /". 2. inilah baris perintah terakhir:ssh -R 2200:SERVER2:22 root@SERVER1 "rsync -e 'ssh -p 2200 -i /root/.ssh/id_rsa_ROOT_ON_SERVER2' --stats --progress -vaz /path/to/big/files root@localhost:/destination/path"
regulatre
Hai @ David, terima kasih untuk peretasan hebat ini. Namun, untuk membuatnya berfungsi, saya perlu kunci server 2 pada server 1 menggunakan kedua solusi (dalam pengeditan pertama dan kedua). Saya pikir itu normal (port forwarding atau tidak, server1 masih mencoba untuk mengotentikasi ke server2), tetapi Anda menulis If you don't mind server1 having a key .... Bisakah Anda memberi tahu saya jika benar-benar memungkinkan untuk menghindari memiliki kunci server2 pada server1?
ssssteffff
2

Berikut adalah beberapa metode yang membuat sinkronisasi menjadi satu garis sederhana, tetapi memerlukan beberapa pengaturan.

  • Siapkan terowongan ssh terbalik dari server1 ke desktop Anda (maaf, saya tidak bisa memberi tahu Anda .ssh/configmantera dari atas kepala saya). Rangkai dengan koneksi dari desktop Anda ke server2. Jalankan rsync dari server1.

  • Atur proxy kaus kaki (atau proxy http yang menerima CONNECT) di desktop Anda. Gunakan untuk membuat koneksi ssh dari server1 ke server2. Jalankan rsync dari server2.

  • Gunakan bersamaan daripada rsync. Tetapi alur kerjanya berbeda.

  • Pasang direktori dari satu atau kedua server di desktop Anda menggunakan sshfs .

Gilles 'SANGAT berhenti menjadi jahat'
sumber
1

Mengapa satu baris? Gunakan skrip shell kecil:

#!/bin/bash
# Run me on server1

# Create the port forward server1 -> desktop -> server2 (i.e.
# the first forward creates a second tunnel running on the desktop)
ssh -L/-R ... desktop "ssh -L/-R ... server2 sleep 1h" &    
pid=$!

# Kill port forward process on exit and any error
trap "kill $pid" EXIT 

rsync -e ssh /path/to/files/ root@localhost:/path/to/files/on/server2

IIRC, Anda dapat mengatur waktu tidur lebih rendah; yang pertama sshtidak akan berakhir selama seseorang menggunakan saluran tersebut.

Aaron Digulla
sumber
Aku cukup yakin bahwa rsync tidak dapat beroperasi antara dua server remote melalui SSH dengan cara (hanya lokal-> terpencil atau remote-> lokal) - meskipun penggunaan sleepdan trapadalah lebih rapi daripada "tetap hidup dan membunuh" metode dalam jawaban saya .
David Spillett
silakan lihat hasil edit pada pertanyaan awal.
regulatre
Sial, kau benar. Tidak diperbolehkan menentukan dua host sebagai argumen pada perintah ling. ... hmmm ..
Aaron Digulla
Oke, saya sudah memperbaiki solusi saya. Anda perlu membuat dua port ke depan untuk membuat layanan ssh dari server2 terlihat di server1.
Aaron Digulla
Tambahkan beberapa ";" untuk mengubahnya menjadi satu-liner. Idenya lebih mudah dipahami dengan naskah.
Aaron Digulla