SSHコマンドにパスワードを提供するには、bashスクリプトでexpectを使用します


131

SSHキーを使用する必要があると返信したい場合は、ご遠慮ください。

SSHパスワードを提供するために、bashスクリプトでexpectを使用しようとしています。パスワードを指定しても機能しますが、SSHセッションで必要な結果が得られないため、bashに戻ります。

私のスクリプト:

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

私のスクリプトの出力:

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

SSHセッションを開始したいのですが、それを終了してbashスクリプトに戻ります。期待する前にbashを使用している理由は、接続するユニットを選択できるメニューを使用しているためです。

ありがとう


49
最初の行を参照してください:SSHキーを使用する必要があると返信したい場合は、控えてください
Max

54
最初の行を少し親しみやすいように編集します。「制約のため、SSHキーを使用できないので、expectで動作させる方法を見つける必要があります」のようなものを検討するかもしれません。あなたがキーを使用していない理由を人々が自然に興味を持ち、役立つようにしようとしているだけであることを期待する必要があります:) @Ignacioはそれらを使用すること示唆していませんでした。
Tim Post

この場合、kermitを使用しようとします。それは持っている非常に強力なスクリプト言語columbia.edu/kermit/skermit.html#scripts
f3xy

回答:


86

bashとexpectを混合することは、望ましい効果を達成するための良い方法ではありません。Expectのみを使用しようとします。

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

bashのサンプルソリューションは次のとおりです。

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

これはエンターを待ってから(しばらくの間)インタラクティブセッションに戻ります。


1
それは素晴らしいです、ありがとう。SSH経由でログインした後にコマンドを入力したい場合はどうすればよいですか?
最大の

このスクリプトは、ログインしているユーザーの非アクティブなシェルを返します。質問がわかりません。どうしても同じスクリプトをbashで使用したい場合は、編集したエントリを確認してください。
PiotrKról、2011年

ログインしたら、プロンプトが表示されたら、私はパスワードを送信と同じように、私は、システムコマンドを送信したいと思います。
最大

上記の投稿にSamlpleコードが追加されました。もちろん、これはmy_commandXが返されたプロンプトを変更しないまで機能します。これが発生した場合は、プロンプト変数を変更する必要があります。
PiotrKról、2011年

@pietrushnicは、「expect $ prompt」の代わりに「interact -o -nobuffer -re $ prompt return」を使用する理由を少し説明できますか?より一般的に使用される後者のルックス...
リチャード・

53

最も簡単な方法は、sshpassを使用することです。これはUbuntu / Debianリポジトリで利用でき、bashとexpectを統合する必要はありません。

例:

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

上記のコマンドは、bashスクリプトと簡単に統合できます。

注:セキュリティへの影響を完全に理解するには、のセキュリティに関する考慮事項のセクションをお読みくださいman sshpass


それが良い解決策であるかどうかはわかりませんが、確かにかなり簡単になります。ありがとう
erikbwork '10

9
セキュリティの観点からは非常に危険です。コマンドライン引数は、システム上の他のプロセスによって読み取られる可能性があります。それらを上書きすることは可能であり、うまくいけばそれが可能sshpassですが、それでも、パスワードがすべてのプロセスで確認できるようになっているときに、それを実行できるようになる前に、まだ起動している期間があります。
Charles Duffy、

1
@CharlesDuffyもちろんです。sshpassは、セキュリティが最優先事項ではないローカルネットワーク環境で実行される簡単なテストスクリプトがあるシナリオで使用されます。実際、man sshpassセキュリティの考慮事項に関するセクション全体が説明されているセクションがあります。これを回答に追加しました、ありがとう。
dotnix

@ erikb85通常、パッケージはすべての汚いことを行いますが、すべての場合において、これらのスクリプトはその使用法のためにのみ構築され、独自のものを追加するよりも優れています。このコメントは、車輪を再発明しないことについてです。難しいことに対処するのは、まだ対処したことがない人だけにしてください。sshpassは良い機能です。
m3nda

2
完全を期すために、「man sshpass」は見込みユーザーに適切なセキュリティ警告を提供し、「-p」はそれを使用する最も安全でない方法であると指摘し、環境変数を介してパスワードを取得するための「-e」オプションを提供します、少なくともコマンドラインから除外します。
Ron Burk

22

EODの直前に「interact」expectコマンドを追加します。

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

これにより、ログアウトするまでリモートマシンと対話できるようになります。その後、bashに戻ります。


すぐに出入りします。「お出かけ」がプリントされています。
Emmanuel

8
私は "interact"と "EOD"を "expect eof"に置き換えましたが、うまくいきました。これはMacです。
Emmanuel

2
このページの答えはどれもうまくいきませんでしたが、@ Emmanuelの使用提案expect eofにより問題は解決しました。
moertel 2017年

'から削除するusr@$myhost.example.com'と、動作するはずです。そして、おそらくあなたは、交換する必要が\n\rはなく、メーリングリストへ
ティノ

20

質問に対する答えを数か月探した後、最終的に本当に簡単なスクリプトを書くという本当に最善の解決策を見つけました。

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

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

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

できた!


expect "assword:"意味expect "password:"ですか?
ユーザー

1
@userはとの"assword"両方に一致Passwordpasswordます。
Ferdinand.kraft

8

また、使用することを確認してください

send -- "$PWD\r" 

代わりに、ダッシュ(-)で始まるパスワードは失敗します。

上記は、ダッシュで始まる文字列をsendコマンドのオプションとして解釈しません。


8

単純な期待スクリプト

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

例:

    ./Remotelogin.exp <ip> <user name> <password>

7

ヘルパーツールfd0ssh(pmtではなくhxtoolsから)を使用します。これは、sshプログラムからの特定のプロンプトを期待する必要なく機能します。


これは素晴らしい!(少なくともubuntuサーバーでは)実行するのは少し難しいですが、スムーズに動作します!私たちが作った設定: echo "yoursshpass" | fd0ssh ssh -c -L$port:$ip:$remote_port user@yourserver.com & ありがとう!
JP Illanes

1
コマンドラインでパスワードを渡すよりもはるかに安全ですsshpass
Charles Duffy、

5

bashスクリプトから小さな expectスクリプトを使用すると便利な別の方法は次のとおりです。

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

これは機能する ...If the string "-" is supplied as a filename, standard input is read instead...


引数なしで呼び出すとデフォルトで読み取ら-れるため、ここは必要ありません。ただし、コマンドプロンプトなしで対話的に実行する場合(vs. )、またはオプションのように見えても(最初は)で最初の引数をファイルにする必要がある場合に役立ちます(で始まります)。その場合、(与えられたファイル)がであれば、これはから読み込まれます。expectstdinexpectexpect -expect -f "$@"-$1-stdin
ティノ

1

sshpassMakefile内のSublime Textビルドターゲット内で使用しようとすると壊れます。sshpassあなたの代わりに使用することができますpasshhttps : //github.com/clarkwang/passh

sshpassあなたがするだろう。

sshpass -p pa$$word ssh user@host

passhあなたがするだろう。

passh -p pa$$word ssh user@host

注:を使用することを忘れないでください。そうしない-o StrictHostKeyChecking=noと、初めて使用するときに接続がハングします。例えば:

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

参照:

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