SSH をよく使う人には、必須なツールである ssh-agent の使い方について説明します。
1. SSH とは?
SSH(Secure Shell、セキュアシェル)というのは、通信プロトコルです。暗号化 と 認証 の仕組みを持っているため、安全な通信が実現できます。
いろいろな用途があるのですが、一番多いのは「ターミナルエミュレーターと呼ばれるアプリケーションを使って、遠隔にあるサーバーにログインし、コマンドを打ち込むことで何らかの作業を行う」という使い方です。(「シェルログイン」と呼ばれることもあります)
SSH でサーバーにログインするには、以下のようにログインユーザー名とログインするサーバーのホスト名を指定して、ssh
コマンドを実行します。(ホスト名の部分は、代わりにIPアドレスを指定することもできます。)
ssh ログインユーザー名@ホスト名
このログインを行うには、サーバー側で sshd
というプログラムが稼働している必要があります。
この sshd
はデフォルトで 22番ポートを利用しますが、違う番号に変更している場合は、ssh
コマンドの -p
オプションでその番号を指定する必要があります。
例えば、2222 に変更していた場合、先程のコマンドは以下のようになります。
ssh -p 2222 ログインユーザー名@ホスト名
2. ssh-agent とは?
SSH で利用される認証方式
SSH は様々な 認証方式 に対応しています。
サーバー上に作成されたユーザーの「ユーザー名」と「パスワード」で認証する方式が一番分かりやすいのですが、当然この2つの情報が漏れてしまえば誰でもなりすましができてしまいます。
そうした危険を避けるため、様々なところで 公開鍵認証 という方式を利用することが推奨されています。
この方式は、利用者(ユーザー側)が、
- 誰に見られてもよい 公開鍵
- 本人だけが持っている 秘密鍵
のペアを作成して認証に利用します(どちらもファイルとして生成します)。
簡単に説明しますと、事前に公開鍵をサーバー側に配置しておき、ログイン時の認証処理において、ローカルに配置された秘密鍵と照合して本人確認するという方式になります。通常、秘密鍵にはパスフレーズ(パスワードと同じようなもの)を設定しておきまして、認証時に入力する必要があります。
ということで公開鍵認証には以下の特徴があるため、パスワードよりも漏れる心配がかなり低く安全なのです。
- 秘密鍵はランダムで大きめなサイズのデータになっており、予測はほぼ不可能である。
- 秘密鍵の配置場所や、パーミッション(アクセス権限)に厳しい制限がある。
- 認証時にはパスフレーズの入力が必要である。
秘密鍵を一時的に保持してくれる ssh-agent
非常に安全な公開鍵認証方式なのですが、何度も認証が必要になるような環境ですと、パスフレーズの入力が大きなストレスになります。このために利用できるツールが、ssh-agent です。
ssh-agent を起動して秘密鍵を登録しておけば、ssh
コマンドを実行した際に自動的に秘密鍵を適用して認証処理を行ってくれます。パスフレーズの入力は、秘密鍵の登録時に一度行うだけで済みます。
3. ssh-agent の使い方
1. ssh-agent の開始(起動)
ssh-agent プログラムを開始します。一度起動すると、バックグラウンドで稼働し続けます。
ここでは3つの起動方法を紹介します。お好みによってどれか1つを実行してください。
方法1: ssh-agent コマンドをそのまま実行する
以下のコマンドを実行して ssh-agent を開始する方法です。
$ ssh-agent $SHELL
- この方法だと、シェルのプロセスが1つ余計に生成されてしまいます。
- つまり、2回
exit
コマンドを実行しないとログアウトできません。
実行例(生成されるプロセス)
fooというユーザーで、host.example.com サーバーにログインしている状態です。
ssh-agent を開始し、プロセスをツリー表示しています。
$ ssh-agent $SHELL
$ ps xf
PID TTY STAT TIME COMMAND
31463 ? S 0:00 sshd: foo@pts/0
31464 pts/0 Ss 0:00 \_ -bash
31547 pts/0 S 0:00 \_ /bin/bash
31548 ? Ss 0:00 \_ ssh-agent /bin/bash
31609 pts/0 R+ 0:00 \_ ps xf
- bash の子プロセスとして /bin/bash のプロセスが生成されています。
- ssh-agent のプロセスは更にその下にぶら下がります。
※ $SHELL
の値は、/bin/bash
になっています。
方法2: exec を使う
以下のコマンドを実行して ssh-agent を開始する方法です。
$ exec ssh-agent $SHELL
exec
コマンド(Bashの組み込みコマンド)を使うことで、現在のシェルを新しいシェルで置換します。- その新しく置き換えられたシェルのプロセスに対して、子プロセスとして ssh-agent プログラムのプロセスが生成されます。
- そのため、
exit
した時に、ssh-agent も終了します。
実行例(生成されるプロセス)
fooというユーザーで、host.example.com サーバーにログインしている状態です。
ssh-agent を開始し、プロセスをツリー表示しています。
$ exec ssh-agent $SHELL
foo@ host.example.com : ~
$ ps xf
PID TTY STAT TIME COMMAND
29687 ? S 0:00 sshd: foo@pts/0
29688 pts/0 Ss 0:00 \_ /bin/bash
29951 ? Ss 0:00 \_ ssh-agent /bin/bash
30015 pts/0 R+ 0:00 \_ ps xf
- ssh-agent が /bin/bash の子プロセスになっているのが分かります。
※ $SHELL
の値は、/bin/bash
になっています。
方法3: eval を使う
以下のコマンドを実行して ssh-agent を開始する方法です。
eval `ssh-agent`
- 余計なシェルのプロセスは生成されません。
- ssh-agent が独立したプロセスとして生成されます。
- そのため、ログアウトしても ssh-agent のプロセスが残ったままになってしまいます(通常 プロセスが終了すると、内部でその子プロセスにシグナルを送ってそちらも終了させます)。
実行例(生成されるプロセス)
fooというユーザーで、host.example.com サーバーにログインしている状態です。
ssh-agent を開始し、プロセスをツリー表示しています。
$ eval `ssh-agent`
Agent pid 29935
foo @ host.example.com : ~
$ ps xf
PID TTY STAT TIME COMMAND
29687 ? S 0:00 sshd: foo@pts/0
29688 pts/0 Ss 0:00 \_ /bin/bash
29946 pts/0 R+ 0:00 \_ ps xf
29935 ? Ss 0:00 ssh-agent
- ssh-agent は bash の子プロセスにはなっておらず、独立しているのが分かります。
※ $SHELL
の値は、/bin/bash
になっています。
秘密鍵を保持した ssh-agent が残ったままになるのは、セキュリティ的な観点から見てよいことではありません。ssh-agent を明示的に終了させるには、以下のコマンドを実行します。
$ ssh-agent -k
もしくは、~/.bash_logout
ファイルに、このコマンドを記述しておけば、ログアウト時に自動的に実行してくれます。
※ このような時には、絶対パスを使ってコマンドを記述しましょう。which ssh-agnet
コマンドを実行すれば、パスが分かります。
どの方法がよいのか?
自分の使い方に合った方法を選びましょう。
個人的には、余計なシェルのプロセスが生成されず、ログアウトした時に ssh-agent が自動的に終了する 「方法2」がお勧めです。
2. 秘密鍵の追加
次に秘密鍵を ssh-agent に追加します。これをしないと ssh-agent を使う意味がありません。
以下のコマンドで秘密鍵を追加することができます。
$ ssh-add 秘密鍵へのファイルパス
追加する際には、その秘密鍵のパスフレーズを入力する必要があります。
また、ssh-agent には、複数の秘密鍵を追加しておくことができますが、「ssh
コマンドを実行する際に、どの秘密鍵が使われるのか?」を常に意識しておくのが面倒なので、その時その時に必要な秘密鍵を1つだけ追加しておくという使い方もあります。そのためには、「追加されている秘密鍵の一覧表示」「秘密鍵の削除」もできるようになっておきましょう。
4. 秘密鍵の管理
ssh-add
コマンドで、ssh-agent で使う秘密鍵の操作を行うことができます。
代表的な操作について説明します。
追加されている秘密鍵の一覧表示
全ての秘密鍵のフィンガープリント (ingerprints) を表示する
ひと目でどんな秘密鍵が追加されているのか確認したい場合はこちらです。
$ ssh-add -l
全ての秘密鍵に対する公開鍵パラメータを表示する
こちらは公開鍵の中身が全て表示されます。あまり使わないかもしれません。
$ ssh-add -L
追加されている秘密鍵を削除する
個別に削除する
$ ssh-add -d 秘密鍵へのファイルパス
全て削除する
$ ssh-add -D
5. エージェント転送 (ForwardAgent) の使い方
SSH には、「エージェント転送 (ForwardAgent)」という機能があります。
これは何かというと、以下のような動作を可能にする機能です。
- ある環境Aで、ssh-agent を動かして使っている。
- その環境Aから、
ssh
コマンドを使って、サーバーBにログインした。 - この時、サーバーB においても、環境A の ssh-agent が引き続き利用できる。
- なので、サーバーBにいても、
ssh-add -l
を実行すると、環境Aで追加していた秘密鍵が表示されるし、ssh
コマンドを実行した時に、追加されている秘密鍵が自動的に適用される。
- なので、サーバーBにいても、
利用手順(例)
(1) ある環境で ssh-agent を利用します。
ssh-agent を開始します。
$ exec ssh-agent $SHELL
ssh-agent に秘密鍵を追加します。
$ ssh-add
(2) ssh でサーバーにログインします。
その際、-A
オプションを指定します。
$ ssh -A foo@host.example.com
※ -A
オプションの代わりに、~/.ssh/config
ファイルに「ForwardAgent yes
」を記述することでも同様の効果を得ることができます。
(3) サーバーにログインしても、引き続き ssh-agent が利用できるようになっています。
$ ssh-add -l
(最初の環境で追加していた秘密鍵が一覧表示されます)
サーバー上にある秘密鍵を追加することもできます。
$ ssh-add ~/.ssh/id_rsa_test
もちろん、追加されている秘密鍵を使って、更に他のサーバーに ssh でアクセスすることもできます。
$ ssh bar@other.example.net
注意
セキュリティ的には少し怖い機能でもあります。気を付けて使いましょう。
6. おわりに
「ssh-agent」の使い方について説明しました。
「SSH をよく使っているけれど、まだ ssh-agent は使っていない」という方は、是非参考にしてください。