複数のサイトが 1 つの IP とポートを共有する場合に証明書が一致しない原因

更新日時
Copy as MD

問題の説明

この問題は、以下の 3 つの条件が満たされた場合に発生します。
  • Web サーバー上で、複数のサイトが同じ IP アドレスとポートにバインドされている。
  • サーバーがクライアントリクエスト内の異なるホストヘッダーを区別できる。
  • 各 SSL サイトに対して SSL 証明書がリクエストされ、インストールされているが、ユーザーがサイトを閲覧すると証明書の不一致エラーが表示される。

原因

HTTPS リクエストが Web サーバーに到達すると、リクエストは暗号化されます。Web サーバーは、リクエストを復号するために対応するサーバー証明書を必要とします。各サイトは異なる証明書を持っているため、サーバーはリクエスト内のホストヘッダーを使用して、復号に用いる正しい証明書を選択する必要があります。しかし、ホストヘッダーは暗号化されたリクエストの一部です。Web サーバーは、指定された IP アドレスとポートにバインドされた最初のサイトを選択し、そのサイトの証明書を復号に使用します。これにより、他のサイトへのリクエストの復号が失敗し、エラーが発生します。

ソリューション

このトピックでは、3 種類の Web サーバーに対するソリューションを説明します。

IIS

インターネットインフォメーションサービス (IIS) サーバーの場合、以下のいずれかの方法で問題を解決します。
  • 複数のポートへのバインド
    各 HTTPS サイトを、同じ IP アドレス上の異なるポートにバインドします。たとえば、HTTPS サイトを [$Domain]:[$Port] にバインドします。ただし、クライアントがサイトを閲覧する際には、アドレスバーにポートを指定する必要があります。
    説明
    • [$Domain]:サイトのドメイン名。
    • [$Port]:指定されたポート。
  • 複数の IP アドレスへのバインド

    各 HTTPS サイトを異なる IP アドレスにバインドします。この方法により、リクエストの競合を防ぎ、リクエストにホストヘッダーを含める必要がなくなります。ただし、この方法はコストが高くなります。

  • ワイルドカード証明書の使用

    サイトにワイルドカード証明書を使用します。たとえば、example.aliyundoc.comdemo.aliyundoc.comlearn.aliyundoc.com のサイトは、*.aliyundoc.com 用に発行された証明書を使用できます。これにより、これらのサイトへのリクエストはすべて、この証明書を使用して復号できます。

  • IIS のアップグレード

    IIS をバージョン 8 以降にアップグレードします。IIS 8 は、サーバ名表示 (SNI) 機能をサポートしています。この機能により、サーバーはリクエストからホストヘッダーを取得して、正しい証明書を選択できます。SNI を有効にする方法の詳細については、「SSL Scalability」をご参照ください。

Nginx

Nginx サーバーで、バーチャルホストを追加して、複数のサイトを同じ IP アドレスとポートにバインドします。次の手順を実行します。

  1. Nginx サーバーにログインし、次のコマンドを実行して Nginx 設定ファイルを開きます。
    vim [$Nginx_Dir]/conf/nginx.conf
    説明 [$Nginx_Dir] は Nginx のインストールフォルダです。デフォルトのフォルダは /usr/local/nginx です。
  2. 設定ファイルを次の内容で編集します。
    server {
        listen 443;
        server_name [$Domain1];
        ssl on;
        ssl_certificate [$Certificate_Path1];
        ssl_certificate_key [$Key_Path1];
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 
        ssl_ciphers [$Ciphers_Suite1];
        ssl_prefer_server_ciphers   on;
        location / {
            root   html;
            index  index.html index.htm;
        }
    }server {
        listen 443;
        server_name [$Domain2];
        ssl on;
        ssl_certificate [$Certificate_Path2];
        ssl_certificate_key [$Key_Path2];
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers [$Ciphers_Suite2];
        ssl_prefer_server_ciphers on;
        location / {
            root html;
            index index.html index.htm;
        }
    }

Apache

  1. Apache サーバーにログインし、次のコマンドを実行して ssl.conf 設定ファイルを開きます。
    vim [$Apache_Dir]/conf.d/ssl.conf
    説明
    • [$Apache_Dir] は Apache のインストールフォルダです。デフォルトのフォルダは /etc/httpd です。
    • ssl.conf 設定ファイルが見つからない場合は、yum install mod_ssl -y コマンドを実行して、必要な SSL モジュールをインストールします。
    • Apache で SNI を有効にした後、SSLStrictSNIVHostCheck off パラメーターを追加します。
  2. 設定ファイルを次の内容で編集します。
    Listen 443
    NameVirtualHost *:443
    <VirtualHost *:443>
      ……
    ServerName [$Domain1]
    SSLCertificateFile     [$Certificate_Path1];
    SSLCertificateKeyFile  [$Key_Path1];
    SSLCertificateChainFile  [$Certificate_Chain1];
      ……
    </VirtualHost>
    <VirtualHost *:443>
      ……
    ServerName [$Domain1]
    SSLCertificateFile     [$Certificate_Path2];
    SSLCertificateKeyFile  [$Key_Path2];
    SSLCertificateChainFile  [$Certificate_Chain2];
    説明
    • Alibaba Cloud の無料証明書など、1 つの証明書が www.example.comexample.com の両方をカバーする場合は、次のフォーマットを使用します。そうしないと、www プレフィックス付きのドメイン名にアクセスできなくなる可能性があります。
      • ServerName example.com
      • ServerAlias www.example.com
    • [$Certificate_Chain1]:最初のサイトの中間証明書バンドルのパス。
    • [$Certificate_Chain2]:2 番目のサイトの中間証明書バンドルのパス。
    • Apache V2.4.8 以降では、SSLCertificateChainFile ディレクティブは SSLCACertificatePath ディレクティブに置き換えられています。

関連資料

適用範囲

Certificate Management Service