Bisakah saya mem-pipe stdout di satu server ke stdin di server lain?

74

stdoutpada satu server CentOS perlu disalurkan ke stdinserver CentOS lainnya. Apakah ini mungkin?

Memperbarui

ScottPack, MikeyB dan jofel semuanya memiliki jawaban yang valid. Saya memberikan jawaban kepada Scott karena, meskipun pertanyaan saya tidak menentukan keamanan sebagai persyaratan, selalu menyenangkan untuk aman. Namun, saran dua rekan lainnya juga akan bekerja.

Wesley
sumber
1
Perlu dicatat bahwa (hanya) keuntungan utama dari pendekatan non-ssh adalah kecepatan throughput; jika Anda berada di jaringan yang cepat dan keamanan tidak perlu, ini mungkin sepadan dengan ketidaknyamanan ekstra mengetik dua perintah ke dalam dua jendela.
Acak 832

Jawaban:

94

Ini ya tidak malu-malu.

Ketika seseorang menggunakan sshuntuk mengeksekusi perintah pada server jauh, ia melakukan semacam pengalihan input / output internal yang bagus. Sebenarnya, saya menemukan ini sebagai salah satu fitur OpenSSH yang lebih bagus. Secara khusus, jika Anda menggunakan sshuntuk menjalankan perintah sewenang-wenang pada sistem jarak jauh, maka ssh akan memetakan STDINdan STDOUTke perintah yang sedang dijalankan.

Untuk keperluan contoh, anggap Anda ingin membuat tarball cadangan, tetapi tidak ingin, atau tidak bisa, menyimpannya secara lokal. Mari kita melihat sintaks ini:

$ tar -cf - /path/to/backup/dir | ssh remotehost "cat - > backupfile.tar"

Kami membuat tarball, dan menulisnya STDOUT, hal-hal normal. Karena kita menggunakan ssh untuk menjalankan perintah jarak jauh, STDIN dipetakan ke STDINof cat. Yang kemudian kita arahkan ke file.

Scott Pack
sumber
11
Itu bukan semacam "pengalihan input / output internal mewah" - hanya hal biasa, yang membosankan. ssh membaca dari STDIN, sama seperti alat lainnya, dan meneruskannya ke proses jarak jauh. :)
Daniel Pittman
7
@DanielPittman: Tapi jauh lebih menyenangkan untuk menyebutnya "sampah internal".
Scott Pack
7
Demikian pula, netcatpada kedua ujungnya membuat saluran komunikasi yang sederhana, mudah. tar cf - /path/to/dir | nc 1.2.3.4 5000di satu server, nc -l -p 5000 > backupfile.tardi sisi lain.
MikeyB
1
@ MikeyB: Poin bagus. Netcat adalah protokol teks-jelas jadi berhati-hatilah dengan data sensitif. Saya cenderung menggunakan netcat untuk hal-hal yang lebih spesifik seperti akuisisi drive jaringan (ala dd) melalui jaringan lokal dan pemindaian port.
Scott Pack
2
@MikeyB: Anda, orang-orang, bagaimana dengan kursi terbang dan celana Anda!
Scott Pack
28

Cara yang nyaman untuk mem-piping data antara host ketika Anda tidak perlu khawatir tentang keamanan melalui kabel menggunakan netcatpada kedua ujungnya pada koneksi.

Ini juga memungkinkan Anda mengaturnya secara tidak sinkron:

Pada "penerima" (sungguh, Anda akan memiliki komunikasi dua arah, tetapi lebih mudah untuk memikirkannya seperti ini), jalankan:

nc -l -p 5000 > /path/to/backupfile.tar

Dan pada "pengirim", jalankan:

tar cf - /path/to/dir | nc 1.2.3.4 5000
MikeyB
sumber
Sangat bagus untuk diketahui. Ini bagus jika koneksi fisik dipercaya seperti mungkin jaringan cadangan atau jika koneksi sudah tunneled.
Wesley
Atau jika datanya adalah sesuatu yang bersifat publik.
Samuel Edwin Ward
1
+1 netcat adalah alat yang sangat berharga, terutama saat Anda tidak menjalankan server ssh.
kwarrick
21

Alat yang sangat ampuh untuk membuat koneksi satu dan dua arah adalah socat. Untuk melihat sekilas kemungkinan, lihat contoh di halaman manualnya .

Ini menggantikan netcatdan alat-alat serupa sepenuhnya dan memiliki dukungan untuk koneksi terenkripsi ssl. Untuk pemula, mungkin tidak cukup sederhana, tetapi setidaknya baik untuk mengetahui bahwa itu ada.

Jofel
sumber
1
@WesleyDavid: Untuk "Pembaruan" Anda: Hanya untuk kelengkapan, saya telah menambahkan jawaban saya bahwa socat memiliki dukungan SSL, jadi enkripsi juga dengan socat. Namun, dalam banyak kasus ssh adalah solusi yang lebih baik dan lebih mudah, jadi saya akan memilih jawaban ScottPack juga.
jofel
5

TL; DR

Hal-hal hanya menjadi sedikit lebih rumit ketika Anda memiliki server benteng yang harus digunakan.

  1. Anda dapat mengirimkan sshsebagai perintah untuk sshmenyukainya:

    • cat local_script.sh | ssh -A usera@bastion ssh -A userb@privateserver "cat > remote_copy_of_local_script.sh; bash remote_copy_of_local_script.sh"
  2. Waspadai terminal palsu


Perhatikan bahwa poin penting utama di sini adalah ssh, seperti kebanyakan alat, hanya memperlakukan stdoutdan stdinmemperbaiki secara default.

Namun, ketika Anda mulai melihat opsi suka Disable pseudo-terminal allocation.dan Force pseudo-terminal allocation.Anda mungkin perlu melakukan sedikit trial and error. Tapi, sebagai aturan umum Anda tidak ingin mengubah ttyperilaku kecuali Anda mencoba untuk memperbaiki sampah yang rusak / biner di emulator terminal (apa yang diketikkan oleh manusia).

Sebagai contoh, saya cenderung menggunakan -Atsehingga ssh-agent workstation saya diteruskan, dan menjalankan tmux dari jarak jauh tidak muntah biner (seperti begitu ssh -At bastion.internal tmux -L bruno attach). Dan, untuk buruh pelabuhan juga (seperti itu sudo docker exec -it jenkins bash).

Namun, kedua -tflag tersebut menyebabkan beberapa sulit untuk melacak korupsi data ketika saya mencoba melakukan sesuatu seperti ini:

# copy /etc/init from jenkins to /tmp/init in testjenkins running as a container
ssh -A bastion.internal \
ssh -A jenkins.internal \
sudo tar cf - -C /etc init | \
sudo docker exec -i testjenkins \
bash -c 'tar xvf - -C /tmp'

# note trailing slashes to make this oneliner more readable.
Bruno Bronosky
sumber
2

Cobalah untuk meletakkan kunci publik ssh Anda di host lain hanya dengan satu perintah

ssh [email protected] 'cat >> .ssh/authorized_keys' < .ssh/id_rsa.pub
piring
sumber
2

Saya menemukan ini sebagai yang termudah, setelah mengatur tidak ada handshaking kata sandi antara server untuk pengguna Anda menjalankan perintah sebagai:

Tidak terkompresi

tar cf - . | ssh servername "cd /path-to-dir && tar xf -"

Kompresi dengan cepat

tar czf - . | ssh servername "cd /path-to-dir && tar xzf -"
pengguna60802
sumber
Menggunakan kompresi pada file tar adalah ide yang sangat buruk jika Anda sshsudah dikonfigurasi untuk kompresi.
Anthon
@Anthon Mengapa sangat buruk, dan bagaimana orang akan memeriksa apakah kompresi ssh sudah diaktifkan?
Tom Hale
1
@ TomHale Tergantung pada kecepatan sistem Anda, ini mungkin memperlambat operasi keseluruhan, karena kompresi kedua membutuhkan waktu, tetapi tidak mungkin untuk mencukur byte tambahan. Compressiondapat diatur di salah satu file konfigurasi, pemeriksaan cepat untuk itu adalah untuk melihat apakah ssh -v localhost exit 2>&1 | fgrep -i compressmemberikan output (AFAIK tidak ada pilihan untuk membuang konfigurasi seperti ssh telah membacanya di).
Anthon
tarmemiliki -C pathbendera yang berfungsi untuk cdan xperintah. Anda tidak harus meletakkan cdperintah terpisah di sana. (Tetapi itu baik untuk dicatat bahwa Anda dapat menjalankan lebih dari satu perintah.)
Bruno Bronosky
@ Bruno, -Cadalah ekstensi GNU (meskipun sekarang juga didukung oleh bsdtar dan schily tar)
Stéphane Chazelas