The Ja-Jakarta ProjectTomcat Servlet/JSP コンテナ

リンク

ユーザガイド

リファレンス

Tomcat開発

Tomcat5 サーブレット/JSP コンテナ

SSL設定の手引き

Printer Friendly Version
印刷用
バージョン
簡易スタート版

以下の説明では、Tomcat 5をインストールしたディレクトリを指すために$CATALINA_HOMEという変数名を使用します。 これは、大半の相対パスを解決していくのに必要となる基底ディレクトリです。 しかしながら、複数のインスタンスを使用するためにTomcat 5にCATALINA_BASEディレクトリを設定する場合は、 これらの各々のインスタンスで参照できるよう$CATALINA_HOMEの替わりに$CATALINA_BASEを使用してください。

Tomcat 5にSSL機能をインストールおよび設定するためには、以下の単純なステップに従う必要があります。 詳しい情報については、この手引きの続きをお読みください。

  1. JVM 1.3環境で実行しているケースでは、 http://java.sun.com/products/jsse/ からJSSE 1.0.2以降を入手してください。 そして、JVMシステム上のインストール済み拡張ライブラリにするか、JSSEをインストールしたディレクトリの位置を環境変数JSSE_HOMEに設定してください。
    [訳注: インストール済み拡張ライブラリとは、$JAVA_HOME/jre/lib/extディレクトリ配下に格納されたライブラリを示します。 ]


  2. 下記に示すコマンドを実行し、証明書のキーストアを生成してください。

    Windows:

    %JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA
    

    Unix:

    $JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA
    

    そして、パスワードに"changeit"という値を指定してください。


  3. $CATALINA_HOME/conf/server.xmlにある"SSL Coyote HTTP/1.1 Connector"欄のコメントを外し、必要に応じて設定内容を調整してください。


SSL入門

SSL(Secure Socket Layer)とは、WebブラウザとWebサーバ間でセキュアな接続の元で通信を行えるようにする技術です。 つまり、送信されるデータが片方で暗号化されて送信され、その後、処理に入る前にもう片方で復号化されます。 これは、双方向プロセスであり、データを送信する前に、サーバおよびブラウザがすべてのやり取りを暗号化することを意味します。

SSLプロトコルでもう一つ重要なのは、認証です。 つまり、セキュアな接続上でWebサーバと最初に通信を試みる間に、当該サーバは、"証明書"という形式で、誰の、何のサイトであるのかを示す証拠として、証明に必要なもの一式をWebブラウザに提示します。 また、あるケースでは、サーバ側が、あなたが誰なのかを示す証明として、Webブラウザに証明書を要求することもあります。 これは"クライアント認証"として知られていますが、実際には個人ユーザよりも、企業間電子商取引(B2B)においてより多く使われます。 SSL化されているWebサーバのほとんどは、クライアント認証を要求しません。

SSLとTomcat

セキュアソケットを利用できるようにTomcatを設定する必要があるのは、ほとんどがスタンドアローンWebサーバとして実行する場合だけであることに注意して下さい。 ApacheやMicrosoft IISといった他のWebサーバの後方のサーブレット/JSPコンテナとしてTomcatを使う場合、通常はプライマリWebサーバで、 ユーザからのSSL接続をハンドリングするように設定する必要があります。 一般に、こうしたサーバはSSL関連の機能のネゴシエーションを全て行い、Tomcatコンテナで処理させたいリクエストは復号化した後にTomcatに転送します。 同様に、Tomcatは平文のレスポンスを返し、ユーザのブラウザに返される前に暗号化されます。 このような環境において、TomcatはプライマリWebサーバとクライアントの間での通信がセキュアな接続の元で行われていることを認識しています (アプリケーションがこのことを確認できる必要があるためです)が、暗号化もしくは復号化処理自体に関与することはありません。

証明書

SSLを実装するためには、Webサーバはセキュアな接続を受け付ける各外部インターフェース(IPアドレス)ごとに証明書を用意しなければなりません。 「特に機密性の高い情報を受信する前には、サーバの所有者はユーザが想定している者であるという一種の正当な保証をサーバは提供すべき」という理論がこうした設計の背景にあります。 証明書に関するさらに一般的な説明はこのドキュメントの範囲外となりますが、証明書はインターネットアドレスの"デジタル運転免許証"のようなものと考えてください。 サイトの所有者または管理者の基本的な連絡先とともに、そのサイトがどの企業に関連しているかが証明書には記述されています。

この"運転免許証"は、その所有者によって暗号化された状態で署名されています。 したがって、他人が偽造することはきわめて困難です。E-コマースなど、身元の認証が重要となる商取引に関わるサイトでは、証明書は一般的にVeriSignやThawteといった有名な認証局(CA)より購入されます。 こうした証明書は電子的な証明が可能です -- つまり、認証局は発行した証明書の正当性を保証します。したがって、証明書を発行した認証局を信用すれば、証明書が有効であると信頼できるのです。

しかしながら多くのケースでは、実際に重要なのは認証ではありません。管理者は単に、サーバによって送受信されているデータが外部に漏れないことや、接続に対して盗聴を試みる者が詮索できないことを保証したいと思っているだけかもしれません。 幸運にもJavaでは、"自己署名"証明書を簡単に生成可能な、keytoolと呼ばれる比較的シンプルなコマンドラインツールを提供しています。 自己署名証明書はユーザが生成した証明書に過ぎず、有名な認証局より公式に発行されたわけではないので、実際には本物の証明書であることを少しも保証しません。 繰り返しますが、このことが重要かどうかは、あなたの要求次第です。

SSLを動かす上での一般的なヒント

ユーザがあなたのサイト上のセキュアなページへ初めてアクセスしようとすると、通常は(企業名や連絡先といった)証明書の詳細を含むダイアログを表示し、証明書を有効であると受け入れて処理を続行してよいかどうか確認を求めます。 すでに有効となっている証明書を半永久的に受け入れるオプションを提供しているブラウザもあり、その場合は、サイトへ訪問するたびにプロンプトが表示されることはありません。 このオプションが提供されないブラウザもあります。いったんユーザが承認すれば、少なくともブラウザのセッションが維持される間は証明書は有効だと考えていいでしょう。

また、SSLプロトコルが安全性と効率性の両面を可能な限り意識して設計されているとは言っても、暗号化/復号化は、パフォーマンスという観点では演算のコストが高いプロセスです。 厳密に言うと、Webアプリケーション全体にSSLを張り巡らした状態で稼動する必要はなく、実際には、各ページで開発者がセキュアな接続を要するかどうかを選定して決定することができます。 かなり負荷の高いサイトでは、重要なページ、すなわち機密情報をやり取りする可能性のあるページのみをSSLの元で動かすのが一般的です。 これには、ログインページや個人情報を扱うページ、クレジットカード情報を送信する可能性のあるショッピングカートの精算手続といったものも含まれるでしょう。 http:の代わりにhttps:をアドレスの先頭につけることにより、アプリケーションのどのページでもセキュアソケット上でリクエスト処理を行えます。 セキュアな接続を絶対に必要とするページはいかなるものでも、ページのリクエストに関連するプロトコル形式をチェックし、httpsが指定されていない場合は適宜対策を講ずるべきです。

最後に、セキュアな接続の元で名前ベースの仮想ホストを使用することは問題があるかもしれません。 これは、SSLプロトコル自身の持つ設計上の制限です。 クライアントブラウザがサーバ証明書を受け付けるSSLのハンドシェイクは、HTTPリクエストがアクセスされる前に行われなければなりません。結果として、 仮想ホスト名を含むリクエスト情報は認証処理に先立って決定できず、したがって、単一IPアドレスに対して複数の証明書を割り当てることは不可能です。 単一IPアドレス上のすべての仮想ホストが同一の証明書で認証しなければならない場合は、仮想ホストを複数追加してもサーバ上のSSLオペレーションを妨げはしないはずです。 しかしほとんどのクライアントブラウザは、証明書にドメイン名が載っていればそれとサーバのドメイン名とを比較することに留意して下さい(まずは公式かつ認証局で署名された証明書に対して適用されます)。 ドメイン名が合致しなければ、こうしたブラウザはクライアントユーザに警告を表示します。 一般的には、稼働環境でSSLとともに使用されるのは、アドレスベースの仮想ホストだけであるのが通例です。

設定
JSSEの入手とインストール

Java Secure Socket Extensions (JSSE) パッケージのバージョン1.0.2以降を http://java.sun.com/products/jsse/ よりダウンロードしてください。Tomcatをソースコードから構築する場合、 このパッケージはすでにダウンロード済となっていることでしょう。 JDK 1.4上で動かすのであれば、これらのクラスはJDKに組み込まれているため、この作業ステップを飛ばしても構いません。

パッケージを展開した後、Tomcatでそれを利用するための手順は2通りあります(どちらか一つを選択してください)。

  • $JAVA_HOME/jre/lib/extディレクトリに、 3つのJARファイル(jcert.jarjnet.jarjsse.jar)をすべてコピーしてJSSEをインストール済拡張ライブラリにする。
  • JSSEバイナリディストリビューションを展開したディレクトリの絶対パスが設定されたJSSE_HOME環境変数を作成する。

証明書のキーストアを用意する

現在、TomcatではJKSフォーマットのキーストアしか扱えません。 これはJava標準の"Java KeyStore"フォーマットであり、keytoolコマンドラインユーティリティで生成されるフォーマットです。 このツールはJDKに同梱されています。

JKSキーストアに既存の証明書をインポートするためには、(JDKドキュメントパッケージにある)keytoolのドキュメントをお読みください。

単独の自己署名証明書を含め、キーストアを一から新しく生成するには、 端末のコマンドライン上で下記のコマンドを実行してください。

Windows:

%JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA

Unix:

$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA

(安全性の高いアルゴリズムとしてはRSAアルゴリズムが望ましく、 これは他のサーバやコンポーネントとの全般的な互換性も確保しています。)

このコマンドで、実行ユーザのホームディレクトリ上に、.keystoreという名前のファイルが新しく生成されます。 違う場所やファイル名を指定する場合には、上述のkeytoolコマンドに対し、-keystoreパラメータと、 キーストアファイルの完全なパス名をつけてください。 また後述するように、server.xml設定ファイルにこの新しい場所を反映させる必要があります。
例:

Windows:

%JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA \
  -keystore \path\to\my\keystore

Unix:

$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA \
  -keystore /path/to/my/keystore

このコマンドの実行の際、最初にキーストアのパスワードを入力するように促されます。 Tomcatで使用するデフォルトパスワードは"changeit"(すべて小文字)ですが、必要ならば独自のパスワードを指定することも可能です。

次に、企業名や連絡先など、証明書に関する全般的な情報を入力するように促されます。 アプリケーションにあるセキュアなページにアクセスしようとしたユーザに対してこの情報は表示され、ここに提示された情報がユーザの期待している情報と合致しているのかどうかを確認できます。

最後に、(同じキーストアファイルに格納された他の証明書とは対照的に) この証明書専用のパスワードであるキーパスワードを入力するように促されます。 ここでは、キーストアのパスワード自体に使用されるのと同じパスワードを使用しなければなりません。 (現在、ENTERキーを押下するとこれを自動的に行うことがkeytoolプロンプトにてユーザに表示されます。)

すべてうまくいけば、サーバで使用できる証明書を含んだキーストアファイルの完成です。

Tomcatの設定ファイルを編集する

最後のステップは、$CATALINA_HOME/conf/server.xml にあるセキュアソケット定義の設定です。 $CATALINA_HOMEは、Tomcatをインストールしたディレクトリを示します。 SSLコネクタを宣言した<Connector>要素のサンプルは、Tomcatにインストールされているデフォルトのserver.xmlファイルに含まれています。その部分にはこのように記述されています。

<-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 -->
<!--
<Connector className="org.apache.coyote.tomcat5.CoyoteConnector"
           port="8443" minProcessors="5" maxProcessors="75"
           enableLookups="true" disableUploadTimeout="true"
           acceptCount="100" debug="0" scheme="https" secure="true";
           clientAuth="false" sslprotocol="TLS"/>
-->

Connector要素自体がデフォルトではコメントアウトされているので、それを囲んでいるコメントタグを外す必要があることに注意して下さい。 その後、必要に応じて指定された属性をカスタマイズできます。 各オプションの詳しい情報については、サーバ設定リファレンスを調べてください。 下記の説明では、SSL通信のセットアップで最も重要な属性のみを取り上げています。

port属性は、Tomcatがセキュアな接続を待ち受けるTCP/IPポート番号です(デフォルト値は8443)。 これを(httpsのデフォルトポートである443といった)任意のポート番号に変更することができます。 しかしながら多くのオペレーティングシステムでは、Tomcatを1024未満のポート番号で動かすには特別なセットアップ(本ドキュメントの範囲外になります)が必要になります。

ここでポート番号を変更する場合、非SSLコネクタ上のredirectPort属性の設定値も変更すべきです。これによってTomcatは、 サーブレット2.4仕様で要求されているように、SSLを要するセキュリティ制約の指定を含んだページへアクセスしようとするユーザを自動的にリダイレクトできるようになります。

SSLプロトコルの設定に使用される追加オプションを示します。 先述したキーストアの設定方法によっては、下記の属性値を追加もしくは変更する必要があるかもしれません。

属性 説明
clientAuth このソケットを使用するために、TomcatがすべてのSSLクライアントにクライアント証明書の提示を求めたい場合、trueを設定してください。
keystoreFile 作成したキーストアファイルがTomcatが想定しているデフォルトの場所(Tomcatの実行ユーザのホームディレクトリ上で、ファイル名が.keystore)にない場合、この属性を追加してください。 絶対パス名もしくは$CATALINA_BASE環境変数を元に解決される相対パス名を指定することができます。
keystorePass Tomcatが想定するパスワード(changeit)と異なるキーストア(および証明書)のパスワードを使用する場合に、この属性を追加してください。
sslProtocol このソケットで使用される暗号化/復号化プロトコル。 デフォルト値をそのまま使用してください。
ciphers このソケットが使用を許可する暗号化方式をカンマで区切った一覧。 デフォルトでは、利用可能な暗号化方式をすべて許可しています。

これらの設定変更を完了した後、いつものようにTomcatを再起動する必要があり、再起動すれば設定が反映されるはずです。 TomcatでサポートするあらゆるWebアプリケーションにSSL経由でアクセス可能になっているはずです。 例えば、次のように試してください。

https://localhost:8443

さらに、(Webアプリケーション"ROOT"を修正していない限り)いつもの派手なTomcatのページが表示されるはずです。 うまく動かない場合は、後の方に出てくる、トラブルシューティングに関するヒントをいくつか紹介しているセクションを参照してください。

認証局から発行される証明書をインストールする

認証局(verisign.com、thawte.com、trustcenter.deなど)から発行される証明書を取得・インストールするには、前の方のセクションをお読みの上、下記に示す手順に従ってください。

ローカル向けの証明書署名要求(CSR)を生成する

あなたの選んだ認証局から証明書を取得するには、いわゆる「証明書署名要求(CSR)」を生成する必要があります。 この証明書署名要求(CSR)は、認証局が、あなたのWebサイトが"セキュア"であることを確認する証明書を発行するのに使用されます。 以下の手順に従って、証明書署名要求(CSR)を生成してください。

  • (前のセクションで説明したように)ローカル向けの証明書を生成してください。
    keytool -genkey -alias tomcat -keyalg RSA \
        -keystore <your_keystore_filename>
    注意: 場合によっては、正しく動作する証明書を生成するのに、"姓名"項目にWebサイトのドメイン(例.www.myside.org)を入力する必要があるかもしれません。
  • 次に、以下のコマンドで証明書署名要求(CSR)を生成します。
    keytool -certreq -keyalg RSA -alias tomcat -file certreq.csr \
        -keystore <your_keystore_filename>

これで認証局に申請可能なcertreq.csrというファイルができます(申請手順については認証局のWebサイトのドキュメントをご覧下さい)。 提出されたものを元に、証明書が発行されます。

証明書をインポートする

これで証明書ができたので、ローカルのキーストアにインポートできます。まず始めに、いわゆる「チェーン証明書」または「ルート証明書」をキーストアにインポートしてください。 その上で、手元にある証明書のインポートを行います。

  • 証明書を取得した認証局よりチェーン証明書をダウンロードしてください。
    Verisign.com: http://www.verisign.com/support/install/intermediate.html
    Trustcenter.de: http://www.trustcenter.de/certservices/cacerts/en/en.htm#server
    Thawte.com: http://www.thawte.com/certs/trustmap.html
  • チェーン証明書をキーストアにインポートしてください。
    keytool -import -alias root -keystore <your_keystore_filename> \
        -trustcacerts -file <filename_of_the_chain_certificate>
  • そして最後に、新規発行された証明書をインポートしてください。
    keytool -import -alias tomcat -keystore <your_keystore_filename> \
         -trustcacerts -file <your_certificate_filename>
トラブルシューティング

SSL通信のセットアップ時に遭遇する問題や対処法の一覧を以下に示します。

  • ログファイルで"java.security.NoSuchAlgorithmException"が表示される。

    JVMが、JSSEのJARファイルを見つけられません。 JSSEの入手とインストールの説明文をお読みください。

  • Tomcatの起動時に、"java.io.FileNotFoundException: {some-directory}/{some-file} not found"のような例外が返される。

    おそらく、参照するキーストアファイルをTomcatが見つけられないのでしょう。 デフォルトでは、(あなたと同じ環境であるかどうかに関係なく)Tomcatの実行ユーザのホームディレクトリ上にある.keystoreという名前のファイルが存在していることをTomcat側は想定しています。 キーストアファイルがどこか他にあるのなら、Tomcatの設定ファイル<Factory>要素にkeystoreFile属性を追加設定しないといけません。

  • Tomcatの起動時に、"java.io.FileNotFoundException: Keystore was tampered with, or password was incorrect" が返される。

    実際にキーストアファイルが改ざんされていないと仮定した場合に一番考えられる原因は、キーストアファイルを生成したときに使用したのと異なるパスワードをTomcatが使用していることです。これを解決するにはいったん前の方のステップに戻ってキーストアファイルを再生成するか、Tomcat設定ファイル<Factory>要素にkeystorePass属性を追加または更新します。 注意 - パスワードは大文字小文字を区別します!

それでもまだ問題があれば、TOMCAT-USERメーリングリストがよい情報源となります。入会および退会に関する情報や、過去のメッセージのアーカイブの場所については、http://jakarta.apache.org/site/mail.html"で見つけることができます。


[訳注: この文書は小川 環が翻訳し、 高橋達男が校正しました。 日本語訳に対するコメントがあれば、report@jajakarta.orgに送って下さい。]
Copyright © 1999-2003, Apache Software Foundation