スキップしてメイン コンテンツに移動

ssh-agentの管理を自動化する

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コマンドで実行するため,内部で登録したシェル変数は,実行後もシェルに残ってします.このため,使用したシェル変数は,末尾で開放している.