UNIXを利用する場合には, パスワードを入力してユーザ認証を受ける. リモートアクセスについてホスト認証は非常に弱く, IPアドレス偽装などの不正アクセスの攻撃に弱い.
SSHは不正アクセスを防ぐために, 暗号技術を使って, クライアントによるサーバホストの認証を行なう. サーバホスト認証が終了した後には, すべての通信を暗号化して通信内容の保護を行なう. 続いてサーバホストによるユーザ認証が行なわれる.
この節では SSH による認証がどのように行なわれるかを説明する. ここでは, より広く使われているSSH1を中心にして説明し, SSH2については部分的にコメントを述べる*7. 具体的なファイル名の対応関係などは 4.3節の表を参照のこと. 認証について更に詳しく知りたい方は, [e14]を参照のこと.
ホスト認証時には同時に, 通信の暗号化を行なう共有鍵暗号システムで使用する session key の交換が行なわれる.
SSH1 によるログインでは,公開鍵暗号システムRSAを用いてサーバホストの認証および session key の交換が行われる (RSA 方式と呼ぶ). SSH2 では RSA 方式に加えて, 認証を公開鍵暗号システムDSAで, session key の交換は Diffie-Hellman 鍵配送方式[6]で行う方式が使われおり, 後者が標準になっている.
ここでは SSH1 で使われている RSA 方式 について説明する. RSA 方式ではホスト認証に, ホスト固有の host-key と, サーバ起動時に作られる server-key の2つの鍵が使用される. この間の, 処理の手順は表 1の通りである.
Seq. | SSH client | Data flow | sshd, SSH-server |
---|---|---|---|
1 | 接続の要求を送る | ---------> | |
2 | 送られてきた host-key を確認する. | <--------- | host-key と server-key を送る |
3 | Session-key を作り host-key および server-key を用いて暗号化して送る. | ---------> | Private-key により session-key を復号化する |
クライアントから要求があるとサーバは public host-key と public server-key, それと併せて自分がサポートする共有鍵暗号システムのリストをクライアントに送る. クライアントは送られてきた host-key を, 自分の known host key データベース*8に既に登録してある host-key と比較して, host-key が一致することを確認する. 次に, 通信の暗号化に使う 256-bit の session key を, 乱数を使って作成する. 作成した session key をサーバから受け取った public host-key および public server-key を用いて暗号化する. また, 通信に使用する暗号システムを, 送られてきたリストの中から選択する. 暗号化した session key と選択した暗号システムをサーバに送る. サーバは受け取った session key の復号化を, private host-key および private server-key を用いて行なう. 復号化ができたことで, 正当なサーバであるとクライアント側は判断できる.
以上の手順でホスト認証が成立し, 暗号化のための session key を双方で共有することができた.
サーバホスト認証の過程で扱う暗号鍵を整理すると, 以下の通りである.
1024-bitのRSA keyあるいはDSA keyでホスト認証のために使われる. SSH のサーバデーモンであるsshdのインストール時に作成される. ssh-keygen を用いてキーの大きさを変更することができる.
SSHクライアントは, アクセスしようとするSSHサーバのpublic host-keyを入手して自分の known host key データベースに登録する必要がある. 実際には, クライアントがSSHサーバに最初にアクセスしたときに, サーバのpublic host-keyを登録するかどうかの問い合わせがあり, 確認して “yes” を答えると自動的に登録される.
Private host-keyは SSHサーバだけが持ち厳重に管理する.
Server-keyは768-bitの RSA keyでホスト認証のために使われる. sshd 起動時に作成され, その後1時間毎に自動的に更新される. ファイルに保存されることがない. Server-keyの目的は, host keyで暗号化した通信を記録して解読されることを防ぐことにある. この一定時間ごとに変化する Server-key で修飾することにより暗号の解読を困難にしている.
SSHではセッションの通信が, 共有鍵暗号方式により暗号化される. Session key はセッションの通信の暗号化に用いられる 256ビット長の乱数である.
サーバによるユーザ認証は, 4つの方法が提供されている. a) UNIX 標準のパスワード認証, b) 公開鍵暗号システムによる認証(以下, 公開鍵認証と呼ぶ), c) rhosts と公開鍵暗号システムを組み合わせた方式による認証(以下, rhosts公開鍵認証と呼ぶ), d) rhosts による認証である*9.
実際に使用される認証方式は, SSH サーバの運用方針による設定と, ユーザ側の設定によって決まる. SSHサーバは, 受け入れを許す設定になっている認証を順番に試みる. SSH1では, rhosts による認証, rhosts 公開鍵認証, 公開鍵認証, パスワード認証の順に試みる. SSH2 では, 公開鍵認証, パスワード認証の順に試みる. 例えば, ユーザが rhosts の設定も, 公開鍵の設定もしていない場合には, 最後のパスワード認証が行なわれ, 公開鍵の設定をしている場合には公開鍵認証が行なわれる.
UNIX 標準のパスワードによる認証の方法である. クライアントはユーザが入力したパスワードをサーバに送る. サーバは通常のパスワード認証ルーチンでチェックする. しかしパスワードは, 「4.1サーバホスト認証」で説明した session key を用いて暗号化して通信されるので, 通常の telnet などより格段に安全である.
サーバが公開鍵暗号システムを使用してユーザ認証を行なう方法である. これを利用しようとするユーザは, 前もって SSHクライアントホストで ssh-keygen を使って1組の public-key と private-key を準備する. SSH1 では RSA keyが, SSH2 では DSA key が標準になっている.
鍵を作成する時に passphrase の入力が求められるが, これはファイルに保存する private-key を暗号化するためのパスワードであり, 安全に保管するための措置である. Passphrase には非常に長い文字列を指定できるので, 単語ではなく, 自分で覚えやすく, 他人には分かりにくい文章となるような文字列を選ぶ. Private-key は鍵を作成したホスト内だけで厳重に管理し, 他のホストには転送しない. Public-key は SSH サーバとする予定のホストに送り, authorized_keys ファイルに登録する.
公開鍵暗号システム RSA によるユーザ認証の手順を表 2 に示す. ログイン要求時に, SSH クライアントはユーザ名と public-key を SSH サーバに送る. SSH サーバは, そのユーザの authorized_keys ファイルを探す. public-key を確認できると乱数を発生させ, その乱数を public-key で暗号化したデータ ( challenge と呼ぶ ) を作成してクライアントに送る. クライアントは, private-key とユーザが入力する passphrase により challenge を復号化する. 次に, 復号化したデータのチェックサムをハッシュ関数 MD5 で作成し, その計算結果をサーバに送り返す. サーバ自身も乱数の MD5 を作成し, 送られてきたデータと比較して, 一致していればユーザ認証が成立する.
この認証方式は, private-key を持ち, そして passphrase を知っている本人だけが challenge を復号化できるということで, 安全性の高い認証方式である.
Seq. |
SSH client | Data flow | sshd, SSH-server |
1 | Username と public-key を送る. | -------------> | public-keyを確認する. |
2 | private-key と pass-phrase によりchallenge を復号化する. | <------------- | 乱数を発生させpublic-key で暗号化した challengeを作成して送る. |
3 | 復号化したデータのMD5 チェックサムを作成して送る. | -------------> | 乱数の MD5 チェックサムを作成し, 送られてきたチェックサムと比較する. |
サーバが rhostsによるユーザ認証と公開鍵暗号システムによるクライアントホストの認証を併用して行なう方式である*10. これを利用しようとするユーザは, 前もってクライアントホストの public host-key をサーバの known host key データベースに登録しておく.
処理手順を 表 3 に示す. ログイン要求時に, SSH クライアントはユーザ名と public host-key を SSH サーバに送る. SSHサーバは, rhosts 関連のファイルを探して, クライアントのホスト名およびユーザ名が登録されているかどうかを調べる. 登録されている場合にはクライアントの public host-key を known host keyデータベースの中で検索する. Host-keyが見つかった場合には, 乱数を発生させて, その乱数をhost-keyで暗号化したchallengeを作成して, クライアントに送る. クライアントは, challenge を private host-keyにより復号化して, そのデータのチェックサムをハッシュ関数 MD5で作成する. その計算結果をサーバに送り返す. サーバは乱数のMD5を作成し, 送られてきたデータと比較して, 一致していれば認証が成立する. このように rhosts 公開鍵認証では, 認証にユーザの passphrase またはパスワードを使用しない.
rhosts関連のファイルとは, /etc/hosts.equiv, $HOME/.rhosts, /etc/shosts.equiv および$HOME/.shostsである. 前2者は, rhosts のファイルそのままであり, 後2者はSSH固有のファイルである. 内容の記述の仕方は同じである.
Seq. | SSH client | Data flow | sshd, SSH-server |
1 | Username とpublic host-keyを送る. | -------------> | rhosts を確認する. 次にpublic host-key を確認する. |
2 | Private host_key によりchallenge を復号化する. | <------------- | 乱数を発生させて, クライアントのpublic host-key で暗号化したchallengeを作成して送る. |
3 | 復号化したデータのMD5 チェックサムを作成して送る. | -------------> | 乱数のMD5 チェックサムを作成し, 送られてきたチェックサムと比較する. |
この方式では, サーバがクライアントホストの認証をおこなっている. しかしユーザ認証は, ホスト認証で代用している. ユーザにとっては便利であるが, サーバのセキュリティはクライアントホストに依存するという点で弱くなる.
サーバは, UNIX 標準の .rhostsおよび /etc/hosts.equivによるユーザ認証を行なうだけである. ファイルに記載されているクライアントホストとユーザを信頼するものである. 実質的な認証は行なわないので, IP偽装攻撃, DSN偽装攻撃, routing偽装攻撃に関して無防備であり, かつサーバホストはクライアントホストのセキュリティに依存することになる. SSH1 ではサポートされているが, 標準で無効になっている. これは使うべきでない. SSH2 ではサポートされていない.
SSH関係の主なファイルをSSH1とSSH2で比較したものが表 4 である.
$HOME はユーザのホームディレクトリを示している. Host key および User's key のうち, ファイル名に “.pub” が付いているものが公開鍵 (public key) で, 付いていないものが秘密鍵 (private-key) である. 参照の欄の「サーバ」は SSHサーバ側で参照するファイル, 「クライアント」は SSH クライアント側で参照するファイルである. * 印がついているものは, Rhosts公開鍵認証の場合のみに参照されるファイルである.
表 4 SSHの主なファイル
種類 | SSH1 | SSH2 | 参照 |
Configuration | /etc/sshd_config | /etc/ssh2/sshd2_config | サーバ |
/etc/ssh_config | /etc/ssh2/ssh2_config | クライアント | |
$HOME/.ssh/config | $HOME/.ssh2/ssh2_config | サーバ/クライアント | |
Host key | /etc/ssh_host_key /etc/ssh_host_key.pub |
/etc/ssh2/hostkey /etc/ssh2/hostkey.pub |
サーバ/クライアント* |
/etc/ssh_known_hosts | クライアント | ||
$HOME/.ssh/known_hosts | $HOME/.ssh2/hostkeys/key_22_*.pub | クライアント/サーバ* | |
User's key | $HOME/.ssh/identity $HOME/.ssh/identity.pub |
$HOME/.ssh2/identification $HOME/.ssh2/id_dsa_nnnn_a $HOME/.ssh2/id_dsa_nnnn_a.pub |
クライアント |
$HOME/.ssh/authorized_keys | $HOME/.ssh2/authorization $HOME/.ssh2/id_dsa_nnnn_a.pub |
サーバ | |
乱数シード | /etc/ssh_random_seed | /etc/ssh2/random_seed | サーバ |
$HOME/.ssh/random_seed | $HOME/.ssh2/random_seed | サーバ | |
Rhosts 関連 | /etc/hosts.equiv, /etc/shosts.equiv $HOME/.rhosts, $HOME/.shosts |
サーバ | |
Shell 環境. | /etc/environment $HOME/.ssh/environment |
/etc/environment $HOME/.ssh2/environment |
サーバ |