ここでは、 SSH (Secure Shell) がどのように安全なのか、その原理から説明する。 まず、 SSH とは何なのか概略を説明した後、 SSH の特徴である認証方式と 通信路の暗号化について説明する。 そして、まとめとして従来のものに対する優位性を議論し、 最後にサイトに導入するときの運用方針について考える。
リモートログインのためのプロトコルとその実装 (クライアント/サーバ)
| 機能 | ssh のコマンド | 従来のコマンド |
|---|---|---|
| リモートログイン | ssh (slogin) | telnet, rlogin |
| リモートでのコマンド実行 | ssh | rsh |
| ファイル転送 | scp | rcp |
| sftp | ftp |
暗号技術を利用することで、強い安全性を確保。
付加的な機能として、任意の TCP/IP の通信を中継することができる。 特に X11 はデフォルトで中継し、ユーザが (DISPLAY 環境変数, xhost 等) 何もしなくてもリモートの X のアプリケーションを立ち上げることができる。
次の3つの方法があり、この順に試される。
このうち 1. と 2. は、 RSA 公開鍵暗号系を認証に用いる。 1. はホストに対して RSA で認証を行い、 2. はユーザに対して RSA で認証を行う。
公開鍵暗号系は、2つの鍵 (秘密鍵と公開鍵) を使う。 公開鍵で暗号化したものは秘密鍵で復号できる。 秘密鍵を誰にも教えなくても暗号通信ができる。
秘密鍵は所有者しか知らないという性質を、認証に使うことができる。 基本的なやり方は、
RSA による認証は、秘密鍵は所有者しか知らないという仮定の上に 成り立っているので、秘密鍵の管理は厳重に行わなければならない。
ssh のサーバがインストールされているすべてのホストは、自身の秘密鍵と 公開鍵の対を持っている。ホストの秘密鍵を保存するファイルは、 root によって所有され、 root 以外には読み書きできないようになっている。 ssh のクライアントは、 root に setuid されていて root 権限で動くので、 ホストの鍵を読むことができて、それを使って rhosts の認証を受けることができる。
ユーザが自分の鍵対を作ることもできる (ssh-keygen)。 秘密鍵をファイルに保存するとき、パスフレーズで暗号化する必要がある。 パスフレーズで暗号化せずに鍵対を作るのは、パスワードをそのままファイルに 書くようなもの。また、ユーザのホームディレクトリに NFS を使っている場合は、 ネットワークをそのまま流れるということにも注意。 鍵を使うときはいちいちパスフレーズを入力しないといけないが、 これを一回で済ます方法もある (ssh-agent)。
rsh の .rhosts ファイルを使った認証方式に加えて、 RSA を使ってクライアントホストを認証する。
rsh の認証は、 .rhosts ファイルに書かれているユーザ@ホストからの アクセスはパスワードなしで認められるというもの。 ホスト名は DNS spoofing という方法で騙すことができ、ユーザ名は自己申告なので、 そのままではかなり危険。 ssh では、 RSA を使って、ホストが本物であることを確かめている。
この認証が通るためには、サーバ側がクライアントホストの公開鍵を 知っている (i.e. クライアントホストの公開鍵がホストまたは ユーザの「知っているホストのリスト」に入っている) 必要がある。
ssh では、セッションの暗号化には共通鍵暗号系を使う。 鍵はセッション毎に作られて、受け渡しは次のように行われる。 なお、ここで使われるサーバの鍵というのは、ホストの鍵とは別に サーバのメモリ上だけにあるもので、一時間毎に作り替えられる。
この手続きはユーザ認証の手続きよりも前に行われる。 つまり、 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 を使うようにするべきではないか。