サイトマップ | 連絡先 | IAjapan TOP
IAjapan 財団法人インターネット協会
有害情報対策ポータルサイト 迷惑メール対策編
  • 一般利用者の皆様へ
  • メール管理者の皆様へ
  • 関連情報
  • サイト紹介

TLS のひみつ

IIJ
技術研究所
山本和彦
2008年2月

1.SSL
2.TLS
3.ラッパーとしての TLS
4.蛇足

SSL(Secure Socket Layer)はラッパー(トンネル)として実装できるが、TLS(Transport Layer Security)はラッパーとして実装できないと勘違いしているエンジニアが多い。この記事では、(少なくともクライアント側では)TLS がラッパーとして実装でき、アプリケーションプログラムの実装を変更しなくても TLS が利用できることを示す。

1. SSL

あるアプリケーションサービスを SSL を用いて保護するときは、別途ポートを用意しなければならない。たとえば、HTTP(80)を SSL で守るために、HTTPS(443)が定義されている。

このポートの分離のおかげで、HTTPS を見張るプログラムは通信がはじめから暗号文であると決め打ちできる。同様に、(当たり前ではあるが)HTTP を見張るプログラムは通信がはじめから平文であると決め打ちできる。このような条件下では、SSL をラッパーとして実装するというアイディアを思いつくのは容易い。

ここでいうラッパーとは、平文の通信と SSL の暗号通信を橋渡しするプログラムのことである。ラッパーのおかげで、既存のプログラムを変更することなく、SSL で通信を保護できる。

たとえば、HTTP サーバについて考えよう。管理者は、HTTP サーバと SSL ラッパーが通信するためのローカルホスト上のポート番号を任意に選ぶ。ここでは、12345 番ポートを選んだとする。

SSL ラッパーは、HTTPS のポートである 443 番ポートを見張る。クライアント(ブラウザ)が接続してきた場合、もちろん通信が SSL で暗号化されている(暗号通信の細かいやりとりは、今回は説明しない)。SSL ラッパーはこれを復号化し、ローカルホストの 12345 番ポートへ平文のデータを転送する。

HTTP サーバは、ローカルホストの 12345 番ポートを見張っている。ここには、SSL ラッパーが平文で接続してくるため、通常の HTTP として処理できる。つまり、通常は 80 番ポートを見張る HTTP サーバを、12345 番ポートを見張るように設定するだけで、SSL が利用できるわけである。

HTTP と HTTPS の両方のサービスを提供するには、デフォルトの 80 番を利用する HTTP サーバに加えて、12345 番ポートを利用するよう設定した HTTP サーバの両方を設定すればよい。

これまでサーバ側の話をしてきたが、クライアント側でも同様である。

以下に、SSL ラッパーの優れた実装である stunnel を使って、POP のクライアント側を設定する例を示す。

    % cat pop3s-client
    client=yes
    pid=
    verify=0
    foreground=yes
    debug=debug
    [12345]
    accept=127.0.0.1:12345
    connect=pop.example.com:995
    % stunnel pop3s-client

設定ファイル pop3s-client では、ローカルの 12345 番ポートに対する平文の接続を SSL で暗号化し、pop.example.com の 995 番ポート、すなわち POP3S に転送するよう定義してある。

以下のように、ローカルホストの 12345 番ポートへ接続してみると、うまく接続が転送されていることが分る。

    % telnet 127.0.0.1 12345
S:  +OK IIJ POP3 Server (pop.example.com) starting. <14663.1200725428@pop.example.com>

なお、“S:”はサーバの暗号化された出力であることを意味する。

2. TLS

SSL は Netscape 社によって設計された。これを IETF に持ち込み標準化を試みたが、そのままの形では受理されなかった。最大の原因は、SSL を利用するときに別のポートが必要だからである。

サービスごとに SSL 用のポート番号を別途割り当てていたら、ポート番号が枯渇すると危惧したわけだ。著者個人の考えとしては、なんでもかんでも 80 番ポートが利用されるこの世の中で、ポート番号が枯渇するなんてありそうにないとは思う。

IETF では、既存のポートのみでも利用できるよう SSL を改造し、TLS として標準化した。たとえば、HTTP は 80 番ポートのみで、TLS が利用できる。一方、サーバ認証や暗号通信の部分に関して言えば、TLS は SSL とほとんど同じである。

SSL ではポート番号を分離しているおかげで、平文通信と暗号通信を区別できた。TLS では、通信は平文で始まり、クライアントの合図によって暗号通信へと遷移する。この合図は、アプリケーションプロトコルごとによって異なるが、総称して START TLS と呼ばれる。

以下に POP で TLS を利用する際のやりとりを示す。

    % telnet pop.example.com 110
S|  +OK IIJ POP3 Server (pop.example.com) starting. <14663.1200725428@pop.example.com>
C|  CAPA
S|  +OK Capability list follows
S|  STLS
S|  .
C|  STLS
S|  +OK Begin TLS negotiation
C:  CAPA
S:  +OK Capability list follows
S:  .

“S”と“C”は、それぞれサーバとクライアントの出力であることを意味する。“|”は平文のままでやりとりされ、“:”の部分はネットワーク上では暗号化されて守られていることを示す。

まず、POP クライアントは、“CAPA”コマンドによりサーバの実装機能の一覧を取る。次の行で、POP 上での START TLS である“STLS”をサポートしていると、サーバが応答しているのが分る。クライアントは、“STLS”コマンドにより暗号通信の開始を告げ、サーバが“+OK”を返すことで、両端で TLS の処理が開始される。

暗号通信が利用可能になると、再びクライアントは“CAPA”コマンドを実行する。すると、サーバは何も返さないので、“STLS”コマンドはサポートされていないと分る(これにより、STLS コマンドが何回も発行されループすることを防止する)。

この例だけ見ると、TLS を利用するには POP のサーバとクライアント両方を改造し“STLS”コマンドを実装しなければならないと勘違いするのも無理はない。そして、サーバやクライアントが、低レベルな SSL/TLS のライブラリを呼べない実装である場合、「TLS はサポートできない」と思う。そして、「やっぱり SSL を使おう」ということになってしまうのだ。

しかしながら、TLS は、SSL と同様にラッパーとして実現できる。

3. ラッパーとしての TLS

論より証拠ということで、ラッパーである stunnel を用いて、TLS を利用してみよう。

    % cat pop3-tls-client
    client=yes
    pid=
    verify=0
    foreground=yes
    debug=debug
    [10985]
    accept=127.0.0.1:12345
    connect=pop.example.com:110
    protocol=pop3
    % stunnel pop3-tls-clinet

上記の例と変わったのは最後の2行である。

  • “connect”のポートが、POP3S の 995 番から、POP の 110 番へ変更された
  • “protocol=pop3”が加わった

ここでローカルホストの 12345 番ポートへ接続すると、pop.example.com の 110 番ポートに暗号路が確立された状態で接続される。

    % telnet 127.0.0.1 12345
S:  +OK IIJ POP3 Server (pop.example.com) starting. <14663.1200725428@pop.example.com>
C:  CAPA
S:  +OK Capability list follows
S:  .

証拠としては弱いが、“CAPA” コマンドに“STLS”が返って来てないので、TLS で暗号化されていると分る。心配なら、tcpdump などで中身が覗き込めるか検査してみてもいいだろう。

先ほどの通信例とこの通信例を見比べてほしい。前者からサーバの最初の挨拶だけを“:”に置き換え、そしてここが重要なのだが、残りの平文“|”の部分を削れば後者になる。この意味するところが分るだろうか?

それはつまり、SSL ラッパーに今削った部分を喋らせれば、TLS ラッパーになるということだ。

TLS の設計のキモは、状態の遷移ではなく、セッションのやり直しである。TLS によって暗号通信が開始された後は、アプリケーションプロトコルが再び最初から始まるのだ。

上記の例では、POP クライアントは最初の“CAPA”コマンドからやり直していることが分るだろう(POP が分りにくければ、SMTP で考えてみるとよい。SMTP であれば、“EHLO”コマンドからやり直す)。

最初からやり直すということは、すなわち、既存のサーバやクライアントを改良せずとも、そのまま利用できるということだ。

クライアント側の SSL ラッパーを TLS ラッパーに改造するには、以下の作業を加えればよい。

  1. サーバの挨拶を保存する
  2. START TLS コマンドをサーバへ送る
  3. サーバから OK が返されたら TLS の暗号通信を開始する
  4. 保存したサーバの挨拶をクライアントへ書き出す

“START TLS”コマンドは、アプリケーションプロトコルごとに異なる。だからこそ、“stunnel”の設定ファイルには“protocol”を指定して、どのアプリケーションプロトコルかを指示する必要がある。

サーバ側の SSL ラッパーを TLS ラッパーに改造するには、以下の点においてクライアント側よりも複雑である。

  • TLS が使われる場合と使われない場合の切り分け
  • 実装機能一覧(capability)の処理

以下に、実装機能一覧を処理する例を示す。

  • TLS が開始されてない平文通信時の実装機能一覧としては、TLS をサポートし、認証は使い捨てパスワードを要求する
  • TLS が開始された後の暗号通信の実装機能一覧としては、TLS をサポートしておらず、認証は生パスワードも許可する

なお、stunnel バージョン 4.20 では、これらを実装できてない。

4. 蛇足

重要なプロトコルに対する SSL ポートの割当状況を以下に示す。

表1 重要なプロトコルに対する SSL ポートの割当状況

プロトコル
通常ポート
SSLポート
HTTP
80
443
POP
110
995
IMAP
143
993
SMTP
25
割当なし

このように、SMTP にだけ SSL 用のポートが割り当てられていない。歴史的に言えば、465 番が割り当てられていたが取り消され、465 番は igmpv3lite というプトロコルに割り当てられた。

著者は割当機関である IANA に対し「ISP として困るので割り当てて欲しい」と申請したが、拒否された。理由は「IETF は SSL を推奨していないから」だそうである。

現在、465 番を SMTP の SSL ポートとして利用している ISP/ASP は多い。現実問題として困ることは起きないと思うが、正式ではないことを知っておくのもよいだろう。

 
リンク・転載・引用・ロゴ使用について | プライバシーポリシー | IAjapanについて | 連絡先