Menyalin file yang dilindungi antar server dalam satu baris?

13

Saya ingin menyalin squid.confdari satu server ke yang lain.

  • Server tidak berbicara satu sama lain. Saya ingin melewati workstation saya.
  • Kedua server memiliki file, sehingga akan ditimpa pada target.
  • File-file tersebut memiliki 600izin dan dimiliki oleh root.
  • login root melalui ssh dinonaktifkan ( PermitRootLogin no).
  • Saya ingin melakukannya dalam satu baris, jika memungkinkan, karena ini akan menjadi bagian dari panduan pengaturan.

Saya tahu harus melakukan

ssh source 'tar czpf - -C /etc/squid/ squid.conf' | \
    ssh target 'tar xzpf - -C /etc/squid/'

untuk menyalin file antara server dan mempertahankan izin. Namun, dalam hal ini saya akan mendapatkan "Izin ditolak".

Saya juga tahu saya bisa melakukan ini:

ssh -t source 'sudo cat /etc/squid/squid.conf'

Dengan cara ini, -tsudo memungkinkan untuk meminta kata sandi admin sebelum mengeluarkan konten file.

Masalahnya adalah, saya tidak tahu bagaimana menggabungkan teknik-teknik itu menjadi sesuatu yang akan meminta kata sandi sudo pada setiap server, dan mentransfer file ke tujuannya. Apakah ini mungkin?

UPDATE : Ini yang terbaik yang bisa saya pikirkan:

ssh -t source 'sudo tar czf /tmp/squid.tgz -C /etc/squid squid.conf' && \
ssh source 'cat /tmp/squid.tgz' | \
    ssh target 'cat >/tmp/squid.tgz' && \
ssh -t source 'sudo rm /tmp/squid.tgz' && \
ssh -t target \
    'sudo tar xzf /tmp/squid.tgz -C /etc/squid && sudo rm /tmp/squid.tgz'

Menyebut ini one-liner tampak seperti peregangan. Saya pikir saya hanya akan memecahnya menjadi langkah-langkah terpisah dalam panduan pengaturan.

itsadok
sumber

Jawaban:

11

Lebih mudah untuk rantai ssh dengan ssh daripada rantai ssh dengan sudo. Jadi mengubah konfigurasi server ssh ok, saya sarankan membuka ssh untuk root dari setiap server, tetapi hanya dari localhost. Anda dapat melakukan ini dengan Matchklausa di sshd_config:

PermitRootLogin no
Match Host localhost
    PermitRootLogin yes

Kemudian Anda dapat mengatur rantai otentikasi berbasis kunci dari pengguna jarak jauh ke pengguna lokal dan dari pengguna lokal ke root. Anda masih memiliki jejak otentikasi sehingga log Anda memberi tahu Anda siapa yang login sebagai root, dan langkah-langkah otentikasi sama seperti jika sudo terlibat.

Untuk terhubung ke server sebagai root, tentukan alias di ~/.ssh/configseperti ini:

Host server-root
HostName server.example.com
User root
ProxyCommand "ssh server.example.com nc %h %p"

Jika Anda bersikeras menggunakan sudo, saya yakin Anda akan memerlukan perintah terpisah, karena sudobersikeras untuk membaca dari terminal (bahkan jika itu memiliki tiket untuk akun Anda) ¹, dan tidak ada metode penyalinan file yang biasa (scp, sftp, rsync) dukungan berinteraksi dengan terminal jarak jauh.

Tetap menggunakan ssh dan sudo, perintah yang Anda ajukan dapat disederhanakan. Di setiap sisi, jika Anda telah mengatur sudo untuk tidak meminta kata sandi lagi, Anda dapat menjalankannya sekali untuk menyelesaikan persyaratan kata sandi dan waktu lain untuk menyalin file. (Anda tidak dapat dengan mudah menyalin file secara langsung karena prompt kata sandi menghalangi.)

ssh -t source 'sudo true'
ssh -t target 'sudo true'
ssh -t source 'sudo cat squid.conf' |
ssh -t target 'sudo tee /etc/squid/squid.conf'

¹ kecuali kamu punya NOPASSWD, tapi kamu tidak akan menanyakan ini.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Solusi pertama bekerja dengan baik untuk saya tetapi baris kedua seharusnya Match host localhost.
cduck
4

Anda dapat mengatur sudountuk tidak meminta kata sandi dengan cara berikutnya:

Sumber:

user    ALL=NOPASSWD:/bin/cat

Sesuai target:

user    ALL=NOPASSWD:/usr/bin/tee

Dan lakukan pada mesin Anda:

ssh source 'sudo cat /test' | ssh target 'sudo tee /test'

Tapi saya sarankan untuk menggunakan sesuatu seperti boneka . Ini jauh lebih baik dan lebih mudah menyelesaikan masalah Anda dengan distribusi file konfigurasi.

PS. Omong-omong, jika Anda akan mengatur sudountuk meminta kata sandi dari pengguna, string dengan [sudo] password for userakan muncul di file target.

buru-buru
sumber
+1 untuk menyarankan boneka, tetapi solusi Anda tampaknya tidak aman. Saya mungkin juga mengizinkan login sebagai root.
itsadok
2

Alih-alih menggunakan ssh, Anda dapat menggunakan scp untuk mentransfer file antara server.

Masuk ke server target:

Ubah ke direktori target tempat Anda ingin menyalin file.

#scp -r -p -P 22 root@source-ipaddress:/source-path-file-to-copy .

r - rekursif p - Mempertahankan waktu modifikasi, waktu akses, dan mode dari file asli

Mughil
sumber
Ini mengasumsikan saya bisa login sebagai root, yang saya tidak bisa. Memperbarui pertanyaan.
itsadok
2

Tanpa mengubah konfigurasi ssh, Anda dapat membuat dua terowongan ssh host-> server1 dan server2-> host melalui koneksi ssh ke server2. Hubungkan kedua terowongan ini pada mesin host (port yang sama). Dan jalankan sudo di server2 untuk mengambil data dari terowongan yang terhubung di server1 dan menyimpannya di server2.

ssh -L60000:${source}:22 -R60000:localhost:60000 -t ${target} 'sudo bash -c "ssh -p 60000 '$(whoami)'@localhost \"cd /path/to/dir; tar -czf - files\"|tar -C/path/to/target -xzf -"'

Idenya adalah: 1- untuk membuat terowongan lokal dari mesin Anda ke mesin sumber pada port 60000

ssh -L60000:${source}:22

1b- Buat terowongan jarak jauh untuk mencapai kembali ke mesin Anda

-R60000:localhost:60000

2- terhubung ke mesin target

-t ${target}

3 - jalankan semua sebagai root pada mesin target untuk menulis

'sudo bash -c "..."'

4- terhubung ke mesin sumber melalui terowongan. whoami dan localhost berarti localhost pada mesin $ {target}.

ssh -p 60000 '$(whoami)'@localhost

5- mengemas file jarak jauh dan mengirimnya zip ke stdout

cd /path/to/dir; tar -czf - file

6- menerima paket melalui stdout dan mengekstrak file sesuai pada direktori / path / ke / target

|tar -C/path/to/target -xzf -

Catatan: Anda dapat menerima hingga 3 konfirmasi tombol dan 3 permintaan kata sandi. Tetapi file akan disalin.

Marco Aurelio
sumber