LoginSignup
117
125

More than 5 years have passed since last update.

expectやsshpassを使わずにシェルでSSHパスワード認証を自動化する

Posted at

はじめに

  • 接続先サーバ側を変更できるのであれば公開鍵認証方式をおとなしく使いましょう。
  • どうしてもパスワード認証方式を使わないといけない場合は、接続クライアント側にソフトウェアをインストール可能ならSSHPassを使いましょう。巷にはexpectコマンドを使った方法があふれていますが、インストール可能な環境ならSSHPassのほうが良い (参考: sshにパスワードで自動ログインするならexpectよりもsshpassを使おう
  • サーバ側もクライアント側も変更がどうしてもできない…残念ながら大人な事情でそういうこともあります。そんな時は本記事が参考になるかと思います。

実現方式

sshにはSSH_ASKPASSという仕組みがあります。以下、引用。

SSH_ASKPASS
パスフレーズを入力する際、ssh が端末から起動されているとssh はパスフレーズをその端末から要求します。ssh が制御できる端末を持っておらず、環境変数DISPLAY およびSSH_ASKPASS が設定されている場合、ssh はSSH_ASKPASS によって指定されるプログラムを起動し、X11 ウインドウを使ってパスフレーズを要求します。これはssh を.xsessionやそれに類するスクリプトから呼び出す際にとくに役に立ちます。(マシンによっては、これがうまく動くためには標準入力を/dev/nullにリダイレクトする必要があるかもしれません)

これはGUIからSSH接続のパスワードを入力させてそれを受け取ることを想定した仕組みですが、これを利用してパスワードをシェルから渡すこともできるわけです。
具体的には環境変数 SSH_ASKPASSに、パスワードを返すプログラム(シェルスクリプト)を設定すればOK。また、環境変数 DISPLAYにはダミーの値を設定しておけばOKです。

具体的な実装例

SSHで接続してls -alを実行するだけの例です。

sshauto.sh
#!/bin/bash

# 接続先情報
SSH_USER=test
SSH_PASS=mypass
SSH_HOST=your_ssh_server
REMOTE_CMD="ls -al"


# 後述のSSH_ASKPASSで設定したプログラム(本ファイル自身)が返す内容
if [ -n "$PASSWORD" ]; then
  cat <<< "$PASSWORD"
  exit 0
fi

# SSH_ASKPASSで呼ばれるシェルにパスワードを渡すために変数を設定
export PASSWORD=$SSH_PASS

# SSH_ASKPASSに本ファイルを設定
export SSH_ASKPASS=$0
# ダミーを設定
export DISPLAY=dummy:0

# SSH接続 & リモートコマンド実行
exec setsid ssh $SSH_USER@$SSH_HOST $REMOTE_CMD
実行結果
[root@6a6d8eb6ad44 ~]# ./sshauto.sh
[root@6a6d8eb6ad44 ~]# total 12
drwxr-sr-x    2 test     test          4096 Jan 23 16:51 .
drwxr-xr-x    3 root     root          4096 Jan 23 16:51 ..
-rw-------    1 test     test            24 Jan 23 16:51 .ash_history

上記の実装例では、SSH_ASKPASS に設定するプログラムを$0で自分自身を設定することで1ファイルで完結していますが、別のファイルでももちろん構わないです。

最後にもう一度書きますが、できるなら公開鍵認証方式をおとなしく使いましょう!!

参考サイト

117
125
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
117
125