木曜日, 2月 04, 2010

ssh-agentを使用したパスワードなしの接続

[概要]
ssh-agentを使用したパスワードなしの接続方法について説明します。

[詳細]
sshでの接続では、都度、パスワードもしくは、パスフェーズを入力をする必要があり、意外と面倒な作業です。また、シェルスクリプトなどでの自動化の妨げになります。
パスワードなしでの接続は、ホストベースの認証や、空のパスフェーズを使った公開鍵認証がありますが、セキュリティの低下が否めません。
ssh-agentを利用することで、前出の方法に比べセキュリティ・レベルをおとさずに、一度の認証で以降パスワードなしで接続することができます。
それでは、認証の手順を説明します。
  1. ssh-agentの起動
    ssh-agentを起動します。なお、RHEL, CentOSやUbuntuなどのディストリビューションでは、コンソールでX windowsを使用すると自動的にssh-agentが起動するようになり、設定もされているので起動の必要ありません。
    コンソールを使用していないリモートユーザやスクリプトで使用するとき、手動で起動してください。
    ssh-agentを実行すると下記のような出力があり、ssh-agentがデーモンとして実行されます。

    [root@localhost.localdomain ~]# ssh-agent
    SSH_AUTH_SOCK=/tmp/ssh-orwkxI2007/agent.2007; export SSH_AUTH_SOCK;
    SSH_AGENT_PID=2008; export SSH_AGENT_PID;
    echo Agent pid 2008;

    "SSH_AUTH_SOCK=..."の行と"SSH_AGENT_PID="をコピー & ペーストします。

    [root@localhost.localdomain ~]# SSH_AUTH_SOCK=/tmp/ssh-orwkxI2007/agent.2007; export SSH_AUTH_SOCK;
    [root@localhost.localdomain ~]# SSH_AGENT_PID=2008; export SSH_AGENT_PID;

    ここで、SSH_AUTH_SOCKは、ssh-agentと他のSSHのクライアントが通信に使用するソケットのファイル、SSH_AGENT_PIDは、ssh-agentの停止するときに使用される環境変数です。

    次のようにevalを使用すると、ssh-agentと同時に環境変数も設定されます。

    [root@localhost.localdomain ~]# eval `/usr/bin/ssh-agent`
    Agent pid 2008

  2. 秘密鍵の追加
    ssh-addを使用して、ssh-agentに秘密鍵を登録することで、エージェントがパスフレーズを維持します。

    [root@localhost.localdomain ~]# ssh-add ~/.ssh/id_rsa
    Enter passphrase for /root/.ssh/id_rsa:
    Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)

  3. 接続確認
    sshをつかって、パスフレーズなしの接続ができるかどうかを確認します。
    [root@localhost.localdomain ~]# ssh remote.localdomain
    Last login: Mon Feb 1 15:22:55 2010 from local.localdomain
    [root@remote.localdomain ~]#
以上でssh-agentを使用したパスワードなしの接続方法について説明は終了です。下は知っていると便利なTIPSです。

おまけ:「ssh-gentの終了方法」
ssh-agentの終了は、"ssh-agent -k"です。このとき、環境変数"SSH_AGENT_PID"で設定されたPIDのargentが終了します。この際、SSH_AGENT_PIDは必須です。
おまけ:「すでに起動しているssh-agentへの接続方法」
リモートから接続したときなど、新たにssh-agentを起動せずに既存のagentを使用することもできます。 すでに起動しているssh-agentに接続するためには、agentのプロセスと、それと通信するためのソケットを特定し、環境変数にセットします。 ソケットと対応するssh-agentを探します。
  1. プロセスの特定
    psコマンドを使って、ssh-agentのプロセスを特定します。
    [root@remote.localdomain ~]# ps -C ssh-agent -o pid,ppid,user,command
    PID PPID USER COMMAND
    4576 4536 root /usr/bin/ssh-agent /bin/sh -c exec -l /bin/bash -c "/usr/bin/dbus-lau"
    7473 1 root ssh-agent

    上の例では2つのssh-agentが動作しています。
    PID 4576は、X Windowのコンソールにログインした際のプロセスで、デーモン化していませんので親のPID(PPID)を見ることができます。
    PID 7473は、今回説明した方法で起動したプロセスです。こちらはデーモン化しているのでPPIDが1になっています。この場合、実際にPID 7473を起動したプロセスはPPID=PID-1つまり7472となります。
  2. ソケットの特定
    ソケット・ファイルは、"/tmp/ssh-XXXXXXXXXX/agent.ppid"として存在します。(Xは任意の英数字、ppidは親のプロセスID。)
    そこで、findコマンドでソケット・ファイルを探します。

    [root@remote.localdomain ~]# find /tmp/ssh-* -name agent.*
    /tmp/ssh-Otawzy4536/agent.4536
    /tmp/ssh-jqcBXV7472/agent.7472

  3. 環境変数の設定
    ソケットとプロセスの結びつけができたら、環境変数SSH_AUTH_SOCKとSSH_AGENT_PIDを設定すれば、既存のssh-agentに接続することができます。
    [root@remote.localdomain ~]# SSH_AUTH_SOCK=/tmp/ssh-Otawzy4536/agent.4536; export SSH_AUTH_SOCK;
    [root@remote.localdomain ~]# SSH_AGENT_PID=4576; export SSH_AGENT_PID;
    [root@localhost.localdomain ~]# ssh remote.localdomain
    Last login: Mon Feb 2 15:22:55 2010 from local.localdomain
    [root@remote.localdomain ~]#

0 件のコメント: