Gunakan harapkan dalam skrip bash untuk memberikan kata sandi pada perintah SSH

131

Bagi mereka yang ingin membalas bahwa saya harus menggunakan kunci SSH tolong abstain

Saya mencoba menggunakan harapkan dalam skrip bash untuk memberikan kata sandi SSH. Memberikan kata sandi berfungsi tetapi saya tidak berakhir di sesi SSH sebagaimana mestinya, ia kembali menjadi bash.

Skrip saya:

#!/bin/bash

read -s PWD

/usr/bin/expect <<EOD
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com'
expect "password"
send "$PWD\n" 
EOD
echo "you're out"

Output dari skrip saya:

spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com
usr@$myhost.example.com's password: you're out

Saya ingin memiliki sesi SSH saya dan hanya ketika saya keluar untuk kembali ke skrip bash saya. Alasan mengapa saya menggunakan bash sebelum mengharapkan adalah karena saya telah menggunakan menu saya dapat memilih unit mana yang akan dihubungkan.

Terima kasih

Maks
sumber
49
silakan lihat baris pertama: Bagi mereka yang ingin membalas bahwa saya harus menggunakan kunci SSH tolong abstain
Max
54
Saya akan mengedit baris pertama Anda menjadi sedikit lebih ramah. Anda mungkin mempertimbangkan sesuatu seperti "Karena kendala, saya tidak bisa menggunakan kunci SSH, saya harus menemukan cara untuk membuatnya bekerja dengan yang diharapkan". Anda harus berharap bahwa orang-orang mungkin secara alami ingin tahu mengapa Anda tidak menggunakan kunci, dan hanya mencoba untuk membantu :) @Ignacio tidak menyarankan Anda menggunakannya, ia hanya menegaskan itu sebagai kendala dan bukan pengawasan.
Tim Post
Saya akan mencoba menggunakan kermit dalam kasus ini. Ini memiliki bahasa skrip yang sangat kuat columbia.edu/kermit/skermit.html#script
f3xy

Jawaban:

86

Mencampur bash dan berharap bukanlah cara yang baik untuk mencapai efek yang diinginkan. Saya akan mencoba menggunakan hanya Harapkan:

#!/usr/bin/expect
eval spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com
#use correct prompt
set prompt ":|#|\\\$"
interact -o -nobuffer -re $prompt return
send "my_password\r"
interact -o -nobuffer -re $prompt return
send "my_command1\r"
interact -o -nobuffer -re $prompt return
send "my_command2\r"
interact

Contoh solusi untuk bash dapat:

#!/bin/bash
/usr/bin/expect -c 'expect "\n" { eval spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com; interact }'

Ini akan menunggu sesi interaktif masuk dan kembali (sesaat).

Piotr Król
sumber
1
ini bekerja dengan baik, terima kasih. Bagaimana jika saya ingin mengetik perintah setelah saya masuk melalui SSH, apa yang harus saya lakukan?
Maks
Skrip ini harus mengembalikan shell yang tidak aktif dengan pengguna yang login. Saya tidak mengerti pertanyaan. Jika Anda benar-benar ingin menggunakan skrip yang sama di bash lihat entri yang diedit.
Piotr Król
Cara yang sama ketika saya mengirim kata sandi ketika diminta, saya ingin mengirim perintah sistem setelah login.
Maks
Kode Samlple ditambahkan ke pos di atas. Tentu saja ini akan berfungsi sampai my_commandX tidak mengubah prompt yang dikembalikan, jika ini terjadi, variabel prompt harus diubah.
Piotr Król
@pietrushnic dapatkah Anda menjelaskan sedikit mengapa menggunakan "interaksi -o -nobuffer -re $ prompt kembali", alih-alih "harapkan $ prompt"? yang terakhir terlihat lebih umum digunakan ..
Richard
53

Cara termudah adalah dengan menggunakan sshpass . Ini tersedia di repo Ubuntu / Debian dan Anda tidak harus berurusan dengan mengintegrasikan ekspektasi dengan bash.

Sebuah contoh:

sshpass -p<password> ssh <arguments>
sshpass -ptest1324 ssh user@192.168.1.200 ls -l /tmp

Perintah di atas dapat dengan mudah diintegrasikan dengan skrip bash.

Catatan: Silakan baca bagian Pertimbangan Keamananman sshpass untuk memahami sepenuhnya implikasi keamanan.

dotnix
sumber
Saya tidak tahu apakah ini solusi yang baik, tetapi tentu saja sangat menyederhanakan. Terima kasih
erikbwork
9
Sangat berbahaya dari sudut pandang keamanan - argumen baris perintah dapat dibaca oleh proses lain pada sistem. Dimungkinkan untuk menimpa mereka, dan mudah sshpass- mudahan melakukan itu, tetapi meskipun ada periode saat itu masih memulai sebelum dapat melakukan itu ketika kata sandi tersedia untuk setiap / setiap proses untuk melihat.
Charles Duffy
1
@ CharlesDuffy Tentu saja, Anda benar. sshpassdigunakan dalam skenario di mana Anda memiliki skrip pengujian sederhana yang dijalankan di lingkungan jaringan lokal di mana keamanan bukanlah perhatian utama. Bahkan, ada bagian di man sshpassmana seluruh bagian tentang Pertimbangan Keamanan dijelaskan. Menambahkan ini sebagai jawaban, Terima kasih.
dotnix
@ erikb85 Biasanya, sebuah paket melakukan semua hal kotor untuk Anda, tetapi, dalam semua kasus, skrip ini dibuat hanya untuk penggunaan itu, maka akan lebih baik daripada menambahkan barang-barang Anda sendiri. Komentar ini tentang jangan menemukan kembali roda. Atasi hal-hal sulit hanya jika belum ada orang yang menanganinya. sshpass itu fungsi yang bagus.
m3nda
2
Untuk kelengkapan, saya menyebutkan bahwa "man sshpass" memberikan peringatan keamanan yang sesuai kepada calon pengguna, menunjukkan bahwa "-p" adalah cara yang paling tidak aman untuk menggunakannya, dan menawarkan opsi "-e" untuk mengambil kata sandi melalui variabel lingkungan , yang setidaknya membuatnya keluar dari baris perintah.
Ron Burk
22

Tambahkan perintah 'berinteraksi' sebelum EOD Anda:

#!/bin/bash

read -s PWD

/usr/bin/expect <<EOD
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com
expect "password"
send "$PWD\n" 
interact
EOD
echo "you're out"

Ini akan memungkinkan Anda berinteraksi dengan mesin jarak jauh sampai Anda keluar. Maka Anda akan kembali di bash.

dr-jan
sumber
Ini masuk dan kembali segera. "Anda keluar" dicetak.
Emmanuel
8
Saya telah mengganti "berinteraksi" dan "EOD" dengan "mengharapkan barang" dan itu berhasil untuk saya. Ini ada di Mac.
Emmanuel
2
Tidak ada jawaban di halaman ini yang berfungsi untuk saya, tetapi saran @ Emmanuel untuk menggunakan expect eofmenyelesaikan masalah.
moertel
Hapus 'dari usr@$myhost.example.com'dan itu akan berhasil. Dan mungkin Anda perlu mengganti \ndengan \r, tapi YMMV
Tino
20

Setelah mencari jawaban untuk pertanyaan selama berbulan-bulan, saya akhirnya menemukan solusi terbaik: menulis naskah sederhana.

#!/usr/bin/expect

set timeout 20

set cmd [lrange $argv 1 end]
set password [lindex $argv 0]

eval spawn $cmd
expect "Password:"
send "$password\r";
interact

Masukkan /usr/bin/exp, lalu Anda dapat menggunakan:

  • exp <password> ssh <anything>
  • exp <password> scp <anysrc> <anydst>

Selesai!

damn_c
sumber
expect "assword:"kau berarti expect "password:"?
pengguna
1
@user "assword"akan cocok dengan keduanya Passworddan password.
Ferdinand.kraft
8

Pastikan juga untuk menggunakan

send -- "$PWD\r" 

sebagai gantinya, karena kata sandi yang dimulai dengan tanda hubung (-) akan gagal jika tidak.

Di atas tidak akan menafsirkan string yang dimulai dengan tanda hubung sebagai opsi untuk perintah kirim.

Timmah
sumber
8

Skrip harapan sederhana

Remotelogin.exp

    #!/usr/bin/expect
    set user [lindex $argv 1]
    set ip [lindex $argv 0]
    set password [lindex $argv 2]
    spawn ssh $user@$ip
    expect "password"
    send "$password\r"
    interact

Contoh:

    ./Remotelogin.exp <ip> <user name> <password>
Vijay SB
sumber
7

Gunakan alat bantu fd0ssh(dari hxtools, bukan pmt), itu berfungsi tanpa harus mengharapkan prompt tertentu dari program ssh.

pengguna562374
sumber
Ini bagus! Agak sulit untuk membuatnya berjalan (setidaknya di server ubuntu) tetapi bekerja dengan lancar! Konfigurasi yang kami buat: echo "yoursshpass" | fd0ssh ssh -c -L$port:$ip:$remote_port [email protected] & Terima kasih!
JP Illanes
1
Jauh lebih aman daripada memasukkan kata sandi pada baris perintah seperti sshpasshalnya.
Charles Duffy
5

Cara lain yang menurut saya berguna untuk menggunakan skrip harapan kecil dari skrip bash adalah sebagai berikut.

...
bash-script start
bash-commands
...
expect - <<EOF 
spawn your-command-here
expect "some-pattern"
send "some-command"
...
...
EOF
...
more bash commands
...

Ini berhasil karena ...If the string "-" is supplied as a filename, standard input is read instead...

Jimbo
sumber
Anda tidak perlu di -sini, karena expectdibaca stdinsecara default jika Anda memintanya tanpa argumen. Namun itu berguna jika Anda ingin menjalankannya secara interaktif tanpa command prompt ( expectvs expect -) atau jika Anda melakukan sesuatu seperti di expect -f "$@"mana argumen pertama akan menjadi file, bahkan jika itu terlihat seperti opsi (dimulai dengan -). Dalam hal ini, jika $1(file yang diberikan) adalah apakah -ini dibaca stdin.
Tino
1

sshpassrusak jika Anda mencoba menggunakannya di dalam target build Sublime Text, di dalam Makefile. Alih-alih sshpassAnda dapat menggunakan passh: https://github.com/clarkwang/passh

Dengan sshpassAnda akan melakukan:

sshpass -p pa$$word ssh user@host

Dengan passhAnda akan melakukan:

passh -p pa$$word ssh user@host

Catatan: Jangan lupa gunakan -o StrictHostKeyChecking=no, kalau tidak koneksi akan hang saat pertama kali Anda menggunakannya. Sebagai contoh:

passh -p pa$$word ssh -o StrictHostKeyChecking=no user@host

Referensi:

  1. Perintah kirim untuk kata sandi tidak berfungsi menggunakan skrip harapan di koneksi ssh
  2. /ubuntu/87449/how-to-disable-strict-host-key-checking-in-ssh
  3. https://linuxcommando.blogspot.com/2008/10/how-to-disable-ssh-host-key-checking.html
  4. /server/330503/scp-without-known-hosts-check
  5. https://debian-administration.org/article/587/pam_mount_and_sshfs_with_password_authentication
pengguna
sumber