コンテンツにスキップ

HTTPSとTLS

ApacheのHTTPSでは、mod_sslがTLS接続を終端し、復号したHTTPリクエストを通常のVirtualHost処理へ渡す。


HTTPは、HTTPメッセージを暗号化せずに送受信する。HTTPSは、HTTPをTLS接続の内側で送受信する。

HTTP
client -> TCP 80 -> Apache -> HTTP processing
HTTPS
client -> TCP 443 -> TLS handshake -> Apache -> HTTP processing

TLSは、通信の暗号化、通信相手の証明書による確認、通信内容が途中で変更されていないことの検出を提供する。TLS接続を確立した後は、Apacheが復号したHTTPリクエストをDirectory、認証、コンテンツ配信などの処理へ渡す。


mod_sslは、ApacheにTLS機能を追加するモジュールである。Debianではa2enmod sslによってモジュールが有効になり、ports.conf内のListen 443も有効になる。

Listen 443はApacheを443番ポートで待ち受けさせる。<VirtualHost *:443>は、そのポートへ到着した接続に適用するサイト設定を定義する。待ち受けとVirtualHostは別の役割を持つ。


HTTPSでは、HTTPのHostヘッダーを受信する前にTLSハンドシェイクを行う。クライアントはTLSのSNI(Server Name Indication)で接続先ホスト名を伝え、Apacheはその名前に対応するHTTPS用VirtualHostの証明書を選ぶ。

TLS接続後にHTTPリクエストを受信すると、ApacheはHostヘッダーも使ってVirtualHostを確認する。したがって、次の名前をそろえる必要がある。

  • クライアントが接続するDNS名
  • TLSのSNI
  • HTTPのHostヘッダー
  • ApacheのServerName
  • 証明書のSAN

SSLEngine Onは、そのVirtualHostでTLS処理を有効にするディレクティブである。

443番ポートのVirtualHostを作るだけでは、HTTPをTLSで保護する設定にはならない。SSLEngine Onに加え、サーバー証明書と秘密鍵を指定する。


SSLCertificateFileは、Apacheがクライアントへ提示するサーバー証明書を指定する。

Apache 2.4.8以降では、このファイルにサーバー証明書とIntermediate CA証明書を連結できる。一般にfullchain.pemという名前で、次の順序にする。

server certificate
Intermediate CA certificate
additional Intermediate CA certificates, if any

Root CA証明書は通常サーバーから送らない。クライアントが自分のTrust Storeに持つRoot CAを信頼の起点にする。


SSLCertificateKeyFileは、サーバー証明書の公開鍵と対になる秘密鍵を指定する。

TLSハンドシェイクでは、この秘密鍵を使ってサーバーが証明書の正当な所有者であることを示す。証明書と秘密鍵の組み合わせが一致しなければ、ApacheはHTTPS用設定を正常に読み込めない。

パスフレーズなしの配備用秘密鍵を使う場合は、root所有・600などで読み取り権限を制限する。Apacheの親プロセスが起動時に秘密鍵を読み込み、その後のTLS処理で使用する。


証明書チェーンとクライアントの信頼

Section titled “証明書チェーンとクライアントの信頼”

Apacheがfullchain.pemを送っても、クライアントが対応するRoot CAを信頼していなければ検証は成功しない。

Root CA certificate <- client Trust Store
-> Intermediate CA <- Apache sends
-> server certificate <- Apache sends

クライアントは署名を順に検証し、サーバー証明書のSANが接続先名と一致するか、有効期間内か、信頼するCAへ到達できるかを確認する。

証明書、SAN、証明書チェーンの詳細は証明書と証明書チェーンと信頼を参照する。


SSLProtocolは、VirtualHostで許可するTLSプロトコルのバージョンを指定する。

SSLProtocol -all +TLSv1.2 +TLSv1.3

-allは一度すべてのプロトコルを無効にし、+TLSv1.2と+TLSv1.3で使用するバージョンだけを有効にする。

Debianの共通mod_ssl設定でもTLSポリシーを定義できる。VirtualHost側へSSLProtocolを書くと、そのVirtualHostの方針を明示できるが、共通設定と重複する場合は必須ではない。