ssh-start.sh
ssh-agentの管理を自動化するスクリプトssh-start.shを紹介する.
詳細
ssh-agentを使うことで,sshでリモートログインする際に,パスワードの入力を省略できる.
ssh-agentを利用するためには,ソケットのパスとプロセスIDを環境変数に登録する必要がある.環境変数に登録すべき情報は,ssh-agentの起動時に,以下のように標準出力に出力される.
$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-XTqIvn4918/agent.4918; export SSH_AUTH_SOCK;
SSH_AGENT_PID=4919; export SSH_AGENT_PID;
echo Agent pid 4919;
上記のように,ssh-agentの出力はシェルコマンドとなっており,実行すれば環境変数がセットされる.このため,多くの解説記事では,次のようにevalを用いる方法が述べられている.
$ eval `ssh-agent`
Agent pid 4919
しかし,この方法は,同じssh-agentのプロセスを複数のシェルから利用することはできない.上記コマンドを他のシェル上でも実行すれば,動作はするが,次の点で優れた手法とは言えない.
- ssh-agentのプロセスを複数起動する (本来は1個で充分).
- 起動毎に秘密鍵の登録,およびパスフレーズの入力が必要となる.
上記の問題は解決するには,1個のssh-agentを複数のシェルから再利用すればよい.例えば2個のターミナルから1個のssh-agentプロセスを利用するには,次のようにする.
# terminal 1
$ ssh-agent > ~/tmp.sh
$ source ~/tmp.sh
Agent pid 4919
# terminal 2
$ source ~/tmp.sh
Agent pid 4919
こうすることで,2個のターミナルから同一プロセスのssh-agentを利用できる.
以上の処理を自動化したものが,ここで紹介するスクリプトである.
使い方
環境変数を扱かうため,通常のスクリプトのようには利用できない.このため,sourceコマンドや.(ドット)コマンドで実行する.
$ source /path/to/dir/ssh-start.sh
$ . /path/to/dir/ssh-start.sh
私はこれをエイリアスして使っている.これをrcスクリプトに書けば幸せになれる.
$ alias ssh-start='. ~/lib/bin/ssh-start.sh'
コード
#!/bin/sh
run_dir=~/var/run/
env_agent=$run_dir/ssh-agent.env
pid_agent=$run_dir/ssh-agent.pid
priv_key=~/.ssh/id_rsa
agent_alive=0
mkdir -p $run_dir
case `uname` in
Linux)
echo linux
if ps -C ssh-agent u | grep ${USER} 2>&1 1>/dev/null; then
echo ## alive
agent_alive=1
fi
;;
FreeBSD)
;;
NetBSD)
;;
CYGWIN*)
if [ -f $pid_agent ]; then
cmdline=/proc/`cat $pid_agent`/cmdline
if [ -f $cmdline ] &&
cat $cmdline | grep ssh-agent; then
agent_alive=1
fi
unset cmdline
fi
;;
esac
if [ $agent_alive -eq 0 ]; then
ssh-agent > $env_agent
sed '1,2d; s/echo Agent pid //; s/;//' \
$env_agent > $pid_agent
fi
source $env_agent
if [ $agent_alive -eq 0 ]; then
ssh-add $priv_key
fi
unset priv_key
unset env_agent
unset pid_agent
コードの解説
次の箇所で一時ファイルや,秘密鍵のパスを指定する.使用する環境に応じて適宜変更する.
run_dir=~/var/run/
env_agent=$run_dir/ssh-agent.env
pid_agent=$run_dir/ssh-agent.pid
priv_key=~/.ssh/id_rsa
psコマンドやprocファイルシステムの仕様が環境によって異なるので,処理を場合分けしている.未記入の箇所についてはいずれ追記する.
sourceコマンドで実行するため,内部で登録したシェル変数は,実行後もシェルに残ってします.このため,使用したシェル変数は,末尾で開放している.