Secara otomatis memasukkan kata sandi SSH dengan skrip


193

Saya perlu membuat skrip yang secara otomatis memasukkan kata sandi ke sshklien OpenSSH .

Katakanlah saya perlu SSH myname@somehostmenggunakan kata sandi a1234b.

Saya sudah mencoba ...

#~/bin/myssh.sh
ssh myname@somehost
a1234b

... tapi ini tidak berhasil.

Bagaimana saya bisa mendapatkan fungsi ini menjadi skrip?

Jawaban:


278

Pertama, Anda perlu menginstal sshpass .

  • Ubuntu / Debian: apt-get install sshpass
  • Fedora / CentOS: yum install sshpass
  • Lengkungan: pacman -S sshpass

Contoh:

sshpass -p "YOUR_PASSWORD" ssh -o StrictHostKeyChecking=no YOUR_USERNAME@SOME_SITE.COM

Contoh port khusus:

sshpass -p "YOUR_PASSWORD" ssh -o StrictHostKeyChecking=no YOUR_USERNAME@SOME_SITE.COM:2400

Catatan:

  • sshpassjuga dapat membaca kata sandi dari file ketika -fflag dilewatkan.
    • Penggunaan -fmencegah kata sandi tidak terlihat jika psperintah dijalankan.
    • File tempat kata sandi disimpan harus memiliki izin aman.

12
Ini jauh lebih baik daripada menggunakan Harapkan.
Per Mejdal Rasmussen

5
hanya perlu diketahui bahwa ketika sshpass memblokir kata sandi Anda dari perintah seperti ps -aux, Anda seharusnya tidak menjalankan perintah dengan mengetik kata sandi Anda karena pengguna lain di komputer yang sama mungkin dapat melihat kata sandi dengan menjalankannya ps -aux. jika praktis, Anda juga ingin menggunakan otentikasi kunci publik, seperti yang disebutkan dalam jawaban lain. ini memungkinkan Anda untuk memisahkan informasi otentikasi dari skrip Anda sehingga Anda dapat membagikan skrip Anda dengan orang lain tanpa khawatir, dan kemudian memutuskan untuk mengaktifkan enkripsi pada folder ~ / .ssh Anda tanpa juga mengenkripsi skrip Anda.
Alexander Taylor

2
Sayangnya ini tidak berfungsi untuk saya di server dengan port ssh khusus ... mengapa ssh tidak bisa memberi kami opsi untuk memasukkan kata sandi di baris perintah?
Andy

2
agar port kustom berfungsi tambahkan "-p port-number" di akhir perintah
Ye Lwin Soe


95

Setelah mencari jawaban untuk pertanyaan itu selama berbulan-bulan, saya akhirnya menemukan solusi yang lebih baik: menulis naskah sederhana.

#!/usr/bin/expect

set timeout 20

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

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

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

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

Selesai!


2
Jawaban ini harus mendapatkan lebih banyak suara, itu adalah bungkus yang bagus. Hanya mencoba beberapa operasi umum seperti rsyncing dengan berbagai flag dan eksekusi perintah jarak jauh dan itu berfungsi setiap saat. Ditambahkan ke kotak alat saya dari skrip yang berguna, Terima kasih @damn_c!
user2082382

7
Mungkin itu tidak mendapatkan lebih banyak suara karena orang tidak mengharapkannya?
clearlight

7
Alasan mengapa ini adalah IMO bukan jawaban yang sangat baik adalah karena kata sandi ditulis dalam skrip yang sejauh ini merupakan metode yang paling tidak aman ...
PierreE

8
Kata sandi akan terlihat oleh siapa saja yang menjalankan ps pada mesin.
Daniel Persson


71

Gunakan otentikasi kunci publik: https://help.ubuntu.com/community/SSH/OpenSSH/Keys

Di host sumber jalankan ini hanya sekali:

ssh-keygen -t rsa # ENTER to every field
ssh-copy-id myname@somehost

Itu saja, setelah itu Anda akan dapat melakukan ssh tanpa kata sandi.


21
Saya melihat. Tapi saya DIBUTUHKAN untuk ssh dengan kata sandi. Ini karena, "Saya" mungkin memiliki skrip pada thumb drive dan perlu menjalankannya dari komputer apa pun; sementara tidak menonaktifkan kebutuhan untuk kata sandi.
user1467855

3
@ user1467855, saya pikir Anda perlu lebih menjelaskan kebutuhan Anda. Tidak ada yang menyarankan Anda memiliki jaringan tidak aman. Dalam pendekatan kunci publik, masih mungkin bagi pengguna untuk masuk dengan kata sandi. Tetapi Anda akan menyalin kunci pribadi ke thumb drive Anda, yang berarti thumb drive akan menjadi satu-satunya hal yang dapat masuk tanpa kata sandi.
Aaron McDaid

5
Sayangnya, saya dalam situasi OP, karena sysadmin melarang otentikasi oleh kunci rsa / dsa dan memerlukan passwor. Apa yang akan kamu lakukan.
Karel Bílek

26
Diturunkan karena ini bahkan tidak mencoba menjawab pertanyaan aktual yang diajukan.
Parthian Shot

2
Ini masih meminta login pertama dan tidak dapat digunakan dalam skrip!
Mehrdad Mirreza

29

Anda dapat menggunakan skrip yang diharapkan. Saya belum menulis satu dalam beberapa waktu tetapi akan terlihat seperti di bawah ini. Anda harus memimpin skrip dengan#!/usr/bin/expect

#!/usr/bin/expect -f
spawn ssh HOSTNAME
expect "login:" 
send "username\r"
expect "Password:"
send "password\r"
interact

Saya melakukan seperti yang Anda sarankan tetapi mendapatkan kesalahan berikut:/bin/myssh.sh: 2: spawn: not found /bin/myssh.sh: 3: expect: not found /bin/myssh.sh: 4: send: not found /bin/myssh.sh: 5: expect: not found /bin/myssh.sh: 6: send: not found
user1467855

Terima kasih Aaron untuk memodifikasi jawaban saya menjadi benar. Anda mungkin perlu menjalankan perintah di bawah ini untuk menemukan jalur yang benar untuk diharapkan. which expect
Lipongo

1
Anda juga dapat menggunakan baris shebang ini:#!/usr/bin/env expect
glenn jackman

1
Saya menambahkan interactsampai akhir sehingga sesi ssh benar-benar interaktif
Karel Bílek

-1 untuk risiko keamanan yang sangat besar karena menyimpan kata sandi teks biasa dalam skrip.
Aaron Digulla

21

Varian I

sshpass -p PASSWORD ssh USER@SERVER

Varian II

#!/usr/bin/expect -f
spawn ssh USERNAME@SERVER "touch /home/user/ssh_example"
expect "assword:"
send "PASSWORD\r"
interact

The -pbendera untuk menentukan nomor port.
Kookerus

4
Tidak. Sshpass bukan ssh. SYNOPSIS sshpass [-ffilename|-dnum|-ppassword|-e] [options] command arguments
RemiZOffAlex

Untuk menjalankan sshpass di Linux CentOS Anda harus yum -y install epel-releasedan kemudianyum -y install sshpass
Junior Mayhé

Dalam konteks ini, data ini dapat diabaikan
RemiZOffAlex

Meskipun saya tahu ini adalah posting lama, perlu dicatat bahwa metode Varian II akan meninggalkan kata sandi yang diberikan kepada sesi yang rentan dalam sejarah bash, membuatnya sangat tidak disarankan.
Kirkland

10

sshpass + autossh

Satu bonus bagus dari yang telah disebutkan sshpassadalah bahwa Anda dapat menggunakannya dengan autossh, menghilangkan lebih banyak lagi inefisiensi interaktif.

sshpass -p mypassword autossh -M0 -t myusername@myserver.mydomain.com

Ini akan memungkinkan koneksi otomatis jika, misalnya wifi Anda terganggu dengan menutup laptop Anda.


2
Perhatikan bahwa Anda tidak dapat menambahkan opsi -fke autossh dalam kombinasi ini, karena when used with autossh, ssh will be *unable* to ask for passwords or passphrases. harding.motd.ca/autossh/README.txt juga superuser.com/questions/1278583/…
allenyllee

9

sshpass dengan keamanan yang lebih baik

Saya tersandung di utas ini sambil mencari cara untuk ssh ke server macet - butuh waktu satu menit untuk memproses upaya koneksi SSH, dan kehabisan waktu sebelum saya bisa memasukkan kata sandi. Dalam hal ini, saya ingin dapat memberikan kata sandi saya segera ketika prompt tersedia.

(Dan jika tidak jelas jelas: dengan server di negara ini, sudah terlambat untuk membuat login kunci publik.)

sshpassuntuk menyelamatkan. Namun, ada cara yang lebih baik untuk melakukannya sshpass -p.

Implementasi saya melompat langsung ke prompt kata sandi interaktif (tidak ada waktu yang terbuang untuk melihat apakah pertukaran kunci publik dapat terjadi), dan tidak pernah mengungkapkan kata sandi sebagai teks biasa.

#!/bin/sh
# preempt-ssh.sh
# usage: same arguments that you'd pass to ssh normally
echo "You're going to run (with our additions) ssh $@"

# Read password interactively and save it to the environment
read -s -p "Password to use: " SSHPASS 
export SSHPASS

# have sshpass load the password from the environment, and skip public key auth
# all other args come directly from the input
sshpass -e ssh -o PreferredAuthentications=keyboard-interactive -o PubkeyAuthentication=no "$@"

# clear the exported variable containing the password
unset SSHPASS

1
note to self: perbarui skrip yang digunakan trapuntuk mencegah ctrl-C bocor SSHPASSvariabel
Ian

1
Saya menemukan itu PreferredAuthentications=keyboard-interactivetidak berhasil, tetapi menggantinya dengan PreferredAuthentications=passwordbekerja.
Mike Partridge

7

Ini adalah bagaimana saya masuk ke server saya.

ssp <server_ip>
  • alias ssp = '/ home / myuser / Documents / ssh_script.sh'
  • cat /home/myuser/Documents/ssh_script.sh

#! / bin / bash

sshpass -p mypassword ssh root @ $ 1

Dan oleh karena itu...

ssp server_ip

5
# create a file that echo's out your password .. you may need to get crazy with escape chars or for extra credit put ASCII in your password...
echo "echo YerPasswordhere" > /tmp/1
chmod 777 /tmp/1

# sets some vars for ssh to play nice with something to do with GUI but here we are using it to pass creds.
export SSH_ASKPASS="/tmp/1"
export DISPLAY=YOURDOINGITWRONG
setsid ssh root@owned.com -p 22

referensi: https://www.linkedin.com/pulse/youre-doing-wrong-ssh-plain-text-credentials-robert-mccurdy?trk=mp-reader-card


3
Saya pikir artikel ini hanya sarkastik!
Yan Foto

5

Saya tidak berpikir saya melihat ada yang menyarankan ini dan OP hanya mengatakan "skrip" jadi ...

Saya perlu menyelesaikan masalah yang sama dan bahasa saya yang paling nyaman adalah Python.

Saya menggunakan perpustakaan paramiko. Selain itu, saya juga perlu mengeluarkan perintah yang saya perlukan izin meningkat menggunakan sudo. Ternyata sudo dapat menerima kata sandi melalui stdin melalui bendera "-S"! Lihat di bawah:

import paramiko

ssh_client = paramiko.SSHClient()

# To avoid an "unknown hosts" error. Solve this differently if you must...
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# This mechanism uses a private key.
pkey = paramiko.RSAKey.from_private_key_file(PKEY_PATH)

# This mechanism uses a password.
# Get it from cli args or a file or hard code it, whatever works best for you
password = "password"

ssh_client.connect(hostname="my.host.name.com",
                       username="username",
                       # Uncomment one of the following...
                       # password=password
                       # pkey=pkey
                       )

# do something restricted
# If you don't need escalated permissions, omit everything before "mkdir"
command = "echo {} | sudo -S mkdir /var/log/test_dir 2>/dev/null".format(password)

# In order to inspect the exit code
# you need go under paramiko's hood a bit
# rather than just using "ssh_client.exec_command()"
chan = ssh_client.get_transport().open_session()
chan.exec_command(command)

exit_status = chan.recv_exit_status()

if exit_status != 0:
    stderr = chan.recv_stderr(5000)

# Note that sudo's "-S" flag will send the password prompt to stderr
# so you will see that string here too, as well as the actual error.
# It was because of this behavior that we needed access to the exit code
# to assert success.

    logger.error("Uh oh")
    logger.error(stderr)
else:
    logger.info("Successful!")

Semoga ini bisa membantu seseorang. Kasus penggunaan saya adalah membuat direktori, mengirim dan menghapus file dan memulai program pada ~ 300 server sekaligus. Karena itu, otomatisasi adalah yang terpenting. Saya mencoba sshpass,, expectdan kemudian datang dengan ini.


2

Saya mendapatkan ini berfungsi sebagai berikut

.ssh / config telah dimodifikasi untuk menghilangkan prompt ya / tidak - saya berada di belakang firewall jadi saya tidak khawatir tentang kunci ssh palsu

host *
     StrictHostKeyChecking no

Buat file tanggapan untuk harapan yaitu answer.expect

set timeout 20
set node [lindex $argv 0]
spawn ssh root@node service hadoop-hdfs-datanode restart

expect  "*?assword {
      send "password\r"   <- your password here.

interact

Buat skrip bash Anda dan panggil saja harapan dalam file

#!/bin/bash
i=1
while [$i -lt 129]    # a few nodes here

  expect answer.expect hadoopslave$i

  i=[$i + 1]
  sleep 5

done

Dapatkan 128 hadoop datanodes yang disegarkan dengan konfigurasi baru - dengan asumsi Anda menggunakan NFS mount untuk file hadoop / conf

Semoga ini bisa membantu seseorang - Saya seorang Windows numpty dan ini membutuhkan waktu sekitar 5 jam untuk mencari tahu!


"Saya di belakang firewall jadi saya tidak khawatir tentang kunci ssh palsu". Firewall tidak melakukan apa pun dalam kasus ini. HostKeyCheck adalah agar Anda dapat memverifikasi host di ujung lain bukan Host trojan. Yaitu yang hanya berpura-pura berada di tempat yang ingin Anda sambungkan. Jika Anda terhubung ke host yang tidak dikenal, dan melakukan sesuatu yang sensitif, seperti menulis file yang memiliki kredensial atau token atau memasukkan kata sandi, informasi itu sekarang menjadi pengetahuan publik yang efektif. Anda berada di belakang firewall tidak relevan.
JCGB

2

Jika Anda melakukan ini pada sistem Windows, Anda dapat menggunakan Plink (bagian dari Putty).

plink your_username@yourhost -pw your_password



1

Saya berhasil membuatnya bekerja dengan itu:

SSH_ASKPASS="echo \"my-pass-here\""
ssh -tt remotehost -l myusername

0

Dalam contoh di bawah ini saya akan menulis solusi yang saya gunakan:

Skenario: Saya ingin menyalin file dari server menggunakan skrip sh:

#!/usr/bin/expect
$PASSWORD=password
my_script=$(expect -c "spawn scp userName@server-name:path/file.txt /home/Amine/Bureau/trash/test/
expect \"password:\"
send \"$PASSWORD\r\"
expect \"#\"
send \"exit \r\"
")

echo "$my_script"

-2

Gunakan skrip ini tossh di dalam skrip, Argumen pertama adalah nama host dan yang kedua adalah kata sandi.

#!/usr/bin/expect
set pass [lindex $argv 1]
set host [lindex $argv 0]
spawn ssh -t root@$host echo Hello
expect "*assword: " 
send "$pass\n";
interact"

Apa yang ditampilkan di atas jawaban yang ada? Terutama yang oleh damn_c, Lipongo atau RemiZOffAlex dan lainnya ...
Martin Prikryl

eksekusi skrip bersama dengan ssh #! / usr / bin / harapkan set pass [lindex $ argv 1] set host [lindex $ argv 0] spawn ssh -t root @ $ host sh /tmp/anyscript.sh harapkan "* assword:" kirim "$ pass \ n"; berinteraksi "
Shivam Mehrotra

-3

Untuk menghubungkan mesin jarak jauh melalui skrip shell, gunakan perintah di bawah ini:

sshpass -p PASSWORD ssh -o StrictHostKeyChecking=no USERNAME@IPADDRESS

di mana IPADDRESS, USERNAMEdan PASSWORDmerupakan nilai input yang perlu disediakan dalam skrip, atau jika kita ingin memberikan dalam runtime gunakan perintah "baca".


5
Apa yang ditunjukkan oleh jawaban ini di atas jawaban yang ada? + Jangan pernah menyarankan siapa pun untuk menggunakan StrictHostKeyChecking=notanpa menjelaskan konsekuensinya.
Martin Prikryl

-5
sudo ssh username@server_ip_address -p port_number

tekan tombol enter dan kemudian masukkan kata sandi sistem Anda dan akhirnya masukkan kata sandi server Anda

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.