今更SSHとは何? なんて遅れているなと言われそうですが、SSHの仕組みは結構複雑なので、私のような素人の解説でも人によっては意味があるだろうと勝手に決め込んで書きました。SSH通信の原理を知るという教養番組みたいなものですので、具体的な設定法にのみ興味のある方はこの章をスキップしてください。
SSHの発明者(Tatu Ylonen)がある時期に会社(SSH Communications Security)(日本SSH社はここ)を起こして商用SSHを売り出してから、SSHは自由に使えなくなりました。そこで元々の公開されていたSSHをベースに本質は維持しつつ特許に抵触する部分を全部取り払って改良を加えたものがOpenSSHです。ユニックスのFreeBSD用に開発され、他のOSにも移植されています。つまりSSHにはこの「商品としてのSSH」と「SSHという通信の仕組み」という二重の意味があります。OpenSSHを学習したければ「OpenSSH/セキュリティ管理ガイド:新山祐介/春山征吾著」がお奨め。サポートページもしっかりしています。OpenSSHのオフィシャルサイトやOpenSSH情報などでもいろいろな情報が見られます。日本語訳はここで見られます。 OpenSSHと商用SSHの内容の違いはここに説明してあります。Cygwin用に移植されたのがCygwin/OpenSSHです。私がここで扱う実際のプログラムですが、中身がSSHであることに変わりはありません。
目的地に通信を送りたい場合にインターネットに乗せますが、通信回路は網のように張り巡らされています。通信は一度に相手に届くのではなく、一つ一つの網の結び目がデータを受け取り再び送り出すことの繰り返しです。結び目の一つを悪意を持つ人がコントロールすると、通信内容を盗聴したり、通信相手になりすまして(man in the middle)悪さをしたり詐欺を働くことが可能です。遠隔地のサーバーと通信したり、データのやりとりする方法として、以前はリモートホストへのログインには telnet が、ファイル転送には ftp コマンドが良く使われましたが、もはや安全ではありません。これに代わって登場した方式がSSH通信方式です。telnetには slogin あるいは ssh が、ftp には sftp 命令が対応します。使い方はほとんど同じなので、クライアントソフトを使う分には、SSHの仕組みを知らなくてもそれほど不自由は感じませんが、サーバーを設置するには仕組みをある程度理解しておく必要があります。SSHにはプロトコル1バージョンとプロトコル2バージョンがあり互換性はありません。プロトコル2方式の方が安全性が高いので、いずれはこちらに移行すると思われます。ただし、中身はともかく設定法はヴァージョン1、2でほとんど同じです。
ユーザーがサーバーを訪問するときはサーバーと話し合いを始める前に、まずお互いにSSHのどちらのプロトコルを使うかを決めます。OpenSSHの場合はまずプロトコル2が使用可能かをチェックして、用意されていない時はプロトコル1に移るように設定できます。もちろんプロトコル1もしくは2を単独で使うこともできます。ここまでは暗号化せずに交信を行います。安全を確保するためにSSHで採用しているプロセスは、
(1)通信の暗号化 (2)サーバー認証 (3)ユーザー認証
の3通りよりなります。(1)は盗聴を防ぐため、(2)(3)はなりすましを防ぐためです。
暗号化には共通鍵方式と公開鍵方式の二通りあります。共通鍵方式は文章の暗号化と復号化に同じキー(共通鍵)を使います。公開鍵方式は秘密鍵と公開鍵の二つの鍵を用意し、公開鍵で暗号化し秘密鍵で復号化します。公開鍵で暗号化した文章は公開鍵では復号化できないので公開しても(一応は)安全です。通信者同士がすでに共通鍵を保有している場合は共通鍵方式が早くて便利ですが、相手の見えないインターネット通信では共通鍵自身をも転送しなければならずそこに危険が生じます。公開鍵方式にはその危険性はありませんが計算に時間がかかるという欠点を持っています。そこでSSHでは公開鍵を使って暗号化した共通鍵を共有し、以後はこの共通鍵を使って通信のやりとりをすることにしています。共通鍵の暗号化には「3DES」「Blowfish」「AES」方式などがあります。公開鍵の暗号化はプロトコル1では「RSA」方式を使います。プロトコル2では暗号化は「RSA」もしくは「DSA」方式を使いますが、同じRSA方式でもプロトコル1と2の互換性はありません。
サーバ認証とは、ユーザーがサーバーに接触するとき相手サーバーが偽者でないことを確認する手続きです。
ユーザーが接触してきたとき、サーバーは自分自身のホストを認証させるためのホスト認証キーという公開鍵の対を作り、公開鍵(※1)をサーバーIPアドレスやホスト名と共にユーザーに渡します。ユーザーはその公開鍵を既知のホストとしてユーザープログラムの「known_hosts」ファイルに入れておきます。サーバーもまたユーザーのホスト情報を入れておく「known_hosts」ファイルを持ちます。ユーザーがサーバーに接続したときユーザーはサーバーのホスト認証公開鍵をチェックして正しいサーバーであることを知ります。
(※1 ちょっとまぎらわしいのですが、秘密鍵と公開鍵のペアを公開鍵の対、ペアの一つとしての公開鍵を単に公開鍵と呼ぶことにします。)
ただし、ユーザーが始めてサーバーに接触したときは、サーバーホスト名は未登録ですので、サーバーは 自分の身分証明書を呈示した上でなおかつ自分は偽物かも知れないよとユーザーに警告を出します。 より正確に言えば、サーバーは生成したホスト鍵の指紋 ( finger print:16個の16進法の二桁文字、ただしGUI環境ではこれも表に出さないことが多い ) をユーザーに提示します (第1章でサーバー構築後の ssh localhost に対する応答を見で下さい )。ユーザーはこの指紋を見て管理者に電話などで身元確認をするわけです。しかし、我々レベルのユーザーは通常はそこまではしないでしょう。警告を受けても相手を信用してOKを出すのが普通です。従って第一回目の接触時だけは安全性が保証されていません。しかし、2回目以降の通信は登録されているホストに繋がるはずですから、もし警告が出たら要注意です。
サーバーに入ってくるユーザーが確かに本人であることをサーバーが確認する手続きです。
<公開鍵認証による方法> 「公開鍵認証」(プロトコル1ではRSA検証)を使う場合は、ユーザーもしくはサーバー管理者が認証用の公開鍵と秘密鍵のペアを作り、秘密鍵はユーザーが保持して公開鍵はあらかじめ何らかの方法でサーバーに登録しておきます。フロッピーなどで直接持ち込むのがベストですが、そう簡単ではありませんよね。ユーザーが接触してくるとサーバーはユーザの公開鍵を使ってユーザーに暗号化した謎かけをします(※2)。ユーザーは自分の秘密鍵を使って復号化し答えをサーバー側に戻します。サーバーはそれを検証して正しい答えが得られれば正しいユーザーと認めます。
(※2 サーバーは乱数を発生させユーザーの公開鍵で暗号化しユーザーに送ります。これをチャレンジと呼びます。ユーザーは自分の秘密鍵で復号化したデータをハッシュ関数と呼ばれる関数を使って200ビット程度のチェックサムと呼ばれる数値を作り送り返します(レスポンス)。サーバーは正しいチェックサムが帰って来るかどうかをチェックするのです。ハッシュ関数はデータの一部でも変化すると値が大きく変わると言う性質を持っておりデータ改竄の検出に良く使われます。)
<パスワード認証による方法> 従来のパスワードログイン方式と同じですが、パスワードが暗号化されているので安全性は高まっています。暗号化は次に述べる共通鍵の暗号化と同じ方式で行われます。しかし、暗号化されているとはいえパスワード自身がネットワークに乗りますので、やはり危険はあるわけで公開鍵方式に比べると安全度が低くなります。ただし、ユーザーの公開鍵をサーバーに渡す手段として、とりあえず暗号化通信を確保したいときなどには役に立ちます。公開鍵は一応見られても差し支えないことにはなっていて、メイルでも送ることは可能ですが危険は少しでも避けなければいけません。
<ホスト認証による方法> ユーザーを見ないでユーザーホストだけを認証する方法です。安全性が落ちるので通常は推奨されません。企業内特定作業グループなどで効率運用を図るときなどに使います。
SSHプロトコル1方式の場合: サーバー検証とユーザー検証が終わると本来の目的の通信をはじめます。このときサーバーはサーバーキーと呼ばれる公開鍵のペアを作り公開鍵をユーザーに渡します(※3)。ユーザーはサーバーのホスト認証キーとサーバーキーを両方使って自分が作った共通鍵 ( セッションキー ) を暗号化してサーバーに渡します。これ以降の通信はこの共通鍵で暗号化/復号化します。この暗号化方式では、サーバーキーは接続の度に違うキーが作られ、また接続中も定期的に変更されるので高い安全性が確保されます。ユーザーの秘密鍵は普段はパスフレーズで暗号化して格納しておき、交信時に復号化して使うのでさらに安全性が高まります。
(※3 実際にはユーザーが接触したときホスト認証キーと同時に渡されています。)
SSH2プロトコル2方式の場合: サーバー鍵を使わないで共通鍵をつくります。公開鍵方式に似ていますが、公開鍵秘密鍵のペアを使いません。 Diffie-Hellman方式と言って、双方で独立に発生させた乱数を、共有の鍵(秘密にする必要はない)を 使って暗号化した上で交換し、双方で全く同じ共通鍵を作る方法です。
パスワードよりは長いという意味です。スペース文字が使えるので、「sergeant peppers lonely heart club band」みたいな覚え易くて長い文章をつくれます。ただし、良いパスフレーズとは、文法ミスがあり一部数字と入れ替わっている文です。理想的には長くて意味のない文字の羅列が最良ですが、覚えられなくて書き留めたりしたら効果激減ですからね。ユーザーの秘密鍵をパスフレーズで暗号化して収納しておき、交信を始めるときパスフレーズで秘密鍵を復号化し、その秘密鍵でサーバーから渡された暗号文を復号化します。パスワードと違ってパスフレーズはインターネットに乗ることはありません。SSH通信の公開鍵認証方式では、暗号化復号化に使われるキーが全くインターネット上に乗らないということで安全性を高めているのです。
SSHを使うと言っても、ここでは私と同じように基本的にはウインドウズ GUI クライアントを使う人を対象にしていますので、ユニックス用のコマンドを紹介する意味はあまりないのですが、せっかくCygwinを導入したからにはもう一歩深く踏み込みたい人のため、SSH関連のコマンドリストを挙げておきます。
使い方は、パッケージの中のマニュアル(/usr/share/man/man1, 8)か、OpenSSH仕様のマニュアル( 日本語訳はこちら)を見てください。何ができるか、使用オプション、ファイル構造、用語などに疑問が出たときに頼れるところです。無精してすみません。
表2.1 OpenSSHのコマンド
◆ssh: SSHクライアント。遠隔地との暗号化交信用コマンド。機能は旧telnet、rloginと同じ。
◆sshd: SSHサーバーデーモン。サービスの提供。
◆sftp: 遠隔地間データの大量転送に使われる ftp のSSH版。
◆sftp-server: sftp サービスを提供するデーモン。
◆ssh-keygen: 暗号鍵生成ツール。
◆ssh-keysign: プロトコルヴァージョン2で使用する。ホスト認証の際デジタル署名を生成する。
◆ssh-agent: 認証エージェント。秘密鍵を登録することによりパスフレーズの打ち込みを省略できる。
◆ssh-add: 認証エージェントに秘密鍵を登録するコマンド
◆ssh-keyscan: ホスト認証公開鍵の収集ツール。Known_hostsファイルを作るとき使う。
以上のお話は、世の中に流布している解説書、と言っても私が偶然目にしたもののみですが、ここから一文、あそこから二文とつぎはぎして作ったものです。オリジナルに勝る物はありませんし、教えていただいたことに謝意を表して少し紹介しておきます。といっていちいち丁寧に目を通した訳じゃないですけれど。本当にこれ全部呼んだらもう専門家ですよね、多分。
「OpenSSH/セキュリティ管理ガイド:新山祐介/春山征吾著、秀和システム発行」
正誤表・補遺がサポートサイトに置いてあります。この本は体系的にまとめてあって且つ実用性も考慮したお奨め品です。私の知識はもっぱらここから来ています。「OpenSSHオフィシャルサイト」 英語版本家と日本語本家が組み込まれています。
「OpenSSHマニュアルページ」 日本語訳はここ SSH関連コマンドマニュアル。
「OpenSSH on Windows」 ウインドウズで働くもう一つのOpenSSHです。Cygwin/OpenSSHと同じくCygwin上で動きますが、OpenSSHに最適化しているのでファイルサイズははるかに小さくなっています。ただし、 cygwin のレジストリーを変えるので cygwin の他の機能を使いたい人には向いていません。
大きいものを読むのはしんどいので、要点を要領よくまとめた小さな解説が欲しいと言う人には
「Cygwin/Open.readme」:りうさん。重月計画は cygwin 関連の記事が充実しています。
「OpenSSHを使う」:新山祐介さん
「OpenSSH-HOWTO」: WATABE Toyokazu さん
「SSHってかんたんなのね」:TANNO Hajime さん
「Tera Term Pro + TTSSHの導入と使いかた」: SHINDO Yasutaka さん
後の二つはウインドウズのSSHクライアントの実践的な解説でもあります。ただし、TTSSHはヴァージョン2には対応していません。ヴァージョン2対応の telnet 型クライアントの PuTTY と ftp 型クライアントの WinSCP の使い方を以下に挙げておきます。
「WinSCP 日本語サイト」: 田淵さん
「WinSCPの使い方」: Dream-Seed さん
「WinSCP3の利用について」: Explorer 窓使用での詳細な解説です。
「PuTTY によるSSH1/2 接続」: KATAYAMA Yosinori さん
「PuTTYによるWindows上でのSSH接続」: SHIMADA Mitsunobu さん
SSHが商用化されてからはフリーソフト関連の記事はOpenSSHに移りましたが、それ以前の情報も結構役に立ちますので挙げておきます。
「SSH Communications Security」「日本SSH社」商用SSHの本家です。