SSH の安全性とその原理

ここでは、 SSH (Secure Shell) がどのように安全なのか、その原理から説明する。 まず、 SSH とは何なのか概略を説明した後、 SSH の特徴である認証方式通信路の暗号化について説明する。 そして、まとめとして従来のものに対する優位性を議論し、 最後にサイトに導入するときの運用方針について考える。

SSH とは

リモートログインのためのプロトコルとその実装 (クライアント/サーバ)

SSH のユーザインターフェイス (クライアントコマンド)
機能ssh のコマンド従来のコマンド
リモートログインssh (slogin)telnet, rlogin
リモートでのコマンド実行sshrsh
ファイル転送scprcp
sftpftp

暗号技術を利用することで、強い安全性を確保。

  1. RSA 公開鍵暗号系を用いた認証
  2. 通信路の暗号化

付加的な機能として、任意の TCP/IP の通信を中継することができる。 特に X11 はデフォルトで中継し、ユーザが (DISPLAY 環境変数, xhost 等) 何もしなくてもリモートの X のアプリケーションを立ち上げることができる。

認証

次の3つの方法があり、この順に試される。

  1. Rhosts with RSA host authentication
  2. RSA authentication
  3. Password authentication

このうち 1. と 2. は、 RSA 公開鍵暗号系を認証に用いる。 1. はホストに対して RSA で認証を行い、 2. はユーザに対して RSA で認証を行う。

公開鍵暗号系は、2つの鍵 (秘密鍵と公開鍵) を使う。 公開鍵で暗号化したものは秘密鍵で復号できる。 秘密鍵を誰にも教えなくても暗号通信ができる。

秘密鍵は所有者しか知らないという性質を、認証に使うことができる。 基本的なやり方は、

  1. サーバがランダムなビット列 (challenge) を作る。 (ssh では 256bit)
  2. 認証したいホストまたはユーザの公開鍵で暗号化してクライアントに送る。
  3. クライアントは、サーバから送られてきた暗号化された challenge を、 秘密鍵で復号する。
  4. 復号した結果をサーバに送り返す。
  5. サーバは、送り返されたものから、クライアントがきちんと復号できたか どうかを見て、復号できていれば認証に成功、そうでなければ失敗となる。

RSA による認証は、秘密鍵は所有者しか知らないという仮定の上に 成り立っているので、秘密鍵の管理は厳重に行わなければならない。

ssh のサーバがインストールされているすべてのホストは、自身の秘密鍵と 公開鍵の対を持っている。ホストの秘密鍵を保存するファイルは、 root によって所有され、 root 以外には読み書きできないようになっている。 ssh のクライアントは、 root に setuid されていて root 権限で動くので、 ホストの鍵を読むことができて、それを使って rhosts の認証を受けることができる。

ユーザが自分の鍵対を作ることもできる (ssh-keygen)。 秘密鍵をファイルに保存するとき、パスフレーズで暗号化する必要がある。 パスフレーズで暗号化せずに鍵対を作るのは、パスワードをそのままファイルに 書くようなもの。また、ユーザのホームディレクトリに NFS を使っている場合は、 ネットワークをそのまま流れるということにも注意。 鍵を使うときはいちいちパスフレーズを入力しないといけないが、 これを一回で済ます方法もある (ssh-agent)。

Rhosts with RSA host authentication

rsh の .rhosts ファイルを使った認証方式に加えて、 RSA を使ってクライアントホストを認証する。

rsh の認証は、 .rhosts ファイルに書かれているユーザ@ホストからの アクセスはパスワードなしで認められるというもの。 ホスト名は DNS spoofing という方法で騙すことができ、ユーザ名は自己申告なので、 そのままではかなり危険。 ssh では、 RSA を使って、ホストが本物であることを確かめている。

この認証が通るためには、サーバ側がクライアントホストの公開鍵を 知っている (i.e. クライアントホストの公開鍵がホストまたは ユーザの「知っているホストのリスト」に入っている) 必要がある。

セッションの暗号化

ssh では、セッションの暗号化には共通鍵暗号系を使う。 鍵はセッション毎に作られて、受け渡しは次のように行われる。 なお、ここで使われるサーバの鍵というのは、ホストの鍵とは別に サーバのメモリ上だけにあるもので、一時間毎に作り替えられる。

  1. サーバ側からクライアントに、ホストの公開鍵とサーバの公開鍵を提示する。
  2. クライアントがセッション鍵 (256bit のランダムなビット列) を生成する。
  3. クライアントがセッション鍵をホストの公開鍵とサーバの公開鍵で暗号化し、 サーバに送る。
  4. サーバは送られたセッション鍵をホストの秘密鍵とサーバの秘密鍵で復号する。
  5. ここから後のすべての通信は、このセッション鍵で暗号化される。
    サーバは、確認のメッセージ (暗号化されている) をクライアントに送る。
  6. クライアントは、サーバからのメッセージが確認できると、次の認証の段階に 移る。鍵が正しく渡されていなければ、サーバからのメッセージが確認できない。 このときは、接続を中断する。

この手続きはユーザ認証の手続きよりも前に行われる。 つまり、 password authentication で送られるパスワードは、 ネットワークを暗号化された状態で流れる。

ssh の暗号化は、盗聴に強いだけでなく、偽のパケットを送り込んだりといった 能動的な攻撃にも強い (らしい)。 暗号化を行わない従来のプロトコルでは、このような攻撃にはどうしようもない。

サーバホストの認証

セッション鍵の受け渡しの手続きで、サーバが正しい秘密鍵を知っていないと、 セッション鍵を復号することができず、クライアントが正しく復号できる 確認メッセージを作ることができない。このことで、サーバホストが認証できる。

また、 ssh の実装では、ホストの公開鍵が示されたとき、クライアントは、 それが以前と変わっていないかどうかチェックする。 初めてのホストのときは、ユーザに接続していいかどうか聞く。 一旦接続すると、相手の公開鍵がユーザの「公開鍵を知っているホストのリスト」に 書き加えられる。 リストとの照合は、コマンド行引数に与えられた文字列そのもので比較する。 例えば ``hoge'' と ``hoge.c.u-tokyo.ac.jp'' は別物。 このリストは、 rhosts の認証でも使われる。

まとめ

ssh は、特に rsh, rlogin に対する優位性が高い。 rsh は世界中のどこかのネームサーバが cracker に支配されると 不正侵入される危険があるが、 ssh はローカルのネームサーバが crack されても安全 (?)。 ssh は、きちんと設定すると、 rsh と全く同じように、 ユーザがパスワードを入力することなしに使うことができる。

telnet に対しては、暗号化される点で優位。 特に、パスワード入力の部分が暗号化されることが重要。

ssh が X を中継するので、リスクを含む xhost でリモートホストに アクセス許可を出すということをしなくて済む。

運用方針の例

ssh を導入しても、従来の telnet や rlogin をやめなければ セキュリティの向上にはならない。かといって、急にやめるのは難しい。 まずは TCP wrapper を使ってアクセス制限するのがいいのではないか。 特に rsh, rlogin については、ローカルに制限した方がいい。 ローカルドメイン内では、ネームサーバが信用できるので、 rsh, rlogin の 危険性はそれほど深刻ではないだろう。

ただし、 root のパスワードを打ったり、 root 権限でコマンド実行したり するときは、 ssh を使うようにするべきではないか。



西村 大介 <nishi@graco.c.u-tokyo.ac.jp>
1998年12月10日(木) 15時48分 3秒 最終更新