共通テーマ: OpenSSH キー (鍵) の管理: 第 2 回

ssh-agent と keychain の概要

多くの開発者が、旧来のtelnetコマンドやrshコマンドに代わるセキュアで暗号化された優れた手段として、OpenSSHを使用しています。OpenSSHのさらに魅力的な機能の1つは、1対の相補的な数値「キー」をベースにしたRSA/DSA認証プロトコルによるユーザー認証が可能である点です。RSA/DSA認証の主な魅力の1つは、リモート・システムとの接続をパスワード入力なしで確立する機能です。第2回となる今回の記事では、Daniel Robbins氏がssh-agent(私有鍵キャッシュ)、ならびに鍵ベース認証の利便性と柔軟性の飛躍的向上を目的とした特別なbashスクリプト「keychain」の概要を説明します。

Daniel Robbins (drobbins@gentoo.org), President/CEO, Gentoo Technologies, Inc.

Daniel Robbins氏は、ニューメキシコ州アルバカーキーに住んでいます。彼は、Gentooプロジェクトのチーフ・アーキテクト、Gentoo Technologies Inc. の社長/CEOです。著書に、Macmillanから出版されているCaldera OpenLinux Unleashed、SuSE Linux Unleashed、Samba Unleashed があります。Daniel氏は、小学2年のとき初めてLogoプログラム言語や、中毒になる恐れのあったPac Manに出会って以来、何らかの形でコンピューターに関係してきています。これで、彼がなぜSONY Electronic Publishing/Psygnosisでリード・グラフィック・アーチストを務めているかが分かるでしょう。愛妻Maryさんや、生まれたばかりの愛娘Hadassahちゃんとの時間をとても大切にしています。彼の連絡先はdrobbins@gentoo.org です。



2001年 9月 01日

ssh-agentの紹介

OpenSSHディストリビューションに付属するssh-agent/は、RSA/DSA鍵の取り扱いを快適かつセキュアなものとすることを目的として設計された専用プログラムです(RSA/DSA認証の概要についてはこの連載の第1回を参照)。ssh-agentは、sshと異なり、暗号化解除済み私有鍵のキャッシュのみを目的とした長期にわたって実行されるデーモンです。

sshは、ssh-agentとの通信を可能にする組み込みサポートを備えているため、接続ごとにユーザーにパスワードを要求することなく暗号化解除済みの私有鍵を取得することができます。ssh-agentにより、ssh-addを使用するだけでssh-agentのキャッシュに私有鍵を追加できます。このプロセスは1回のみで、ssh-addの使用後はsshssh-agentから私有鍵を取得するため、その都度パスフレーズが要求されるという煩わしさがなくなります。

ssh-agentの使い方

それでは、このssh-agent鍵キャッシュ・システム全体の仕組みについて見てみましょう。ssh-agentは、起動時にいくつかの重要な環境変数を出力してからシェルから切り離され、バックグラウンドで継続的に実行されます。以下に、ssh-agentが起動時に生成する出力の例を示します。

% ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-XX4LkMJS/agent.26916; export SSH_AUTH_SOCK;
SSH_AGENT_PID=26917; export SSH_AGENT_PID;
echo Agent pid 26917;

ご覧のとおり、ssh-agentの出力は実際には一連のbashコマンドで、これらのコマンドが実行されると2つの環境変数SSH_AUTH_SOCKおよびSSH_AGENT_PIDが設定されます。組み込みのエクスポート・コマンドにより、これらの環境変数はそれより後に実行されるすべての追加コマンドで使用できます。このことは、もしそれらの出力行が実際にシェルで評価された場合のことですが、今の場合はただ標準出力へ書かれるだけです。これを修正するには、次のようにしてssh-agentを呼び出します。

eval `ssh-agent`

このコマンドは、ssh-agentを実行してからssh-agentの出力を評価するようにbashに命令します。このように(通常の一重引用符ではなくバッククウォート(開き引用符)を付けて)起動すると、シェルによってSSH_AGENT_PIDおよびSSH_AUTH_SOCK変数が設定、エクスポートされるため、ログイン・セッション中に起動するすべての新規プロセスでこれらの変数を使用できるようになります。

ssh-agentの最も良い起動方法は、~/.bash_profileに上記の行を追加することです。それにより、ログイン・シェルで起動される全てのプログラムが環境変数を参照してssh-agentを特定し、必要に応じて鍵に関する照会ができるようになります。特に重要な環境変数はSSH_AUTH_SOCKです。SSH_AUTH_SOCKには、sshおよびscpssh-agentとのダイアログの設定に使用できるUNIXドメイン・ソケットへのパスが含まれています。

ssh-addの使い方

しかし、言うまでもなく、ssh-agentの起動時には暗号化解除済みの私有鍵キャッシュは空の状態です。実際にssh-agentを使用する前に、まずssh-addコマンドを使用して私有鍵をssh-agentのキャッシュに追加する必要があります。次の例では、ssh-addを使用してRSA私有鍵~/.ssh/identityをssh-agentのキャッシュに追加します。

# ssh-add ~/.ssh/identity
Need passphrase for /home/drobbins/.ssh/identity
Enter passphrase for /home/drobbins/.ssh/identity 
(enter passphrase)

ご覧のとおり、ssh-addはパスフレーズの入力を要求しています。これは私有鍵の暗号化を解除し、ssh-agentのキャッシュに保管して、私有鍵をいつでも使用できる状態にするためです。ssh-addを使用して私有鍵をssh-agentのキャッシュに追加し、SSH_AUTH_SOCKが現在のシェルに定義されると(~/.bash_profileからssh-agentを起動した場合はそうなるはずです)、scpおよびsshを使用して、パスフレーズを入力せずにリモート・システムとの接続が確立できるようになります。

ssh-agentの制限事項

ssh-agentはきわめて優れていますが、デフォルト構成のままではちょっとした不都合がいくつかあります。次に、この点について見てみましょう。

まず1つは、~/.bash_profileにeval `ssh-agent`を追加した場合に、各ログイン・セッションごとにssh-agentの新しいコピーが起動されるということです。これは、いささか無駄であると同時に、ssh-agentの新しいコピーごとにssh-addによって私有鍵の追加が必要となります。これは、システム上でオープンする端末またはコンソールが1つのみである場合にはあまり問題にはなりませんが、大抵の場合はかなりの数の端末をオープンするため、新しいコンソールをオープンするごとにその都度パスフレーズの入力が必要となります。実際には1つのssh-agentプロセスで十分であるため、その必要はまったくありません。

デフォルトのssh-agentセットアップに関するもう1つの問題は、cronジョブとの互換性がないことです。cronジョブは、cronプロセスによって起動されるため実行環境からSSH_AUTH_SOCK変数を継承せず、したがってssh-agentプロセスが実行中であること、またssh-agentプロセスとの通信もできないことになります。ただし、この問題も修正可能です。


keychainの導入

これらの問題を解決するために、私はkeychainというbashベースのssh-agentフロントエンドを作成しました。keychainの特徴は、ログイン・セッションごとだけでなく、システムごとにも1つのssh-agentプロセスを使用できることです。つまり、ssh-addの実行は、私有鍵ごとに1回だけで良いということです。この後説明しますが、keychainは、ssh-agentのキャッシュ内に既に存在する場合以外のみ私有鍵を追加することによって、ssh-addプロセスの最適化をサポートします。

keychainの仕組みを簡単に説明しておきます。keychainは、~/.bash_profileから起動されると、まずssh-agentがすでに実行中であるかどうかを確認します。実行されていない場合、ssh-agentを起動し、重要なSSH_AUTH_SOCKおよびSSH_AGENT_PID変数を安全に保管し、後で使用するために~/.ssh-agentファイルに記録します。keychainの最も良い起動方法は次のとおりです。通常のssh-agentを使用する場合と同様に、~/.bash_profileから必要なセットアップを実行します。

#!/bin/bash
#example ~/.bash_profile file
/usr/bin/keychain ~/.ssh/id_rsa
#redirect ~/.ssh-agent output to /dev/null to zap the annoying
#"Agent PID" message

ご覧のとおり、keychainの場合、ssh-agentを直接使用する場合のような出力の評価を行うのではなく、~/.ssh-agentファイルを参照します。ただし、結果は同じです。重要なSSH_AUTH_SOCKの定義、ssh-agentの実行が行われ、いつでも使用できる状態になります。SSH_AUTH_SOCKは~/.ssh-agentに記録されるため、ユーザー作成のシェル・スクリプトもcronジョブも~/.ssh-agentファイルを参照するだけで簡単にssh-agentに接続できます。keychain自体もこのファイルを使用します。ここで、keychainは起動時にssh-agentがすでに実行中であるかどうかを確認することを思い出してください。もしそうなら、~/.ssh-agentファイルを使用して適切なSSH_AUTH_SOCK設定を取得することにより、新しいエージェントを起動するのではなく、既存のエージェントを使用できることになります。keychainが新しいssh-agentプロセスを起動するのは、~/.ssh-agentファイルが不整合である(存在しないssh-agentを指し示している)場合または~/.ssh-agent自体が存在しない場合のみです。

keychainのインストール

keychainのインストールは簡単です。まず、keychainプロジェクト のページにアクセスし、最新バージョンのkeychainソース・アーカイブをダウンロードします。その後、次のようにしてインストールします。

# tar xzvf keychain-1.0.tar.gz
# cd keychain-1.0
# install -m0755 keychain /usr/bin

keychainが/usr/bin/にインストールされたので、私有鍵のパスを引数として指定して~/.bash_profileに追加します。以下に、keychain対応の標準的な~/.bash_profileの例を示します。

keychain対応の~/.bash_profileの例
#!/bin/bash
#on this next line, we start keychain and point it to the private keys that
#we'd like it to cache
/usr/bin/keychain ~/.ssh/id_rsa ~/.ssh/id_dsa
source ~/.ssh-agent > /dev/null
#sourcing ~/.bashrc is a good thing
source ~/.bashrc

keychainの実行

各ログイン時にkeychainを呼び出すように~/.bash_profileを構成した後、いったんログアウトし、再度ログインします。ログインすると、keychainによってssh-agentが起動され、エージェントの環境変数設定が~/.ssh-agentに記録され、~/.bash_profileのkeychainコマンド・ラインに指定された私有鍵のパスフレーズの入力が要求されます。

keychainを初めて起動した状態
図1

パスフレーズを入力すると私有鍵がキャッシュされ、keychainは終了します。次いで、~/.ssh-agentを参照し、ssh-agentを使用できるようにログイン・セッションが初期設定されます。ここでログアウトし、再度ログインすると、keychainが既存のssh-agentプロセスを見付けることが分かります。つまり、ログアウト時に終了していなかったということです。さらに、keychainは指定された私有鍵がssh-agentのキャッシュ内にすでに存在するかどうかも確認します。存在しなければ適切なパスフレーズの入力が要求されますが、問題なければ以前に追加した私有鍵が既存のssh-agentに格納されたままになっているはずです。つまり、パスワードの入力が要求されないことになります。

keychainが既存のssh-agentを見付けた状態
図2

おめでとうございます。ログインするとすぐに、リモート・システムに対してsshコマンドやscpコマンドを実行できるはずです。ログインの直後にssh-addを使用する必要はなく、sshscpはいずれもパスフレーズの入力を要求しません。実際に、最初のssh-agentプロセスの実行が続く限りは、ログイン、ssh接続の確立がパスワードを入力せずにできます。また、ssh-agentプロセスはマシンがリブートされるまで、長い期間実行が継続する(そのようにLinuxシステムが設定される)場合が多く、数カ月間パスフレーズを入力せずに済ませることもできます!RSA/DSA認証によるセキュアなパスワードレス接続の世界へようこそ!

先に進んでいくつかの新しいログイン・セッションを作成すると、keychainがその都度全く同じssh-agentプロセスを「フック」することが分かります。cronジョブやスクリプトを実行中のssh-agentプロセスに「フック」できることも忘れてはなりません。シェル・スクリプトやcronジョブからsshまたはscpコマンドを使用するには、コマンドが~/.ssh-agentファイルを最初に参照するようにしてください。

source ~/.ssh-agent

そうすると、sshまたはscpコマンドを実行したときに、現在実行中のssh-agentを見付け、シェルからの場合と全く同様にセキュアなパスワード不要の接続を確立できるようになります。


keychainのオプション

keychainが稼働可能な状態になったら、必ずkeychain --helpと入力して、keychainのコマンド・ライン・オプションをすべて把握してください。では次に、特に重要なオプションである--clearオプションについて説明します。

この連載の第1回の記事で、暗号化されていない私有鍵を使用すると、誰かが私有鍵を盗み、その鍵を使用して他のシステムからパスワードを入力せずにリモート・アカウントにログインできてしまうため危険であると説明しました。keychainは、このような不正使用に対する脆弱性はありませんが(暗号化された私有鍵を使用する限り)、長期にわたって実行されるssh-agentプロセスに対して、keychainによる「フック」がきわめて容易に行えるようになるという脆弱性が生じるのではないでしょうか。もし侵入者が何らかの方法で私のパスワードまたはパスフレーズを知り、ローカル・システムにログインしたとしたらどのような結果になるのかについて考えてみました。もし彼らが何らかの方法で私のユーザー名でログインできたとしたら、keychainによって彼らは暗号化解除済みの私有鍵に直ちにアクセスできるようになり、私の他のアカウントへのアクセスもいとも簡単に行えるようになるはずです。

ここで、次の説明に移る前に、このセキュリティーの脅威についてはっきりさせておきましょう。もし悪意のあるユーザーが何らかの方法で私としてログインできたとしたら、確かにkeychainは彼らに私のリモート・アカウントへのアクセスを許可するはずです。しかし、たとえそうだとしても、侵入者が私の暗号化解除済みの私有鍵を盗むことは極めて困難なはずです。なぜなら、ディスク上では暗号化されたままであるからです。また、私の私有鍵にアクセスするには、私のディレクトリー内のファイルを単に読みとるだけではなく、実際に私としてログインする必要もあります。したがって、ssh-agentの不正使用は、暗号化されていない私有鍵を単に盗む場合(侵入者が私としてログインするかどうかに関係なく、何らかの方法で~/.ssh内の私のファイルにアクセスするだけでよい)よりもはるかに難しいはずです。しかし、もし侵入者が私としてログインすることに成功した場合、私の暗号化解除済みの私有鍵を利用してさらにかなりの損害を与えることができるでしょう。したがって、あまり頻繁にはログインしないサーバーやセキュリティーの監視をしっかりと行っていないサーバーでkeychainを使用する場合は、--clearオプションによってセキュリティー・レイヤーを追加することを検討してください。

--clearオプションを使用すると、そうでないことが証明されるまで、アカウントに対するすべての新規ログインをセキュリティー・ブリーチであるとみなすようにkeychainに指示することができます。--clearオプションを付けてkeychainを起動すると、keychainはログイン時にssh-agentのキャッシュからすべての私有鍵を直ちにフラッシュしてから、通常の操作を実行します。したがって、keychainは侵入者に対して、キャッシュされた既存の鍵にアクセスできるようにするのではなく、パスフレーズの入力を要求します。ただし、これによってたとえセキュリティーが向上するとしてもやや不便になり、keychainを使用せずにssh-agentのみを実行するのとほとんど同じになります。よくあることですが、セキュリティーの向上と利便性の向上を両立させることは難しいということです。

とは言え、--clearオプションを付けてkeychainを使用する方がssh-agentだけを使用するよりやはり有利です。ここで覚えておいていただきたいのは、keychain --clearを使用してもcronジョブやスクリプトは引き続きパスワード不要の接続を確立できるということです。これは、私有鍵がログイン時にはフラッシュされても、ログアウト時にはフラッシュされないためです。システムからのログアウトにセキュリティー・ブリーチの可能性はないため、keychainssh-agentの鍵をフラッシュして応答する必要はありません。したがって、--clearオプションは、バックアップ・サーバー、ファイアウォール、ルーターなど、セキュアなコピー・タスクの実行が頻繁には必要とされない、アクセス頻度の低いサーバーに理想的です。


まとめ

これでOpenSSH鍵管理の連載は終わりです。読者の皆さんはRSA/DSA鍵についての理解が深まり、RSA/DSA鍵の便利かつセキュアな使用方法がお分かりになったことと思います。以下の参考文献をチェックすることもお忘れなく。

参考文献

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Linux, Open source
ArticleID=228927
ArticleTitle=共通テーマ: OpenSSH キー (鍵) の管理: 第 2 回
publish-date=09012001