ssh-agentでsshコマンドで認証鍵の指定を入れなくていいようにしたりログイン先のサーバに認証鍵の情報を転送したりする
TL;DR
ssh-agent bash
でssh-agent
を起動してssh-add /path/to/secret_key
することでssh
コマンドで認証鍵の指定やパスフレーズの入力が省略できるssh-agent
はOpenSSHの認証エージェントで、認証エージェントの「転送」により、ローカルで動いているクライアントが持っている認証情報をログイン先のサーバに転送することができるssh
コマンドの-A
オプションで「転送」を行う旨を指定する- 認証エージェントの転送を利用することで、たくさんの人がアクセスする可能性のあるサーバに秘密鍵をおかなくて済んだりする
SSHでパスワードを使わずにログインする
SSHでパスワードを使わずにログインするようにするには、
ssh-keygen
で秘密鍵と公開鍵のペアを作成する*1- ログイン先のサーバの
~/.ssh/authorized_keys
以下に公開鍵を設置して、所有者・グループ・権限を設定する*2 - 秘密鍵を
-i
オプションで指定してSSHコマンドを叩くssh -i /path/to/secret_key user@exapmle.com
という手順を踏みますが、さらに秘密鍵を指定しているオプションも ssh
コマンドに含まないようにしたいとします。
やり方は
SSH_CONFIG
*3にログイン先のホスト、ログインするユーザー名、そのユーザーがログインするときに使う秘密鍵のパスを指定するssh-agent
を起動して、ssh-agent
に認証に利用する鍵を追加する
といった方法があります。今日は ssh-agent
を使う方法についてもう少しメモします。
ssh-agentを利用してログインをする方法
ssh-agentは公開鍵認証を行うときに利用する秘密鍵の情報をメモリ上に保持するプログラム*4で、sshでログインを行う前に
$ ssh-agent bash
または
$ eval `ssh-agent`
で起動し、 ssh-agent -k
で停止します*5。
起動した後、
$ ssh-add /path/to/secret_key
# パスフレーズが指定された鍵であれば、このタイミングで入力する
でそのセッションのプロセスのメモリ上に秘密鍵の情報を登録し*6、 ssh-add -l
で登録した鍵の一覧を確認できます。
ssh-agent に鍵を登録した状態で ssh
コマンドを打つと、以下のように認証鍵の指定やパスワードの入力を行わずにリモートのサーバへログインすることができます。
$ ssh server.example.com
ssh-agentを利用してログインする場合にできること
さて、 ssh-agent
を使ってパスフレーズや認証鍵の指定なしでログインする方法を紹介しましたが、この手間はパスワード入力をなクスという意味では SSH_CONFIG
にログイン設定をする方法(具体的には
Host example.com HostName example.com IdentityFile ~/.ssh/id_rsa User woshidan
のように設定を書く)とたいして手間は変わりません。
それでは、 ssh-agent
を使うと SSH_CONFIG
を使う場合と比べてなにがちがうのでしょうか。
ssh-agent
は、OpenSSHにおける認証エージェントですが、認証エージェントには、認証エージェントを「転送」するという機能があります。
認証エージェントを「転送」するとはどういうことかというと、ローカルで動いてる認証エージェントが持つ認証鍵を含む情報をログイン先のサーバに通知し、ログイン先のサーバ上の sshd
デーモンにもローカルと同様の情報を持った認証エージェントとして機能してもらうことです。コマンドとしては
$ ssh -A [ユーザ名@]ホスト名
のように ssh
コマンドに -A
オプションをつけることで可能です。
このようにすることで、他のサーバへアクセスする必要のあるサーバに秘密鍵を配置する必要がなくなります。
たとえば、リモートのビルドサーバはビルドに必要なファイルを取得するために他のサーバにアクセスする必要がありますが、その際、秘密鍵をビルドサーバに配置すると、ビルドのデバッグのためにログインしたエンジニアやそれ以外の人(?)はそのファイルにアクセスできたりするわけですが。
管理者だけがアクセスできるようにしたサーバに秘密鍵を置き、そのサーバから ssh-agent
を使ってビルドサーバにログインしてビルド作業を行うようにすることで、秘密鍵にアクセス可能な人数を制限できたりします*7*8。
逆に、認証情報に関するエラーのデバッグのときは、 ssh
のオプションや ssh-add
が行われたタイミングも確認するとよさそうです。
現場からは以上です。
参考
- http://nigohiroki.hatenablog.com/entry/2013/08/18/221434
- https://euske.github.io/openssh-jman/ssh_config.html
- https://euske.github.io/openssh-jman/ssh-agent.html
- https://qiita.com/naoki_mochizuki/items/93ee2643a4c6ab0a20f5
- http://www.unixuser.org/~euske/doc/openssh/book/chap3.html
- http://www.unixuser.org/~euske/doc/openssh/book/chap4.html#make-life-easy-with-ssh-agent
- https://qiita.com/Yarimizu14/items/6a4bab703d67ea766ddc
*1:SSHでパスワードを使わずにログインする手順なので省いていますが、SSHでユーザがログインできるようにする作業全体としては、この前段階にSSHログインできるようにする目的で、ログイン先のサーバに adduser コマンドでユーザを作成し、passwdコマンドでパスワードを作成する必要がある refs: http://nigohiroki.hatenablog.com/entry/2013/08/18/221434
*2:詳細は http://nigohiroki.hatenablog.com/entry/2013/08/18/221434
*3:https://euske.github.io/openssh-jman/ssh_config.html だいたいユーザ用の設定ファイル ~/.ssh/config に書く
*4:https://euske.github.io/openssh-jman/ssh-agent.html
*5:この辺の便利なスクリプトは http://www.unixuser.org/~euske/doc/openssh/book/chap5.html#spread-ssh-agent にまとめっています。圧倒的感謝...!!
*6:他のオプションの利用例などは https://qiita.com/naoki_mochizuki/items/93ee2643a4c6ab0a20f5 が参考になる
*7:もっと、いろいろある気はしたんですが、自分が考えてぱっと出てきた例がこういうのが限界
*8:たとえば、Rundeckには秘密鍵などを管理するための画面があります https://rundeck.org/2.9.1/administration/key-storage.html https://komeda-shinji.blogspot.com/2015/02/rundeck_68.html