Paksa SSH untuk menggunakan shell tertentu

29

Apakah ada cara untuk memaksa SSH menggunakan shell tertentu pada ujung jarak jauh, terlepas dari apa shell default pengguna?

Saya sudah mencoba solusi yang mirip dengan:

ssh host.domain.com /bin/bash -c 'complicated, multi-line command'

tetapi sayangnya shell default pada ujung jarak jauh bertanggung jawab untuk mem-parsing bagian "rumit, perintah multi-line", dan saya mengalami kesulitan untuk menghindarinya agar berfungsi baik untuk pengguna shell Bash dan C.

Plinehan
sumber

Jawaban:

8

Saya tidak percaya ini mungkin, setidaknya dengan sistem berbasis openssh. Jika Anda memiliki kemampuan, solusi yang lebih baik mungkin dengan sftp file shell-script, dan kemudian jalankan dengan metode yang Anda posting. Itu akan memiliki keuntungan meminimalkan jumlah pelarian yang diperlukan, tetapi akan meninggalkan file di belakang yang harus dihapus (mungkin sebagai langkah terakhir dari skrip).

sysadmin1138
sumber
1
Inilah yang akhirnya saya lakukan, tetapi menggunakan scp. Ide yang bagus.
Plinehan
16

Gunakan heredoc:

ssh host.domain.com /bin/bash << EOF
big ugly commands
lots of them
EOF
Ignacio Vazquez-Abrams
sumber
tidakkah Anda harus menggunakan "-s" untuk bash untuk membaca perintah dari stdin?
Weboide
Itu tidak selalu diperlukan.
Ignacio Vazquez-Abrams
Saya akan memilih ini jika saya bisa karena itu mencegah perintah dari memiliki akses ke stdin dan pertanyaannya adalah tentang menggunakan shell tertentu.
Eric Woodruff
3
@EricWoodruff, ... memohon shell tertentu (dalam hal ini bash) adalah persis apa yang menunjukkan bagaimana melakukannya.
Charles Duffy
1
FYI juga bisa kamu lakukan cat /tmp/tempfile_containing_your_script ssh ${hostname} /bin/bash. Jadi alih-alih satu langkah Anda memiliki dua langkah: langkah 1 salin skrip Anda ke file, langkah 2 catskrip untuk ssh.
Trevor Boyd Smith
10

Gunakan login berbasis kunci, bukan berbasis kata sandi. Kemudian Anda dapat menambahkan (daftar) "perintah paksa" ke kunci ssh publik Anda (dalam bidang "opsi" untuk SSH1) yang diinstal pada server (dalam file ~ / .ssh / Authorized_key untuk SSH1 , ~ / .ssh2 / otorisasi untuk SSH2).

Buat perintah paksa Anda sehingga shell yang Anda inginkan disebut ...

Lebih lanjut: Anda dapat mengaitkan paling banyak satu perintah paksa ke kunci yang diberikan. Jika Anda memerlukan beberapa perintah paksa untuk tujuan yang berbeda, Anda harus mengatur kunci yang berbeda. (Tentu saja Anda dapat memasukkan banyak hal ke dalam satu skrip, yang Anda panggil melalui perintah paksa. Namun perlu diketahui bahwa perintah paksa selalu dijalankan untuk akun / kunci yang diberikan jika pengguna masuk, terlepas jika ia meminta sesuatu yang berbeda untuk dijalankan. Jika Anda ingin tetap menghormati perintah asli yang diminta, lihat bagaimana cara mengeksploitasi $SSH_ORIGINAL_COMMANDvariabel ...)

Baca tentang "perintah paksa" melalui Google .

Kurt Pfeifle
sumber
Barang bagus. Grafik di halaman O'Reilly sangat bagus. Namun dalam kasus khusus saya, saya ingin dapat memaksakan ini untuk setiap pengguna, bukan hanya pengguna yang telah mengatur kunci mereka dengan benar. Saya juga tidak memiliki root pada mesin server, jadi saya tidak dapat mengedit file seperti /etc/sshrc.
Plinehan
Yah, selalu server (atau lebih baik: orang yang memberikan kontrol atas server) yang memanggil tembakan ketika Anda terhubung ke layanannya .... 'Pemilik' server memutuskan apa yang dapat dilakukan dengan itu. - Anda tidak dapat memaksakan apa pun 'untuk pengguna mana pun' jika Anda tidak memiliki hak istimewa lebih tinggi dari mereka.
Kurt Pfeifle
Jika klien dapat menjalankan perintah arbitrer maka klien dapat menjalankan shell arbitrer sebagai perintah juga.
Eric Woodruff
@KurtPfeifle yang memiliki tautan ke O'Reilly rusak
Brian Vandenberg
@BrianVandenberg: Terima kasih atas petunjuknya. Saya menghapus tautan itu sekarang.
Kurt Pfeifle
2

Anda dapat menggunakan -topsi untuk memaksa alokasi pseudo-tty untuk program yang ingin Anda mulai, seolah-olah Anda sedang menjalankan shell standar. Kemudian berikan shell yang Anda inginkan sebagai argumen lama.

Dengan teknik ini Anda tidak hanya dapat menggunakan shell apa pun yang diinstal tetapi Anda juga dapat membuka vim dan program lain yang membutuhkan TTY, dari satu perintah. Yang keren jika Anda menulis skrip shell yang mencatat Anda di suatu tempat dan membuka file di vim, atau htop atau sesuatu.

me@my-machine $ ssh root@myhost -t bash
root@myhost:~# exit
Connection to myhost closed.
me@my-machine $ ssh root@myhost -t sh
# exit
Connection to myhost closed.
me@my-machine $ 

Tidak yakin apakah ini shell login tetapi ada opsi untuk membuat bash bertindak seperti shell login, jadi shell Anda mungkin juga memilikinya.

Fábio Santos
sumber
1

Anehnya saya melihat hasil yang berbeda dengan yang berikut:

jalankan di dash:

ssh eric@172.17.1.241 /bin/bash -c "echo <(cat)"                                              
sh: 1: Syntax error: "(" unexpected

vs bash:

ssh eric@172.17.1.241 '/bin/bash -c "echo <(cat)"'                                            
/dev/fd/63

Menampilkan perintah yang dikutip sepenuhnya berfungsi seperti yang diharapkan.

Eric Woodruff
sumber
1
Tidak mengherankan sama sekali. Daemon ssh jarak jauh berjalan secara efektif sh -c "$*". Jadi, Anda berlari sh -c "/bin/bash -c echo <(cat)"; yang echoperintah itu sendiri adalah satu-satunya argumen dilewatkan ke -c, dan <(cat)merupakan argumen yang terpisah sama sekali.
Charles Duffy
0

Saya menghadapi situasi yang sama beberapa waktu lalu di mana saya perlu menggunakan ksh coprocess untuk sqlplus dan saya hanya punya ssh melalui mana membaca dan menulis harus dilakukan.

Cara untuk melakukan ini adalah menyalurkan semua perintah dependen Anda ke dalam satu baris (gunakan;) ke / usr / bin / ksh pada mesin jarak jauh. sebagai contoh:

host="user@host"

db_conn="ora_user/passwd"

a="select * from dual;"

frmt="set heading off echo off feedback off verify off pagesize 0 termout off"

var=$(ssh ${host} "echo 'sqlplus -silent /nolog |&; sql_pid=\$!; print -p \"conn ${db_conn}\"; print -p \"${frmt}\"; print -p \"${a}\"; print -p \"exit\"; wait \$sql_pid' > /remote_dir/kshcmd.txt; awk '{print \$0}' /remote_dir/kshcmd.txt | /usr/bin/ksh")
aws
sumber