woshidan's blog

そんなことよりコードにダイブ。

ssh-agentでsshコマンドで認証鍵の指定を入れなくていいようにしたりログイン先のサーバに認証鍵の情報を転送したりする

TL;DR

  • ssh-agent bashssh-agent を起動して ssh-add /path/to/secret_key することで ssh コマンドで認証鍵の指定やパスフレーズの入力が省略できる
  • ssh-agent はOpenSSHの認証エージェントで、認証エージェントの「転送」により、ローカルで動いているクライアントが持っている認証情報をログイン先のサーバに転送することができる
    • ssh コマンドの -A オプションで「転送」を行う旨を指定する
    • 認証エージェントの転送を利用することで、たくさんの人がアクセスする可能性のあるサーバに秘密鍵をおかなくて済んだりする

SSHでパスワードを使わずにログインする

SSHでパスワードを使わずにログインするようにするには、

  1. ssh-keygen秘密鍵と公開鍵のペアを作成する*1
  2. ログイン先のサーバの ~/.ssh/authorized_keys 以下に公開鍵を設置して、所有者・グループ・権限を設定する*2
  3. 秘密鍵-i オプションで指定してSSHコマンドを叩く ssh -i /path/to/secret_key user@exapmle.com

という手順を踏みますが、さらに秘密鍵を指定しているオプションも ssh コマンドに含まないようにしたいとします。

やり方は

  1. SSH_CONFIG *3にログイン先のホスト、ログインするユーザー名、そのユーザーがログインするときに使う秘密鍵のパスを指定する
  2. 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
# パスフレーズが指定された鍵であれば、このタイミングで入力する

でそのセッションのプロセスのメモリ上に秘密鍵の情報を登録し*6ssh-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 が行われたタイミングも確認するとよさそうです。

現場からは以上です。

参考

*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