スクリプトでSSHパスワードを自動的に入力する


193

OpenSSH sshクライアントにパスワードを自動的に入力するスクリプトを作成する必要があります。

たとえばmyname@somehost、パスワードを使用してSSHでログインする必要があるとしますa1234b

私はすでに試しました...

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

...しかし、これは機能しません。

この機能をスクリプトに組み込むにはどうすればよいですか?

回答:


278

最初にsshpassをインストールする必要があります。

  • Ubuntu / Debian: apt-get install sshpass
  • Fedora / CentOS: yum install sshpass
  • アーチ: pacman -S sshpass

例:

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

カスタムポートの例:

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

ノート:

  • sshpass-fフラグが渡されたときにファイルからパスワードを読み取ることもできます。
    • を使用-fすると、psコマンドが実行されたときにパスワードが表示されなくなります。
    • パスワードが格納されているファイルには、安全なアクセス許可が必要です。

12
これはExpectを使用するよりもはるかに優れています。
Mejdal Rasmussen氏による2013

5
sshpassはのようなコマンドからパスワードをブロックしますps -auxが、同じコンピューター上の他のユーザーはを実行してパスワードを見ることができるため、通常はパスワードを入力してコマンドを実行しないでくださいps -aux。他の回答で述べたように、実用的な場合は、代わりに公開鍵認証を使用することもできます。これにより、スクリプトから認証情報を分離できるため、心配することなくスクリプトを他のユーザーと共有し、後でスクリプトを暗号化せずに〜/ .sshフォルダーで暗号化を有効にすることができます。
Alexander Taylor

2
残念ながら、これはカスタムsshポートを持つサーバーでは機能しません...なぜコマンドラインにパスワードを挿入するオプションをsshで提供できないのですか?
アンディ

2
カスタムポートを機能させるには、コマンドの最後に「-p port-number」を追加します
Ye Lwin Soe


95

数か月間の質問の答えを探した後、私はようやくより良い解決策を見つけました。簡単なスクリプトを書くことです。

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

それを/usr/bin/expに置くと、次のように使用できます。

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

できた!


2
この答えはもっと多くの票を獲得するはずです。それは素晴らしいラッパーです。さまざまなフラグを使用したrsyncやリモートコマンドの実行など、いくつかの一般的な操作を試してみましたが、常に機能しました。便利なスクリプトのツールボックスに追加されました。ありがとう@damn_c!
user2082382 2016年

7
多分人々はそれを期待していなかったので、それはより多くの賛成を得ていませんか?
クリアライト2017年

7
IMOがあまり良い答えではない理由は、パスワードがスクリプトで書かれているためです。これは、安全性が最も低い方法です
。–

8
パスワードは、マシンでpsを実行するすべてのユーザーが見ることができます。
Daniel Persson 2017年


71

公開鍵認証を使用:https : //help.ubuntu.com/community/SSH/OpenSSH/Keys

ソースホストでこれを1回だけ実行します。

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

以上で、パスワードなしでsshを実行できるようになります。


21
そうですか。しかし、私はパスワードでsshする必要があります。これは、 "I"はサムドライブにスクリプトがあり、任意のコンピューターから実行する必要があるためです。パスワードの必要性を無効にしません。
user1467855 2012

3
@ user1467855、私はあなたがあなたの要件をよりよく説明する必要があると思います。安全でないネットワークがあることを示唆している人はいません。公開鍵アプローチでは、ユーザーがパスワードを使用してログインすることは依然として可能です。ただし、秘密鍵をサムドライブにコピーします。つまり、サムドライブはパスワードなしでログインできる唯一のものになります。
アーロンマクデイド

5
残念ながら、sysadminはrsa / dsaキーによる認証を許可せず、パスワードを必要とするため、私はOPの状況にあります。きみはどうする。
カレルは、Bilek

26
これは、質問された実際の質問に答えようとしないため、反対票を投じました。
パルティアンショット

2
これはまだ最初のログインを要求し、スクリプトでは使用できません!
Mehrdad Mirreza

29

expectsスクリプトを使用できます。しばらくは書いていませんが、以下のようになります。あなたはスクリプトを頭に置く必要があります#!/usr/bin/expect

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

私はあなたが提案したとおりにしましたが、次のエラーが発生します:/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

私の答えを正しいものに修正してくれたアーロンに感謝します。以下のコマンドを実行して、予期したとおりに配置する正しいパスを見つける必要がある場合があります。which expect
Lipongo 2012

1
また、このシェバング行を使用することができます:#!/usr/bin/env expect
グレンはジャックマン

1
interact最後に追加したので、sshセッションは実際にインタラクティブです
KarelBílek13年

-1は、スクリプトにプレーンテキストのパスワードを保持するという大きなセキュリティリスクをもたらします。
アーロンディグラ2013年

21

バリアントI

sshpass -p PASSWORD ssh USER@SERVER

バリアントII

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

-pフラグは、ポート番号を指定するためのものです。
Kookerus、2015年

4
いいえ。sshpassはsshではありません。 SYNOPSIS sshpass [-ffilename|-dnum|-ppassword|-e] [options] command arguments
RemiZOffAlex

Linux CentOSでsshpassを実行するにはyum -y install epel-release、次のことが必要ですyum -y install sshpass
JuniorMayhéSep

このデータのこのコンテキストでは無視できます
RemiZOffAlex

私はこれが古い投稿であることを知っていますが、Variant IIメソッドがセッションに与えられたパスワードをbash履歴の脆弱なままにしておくことは非常に勧められないことに注意する価値があります。
カークランド

10

sshpass + autossh

すでに述べた素晴らしいsshpass利点の1つは、で使用できることですautossh。これにより、インタラクティブな非効率性がさらに排除されます。

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

これにより、たとえばラップトップを閉じることによってWi-Fiが中断された場合に自動再接続が可能になります。


2
あなたはオプションを追加することはできません-fので、この組み合わせでautosshにwhen used with autossh, ssh will be *unable* to ask for passwords or passphrases. harding.motd.ca/autossh/README.txtはまたsuperuser.com/questions/1278583/...
allenyllee

9

sshpass より良いセキュリティで

行き詰まったサーバーにSSHで接続する方法を探しているときに、このスレッドを見つけました。SSH接続の試行を処理するのに1分以上かかり、パスワードを入力する前にタイムアウトしました。この場合、プロンプトが表示されたらすぐにパスワードを入力できるようにしたいと考えました。

(そしてそれがはっきりと明確でない場合:この状態のサーバーでは、公開鍵ログインを設定するには遅すぎます。)

sshpass救助へ。ただし、これを行うには、より良い方法があります。sshpass -pます。

私の実装では、対話型のパスワードプロンプトに直接スキップし(公開キーの交換が発生するかどうかを確認するのに時間を無駄にしていません)、パスワードをプレーンテキストとして公開することはありません。

#!/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
自己注意:trapctrl-CがSSHPASS変数をリークするのを防ぐために使用するスクリプトを更新
Ian

1
私はそれPreferredAuthentications=keyboard-interactiveがうまくいかないことを発見しました、しかしそれを取り替えることはうまくいきましたPreferredAuthentications=password
マイクパートリッジ

7

これが私のサーバーへのログイン方法です。

ssp <server_ip>
  • エイリアスssp = '/ home / myuser / Documents / ssh_script.sh'
  • cat /home/myuser/Documents/ssh_script.sh

#!/ bin / bash

sshpass -p mypassword ssh root @ $ 1

したがって...

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

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


3
この記事はただ皮肉なことだと思います!
Yan Foto 2016年

5

だれかがこれを提案しているのを見たとは思いません。OPは「スクリプト」とだけ言ったので...

私は同じ問題を解決する必要があり、私の最も快適な言語はPythonです。

paramikoライブラリを使用しました。さらに、を使用して権限をエスカレートする必要があるコマンドを発行する必要もありましたsudo。sudoが「-S」フラグを介してstdin経由でパスワードを受け入れることができることがわかりました!下記参照:

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

これが誰かを助けることを願っています。私の使用例は、ディレクトリの作成、ファイルの送信と展開、および最大300台のサーバーでのプログラムの起動でした。そのため、自動化が最も重要でした。、を試してsshpassからexpect、これを思いつきました。


2

私はこれを次のように機能させました

.ssh / configはyes / noプロンプトを排除するように変更されました-私はファイアウォールの背後にいるので、なりすましのsshキーについて心配していません

host *
     StrictHostKeyChecking no

expectの応答ファイル、つまり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

bashスクリプトを作成し、ファイルでexpectを呼び出すだけです

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

  expect answer.expect hadoopslave$i

  i=[$i + 1]
  sleep 5

done

新しい構成で更新された128個のhadoopデータノードを取得します-hadoop / confファイルにNFSマウントを使用していると想定します

これが誰かを助けてくれることを願っています-私はWindowsがとても好きで、これを理解するのに約5時間かかりました!


「私はファイアウォールの背後にいるので、なりすましのsshキーについて心配していません」。この場合、ファイアウォールはまったく何もしません。HostKeyCheckを使用すると、相手側のホストがトロイの木馬ホストでないことを確認できます。つまり、接続したい場所にいるふりをしているだけです。不明なホストに接続し、資格情報やトークンを含むファイルを作成したり、パスワードを入力したりするなど、機密情報を扱う場合、その情報は事実上公開されています。ファイアウォールの内側にいることは無関係です。
JCGB





0

以下の例では、使用したソリューションを記述します。

シナリオ: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

このスクリプトをスクリプト内で使用するには、最初の引数がホスト名で、2番目がパスワードになります。

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

これは既存の回答の上に何を示していますか?特にdamn_c、Lipongo、RemiZOffAlexなどによるもの
Martin Prikryl

スクリプトの実行とssh#!/ usr / bin / expect set pass [lindex $ argv 1] set host [lindex $ argv 0] spawn ssh -t root @ $ host sh /tmp/anyscript.sh expect "* assword:" "$ pass \ n"を送信します。対話する」
Shivam Mehrotra

-3

シェルスクリプトを介してリモートマシンに接続するには、以下のコマンドを使用します。

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

ここでIPADDRESSUSERNAMEおよびPASSWORDは、スクリプトで提供する必要がある入力値、または実行時に提供したい場合は、「読み取り」コマンドを使用します。


5
この回答は既存の回答の上に何を示していますか?+ StrictHostKeyChecking=no結果を説明せずに使用するように誰かに提案することは決してしないでください。
Martin Prikryl 2017

-5
sudo ssh username@server_ip_address -p port_number

Enterキーを押してからシステムのパスワードを入力し、最後にサーバーのパスワードを入力します

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.