Komut dosyası ile otomatik olarak SSH şifresi girin


194

Otomatik olarak OpenSSH sshistemcisi için bir parola girilen bir komut dosyası oluşturmanız gerekir .

Diyelim ki myname@somehostşifreyle SSH'ye ihtiyacım var a1234b.

Zaten denedim ...

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

... ama bu işe yaramıyor.

Bu işlevi bir betik haline nasıl getirebilirim?

Yanıtlar:


278

İlk önce sshpass kurmanız gerekiyor .

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

Misal:

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

Özel bağlantı noktası örneği:

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

Notlar:

  • sshpassayrıca -fbayrak iletildiğinde bir dosyadan şifre de okuyabilir .
    • Kullanılması -f, pskomut yürütüldüğünde parolanın görünmesini engeller .
    • Parolanın saklandığı dosyanın güvenli izinleri olmalıdır.

12
Bu, Expect kullanmaktan çok daha iyi.
Per Mejdal Rasmussen

5
sadece sshpass parolanızı gibi komutlardan engellerken, ps -auxnormalde parolanızı yazarak komutları çalıştırmamanız gerektiğini unutmayın, çünkü aynı bilgisayardaki diğer kullanıcılar parolayı çalıştırabilirler ps -aux. pratik ise diğer yanıtta belirtildiği gibi genel anahtar kimlik doğrulamasını da kullanmak istersiniz. bu, kimlik doğrulama bilgilerini komut dosyanızdan ayırmanıza olanak tanır, böylece komut dosyanızı endişelenmeden başkalarıyla paylaşabilirsiniz ve daha sonra komut dosyanızı şifrelemeden ~ / .ssh klasörünüzde şifrelemeyi etkinleştirmeye karar verebilirsiniz.
Alexander Taylor

2
Ne yazık ki bu benim için özel bir ssh portuna sahip bir sunucuda çalışmıyor ... neden ssh bize şifreyi komut satırına ekleme seçeneğini veremiyor?
Andy

2
özel bağlantı noktasının çalışması için komutun sonuna "-p bağlantı noktası numarası" ekleyin
Ye Lwin Soe


96

Aylarca soruya cevap aradıktan sonra, sonunda daha iyi bir çözüm buldum: basit bir senaryo yazmak.

#!/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

Koy /usr/bin/exp, o zaman kullanabilirsiniz:

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

Bitti!


2
Bu cevap imo daha fazla oy almak gerekir, bu harika bir sarıcı. Sadece çeşitli bayraklar ve uzaktan komut yürütme ile rsyncing gibi birkaç yaygın işlemi denedim ve her seferinde çalıştı. Yararlı komut dosyaları araç kutusuna eklendi, Thanks @damn_c!
user2082382

7
Belki daha fazla oy almamıştır çünkü insanlar bunu beklemiyordu?
Clearlight

7
Bunun IMO'nun çok iyi bir cevap olmaması nedeni, şifrenin en az güvenli yöntem olan
kodda yazılmasıdır

8
Parola, makinede ps çalıştıran herkes tarafından görülebilir.
Daniel Persson


71

Ortak anahtar kimlik doğrulamasını kullanın: https://help.ubuntu.com/community/SSH/OpenSSH/Keys

Kaynak ana bilgisayarda bunu yalnızca bir kez çalıştırın:

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

Hepsi bu, bundan sonra şifre olmadan ssh yapabileceksiniz.


21
Anlıyorum. Ama şifre ile ssh GEREKİR. Bunun nedeni, "Ben" komut dosyasının bir başparmak sürücüsünde olması ve herhangi bir bilgisayardan çalıştırması gerektiğidir; şifre ihtiyacını devre dışı bırakmaz.
user1467855

3
@ user1467855, ihtiyaçlarınızı daha iyi açıklamanız gerektiğini düşünüyorum. Kimse güvenli olmayan bir ağınız olduğunu önermiyor. Açık anahtar yaklaşımında, kullanıcıların parola ile oturum açması yine de mümkün olacaktır. Ancak özel anahtarı parmak sürücünüze kopyalarsınız, yani parmak sürücüsü parola olmadan giriş yapabilen tek şey olacaktır.
Aaron McDaid

5
Ne yazık ki, OP durumundayım, çünkü sysadmin, rsa / dsa anahtarları ile kimlik doğrulamasına izin vermez ve parola gerektirir. Ne yapacaksın.
Karel Bílek

27
Bu, sorulan asıl soruya cevap vermeye çalışmadığı için indirildi.
Part Atışı

2
Bu yine de ilk giriş yapılmasını ister ve bir komut dosyasında kullanılamaz!
Mehrdad Mirreza

29

Bir beklenti komut dosyası kullanabilirsiniz. Bir süredir yazmadım ama aşağıdaki gibi olmalı. Senaryo ile başa ihtiyacınız olacak#!/usr/bin/expect

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

Önerdiğin gibi yaptım ama aşağıdaki hataları /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
alıyorum

Cevabımı doğru olacak şekilde değiştirdiği için Aaron'a teşekkür ederim. Beklemeye alınacak doğru yolu bulmak için aşağıdaki komutu çalıştırmanız gerekebilir. which expect
Lipongo

1
Ayrıca bu shebang hattı kullanabilirsiniz:#!/usr/bin/env expect
glenn jackman

1
Ben interactssh oturumu aslında interaktif olması için sonuna ekledim
Karel Bílek

Komut dosyasında düz metin parola tutmanın büyük güvenlik riski için -1.
Aaron Digulla

21

Değişke I

sshpass -p PASSWORD ssh USER@SERVER

Değişke II

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

-pBayrak bir port numarasını belirtmek içindir.
Kookerus

4
Hayır. Sshpass ssh değil. SYNOPSIS sshpass [-ffilename|-dnum|-ppassword|-e] [options] command arguments
RemiZOffAlex

Linux CentOS yapmalısınız içinde sshpass çalıştırmak için yum -y install epel-releasedaha sonra veyum -y install sshpass
Genç mayhe

Bu bağlamda bu veriler göz ardı edilebilir
RemiZOffAlex

Bu eski bir yazı olduğunu bilsem de, Variant II yönteminin oturuma verilen şifreyi bash tarihinde savunmasız bırakacağını ve oldukça tavsiye edilemez hale getirdiğini belirtmek gerekir.
Kirkland

11

sshpass + autossh

Daha önce bahsedilen güzel bir bonus, sshpassonu kullanarak kullanabilmeniz autosshve etkileşimli verimsizliğin daha da ortadan kaldırılmasıdır.

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

Bu, örneğin wifi'niz dizüstü bilgisayarınızı kapatarak kesilirse otomatik yeniden bağlanmaya izin verir.


2
-fBu kombinasyonda autossh'a seçenek ekleyemeyeceğinizi unutmayın , çünkü when used with autossh, ssh will be *unable* to ask for passwords or passphrases. harding.motd.ca/autossh/README.txt ayrıca superuser.com/questions/1278583/…
allenyllee

9

sshpass daha iyi güvenlikle

Bir yırtık aşağı sunucuya ssh için bir yol ararken bu iş parçacığı üzerinde tökezledi - SSH bağlantı girişimi işlemek için bir dakika sürdü ve bir şifre girmeden önce zaman aşımına uğradı. Bu durumda, komut istemi hazır olduğunda hemen şifremi girebilmek istedim .

(Acı vermezse: bu durumdaki bir sunucudayken, ortak anahtarla oturum açmak için çok geç.)

sshpasskurtarmak için. Ancak, bununla ilgili daha iyi yollar var sshpass -p.

Uygulamam doğrudan etkileşimli parola istemine atlar (genel anahtar değişiminin gerçekleşip gerçekleşemeyeceğini görmek için zaman kaybı olmaz) ve parolayı hiçbir zaman düz metin olarak göstermez.

#!/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
Kendine not: trapctrl-C SSHPASSdeğişkenini sızdırmasını önlemek için kullanılacak komut dosyasını güncelleme
Ian

1
Bunun PreferredAuthentications=keyboard-interactiveişe yaramadığını fark ettim , ama onun yerine PreferredAuthentications=passwordçalıştı.
Mike Partridge

8

Sunucularıma bu şekilde giriş yaparım.

ssp <server_ip>
  • takma ad ssp = '/ home / myuser / Belgeler / ssh_script.sh'
  • cat /home/myuser/Documents/ssh_script.sh

#! / Bin / bash

sshpass -p mypassword ssh kökü @ $ 1

Ve bu nedenle...

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

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


3
Bence bu makale sadece alaycı!
Yan Foto

5

Ben kimse bunu önermek gördüm sanmıyorum ve OP sadece "script" dedi yani ...

Aynı sorunu çözmem gerekiyordu ve en rahat dilim Python.

Paramiko kütüphanesini kullandım. Ayrıca, kullanarak yükseltilmiş izinlere ihtiyaç duyacağım komutları yayınlamam gerekiyordu sudo. Bu sudo "-S" bayrağı ile stdin üzerinden şifresini kabul edebilir çıkıyor! Aşağıya bakınız:

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!")

Umarım bu birine yardımcı olur. Benim kullanım durumum dizin oluşturmak, dosyaları göndermek ve yıldızlarını kaldırmak ve zamanla ~ 300 sunucularda program başlatmaktı. Bu nedenle, otomasyon çok önemliydi. Denedim sshpass, expectve sonra bunu buldum .


2

Bu işi şu şekilde aldım

.ssh / config, evet / hayır istemini ortadan kaldırmak için değiştirildi - Bir güvenlik duvarının arkasındayım, bu yüzden sahte ssh anahtarları hakkında endişelenmiyorum

host *
     StrictHostKeyChecking no

Answer.expect beklentisi için bir yanıt dosyası oluşturun

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

Bh betiğinizi oluşturun ve dosyada beklemek çağırın

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

  expect answer.expect hadoopslave$i

  i=[$i + 1]
  sleep 5

done

Yeni yapılandırmayla yenilenen 128 hadoop veriyi alır - hadoop / conf dosyaları için bir NFS montajı kullandığınızı varsayar

Umarım bu birine yardımcı olur - Ben bir Windows numpty ve bu benim anlamak için yaklaşık 5 saat sürdü!


"Bir güvenlik duvarının arkasındayım, bu yüzden sahte ssh anahtarları için endişelenmiyorum". Bir güvenlik duvarı bu durumda hiçbir şey yapmaz. HostKeyCheck öylesine sen-ebilmek doğrulamak ana tarafta diğer bir truva atı doğru olmadığını doğrulamak. Yani bağlanmak istediğiniz yerde gibi davranan biri. Bilinmeyen bir ana bilgisayara bağlanır ve kimlik bilgileri veya bir belirteç içeren bir dosya yazmak veya bir parola girmek gibi hassas bir şey yaparsanız, bu bilgiler artık etkin bir şekilde kamunun bilgisidir. Bir güvenlik duvarının arkasında olmanız önemsizdir.
JCGB

2

Bunu bir Windows sisteminde yapıyorsanız, Plink'i (PuTTY'nin bir parçası) kullanabilirsiniz.

plink your_username@yourhost -pw your_password



1

Ben bununla çalışmayı başardı:

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

0

Aşağıdaki örnekte kullandığım çözümü yazacağım:

Senaryo: sh komut dosyasını kullanarak bir sunucudan dosya kopyalamak istiyorum:

#!/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

Bu komut dosyasını komut dosyası içinde tossh kullanın, İlk argüman ana bilgisayar adı ve ikincisi parola olacaktır.

#!/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"

Bu mevcut cevapların üstünde ne gösteriyor? Özellikle damn_c, Lipongo veya RemiZOffAlex ve diğerleri tarafından olanlar ...
Martin Prikryl

ssh #! / usr / bin / wait set pass ile birlikte script yürütme [lindex $ argv 1] set host [lindex $ argv 0] spawn ssh -t root @ $ host sh /tmp/anyscript.sh bekliyoruz "* assword:" "$ pass \ n" gönder; etkileşim "
Shivam Mehrotra

-3

Uzak makineyi kabuk komut dosyalarıyla bağlamak için aşağıdaki komutu kullanın:

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

nerede IPADDRESS, USERNAMEve PASSWORDkomut vermeniz gerekecektir girdi değerlerdir, yoksa çalışma zamanı kullanımda sağlamak istiyorsanız komutu "okuma".


5
Bu cevap mevcut cevapların üstünde ne gösteriyor? + Asla kimsenin StrictHostKeyChecking=nosonuçlarını açıklamadan kullanmasını önermeyin .
Martin Prikryl

-5
sudo ssh username@server_ip_address -p port_number

enter tuşuna basın ve ardından sisteminizin şifresini girin ve son olarak sunucu şifrenizi girin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.