同じSSL証明書を複数サーバーで使用できるか|冗長化構成と秘密鍵管理の注意点

テクノロジー

Webサーバーを冗長化するとき、次の疑問が生じることがあります。

Webサーバーが2台あれば、SSL証明書も2枚必要なのか。同じSSL証明書を複数のWebサーバーに配置しても問題ないのか。

いわゆる「SSL証明書の使い回し」が可能なのか、という疑問です。

結論から書きます。

同じFQDNでサービスを提供するWebサーバーであれば、同じSSL/TLSサーバー証明書を複数台で使用できます。Active-Standby構成だけでなく、ロードバランサー配下で複数のWebサーバーを同時稼働させるActive-Active構成でも成立します。

複数サーバーで証明書を使用する際に確認すべき点は、証明書の枚数ではありません。SANに登録するFQDN、証明書と秘密鍵の組み合わせ、TLS通信を終端する場所、証明書更新を全サーバーへ反映する運用が主な論点になります。

この記事では、PacemakerとCorosyncを利用してApache HTTP Serverを冗長化した検証経験を踏まえ、同じ証明書を複数サーバーで使用する場合の構成と注意点を整理します。

証明書はサーバー台数ではなく接続先の名前を証明する

「Webサーバーが2台なら証明書も2枚必要」と考えてしまう背景には、証明書を物理サーバーや仮想マシンにひもづくものとして捉えやすい点があります。

HTTPSで利用するサーバー証明書は、利用者が接続するサービスのDNS名と、接続先サーバーが提示する証明書との対応を確認するために使われます。

利用者が次のURLへ接続するとします。

https://www.example.com

証明書のSAN、正式にはsubjectAltNameには、次のDNS名が登録されている必要があります。

DNS:www.example.com

現在のTLSサーバー認証では、DNS名の照合にSANのdNSNameを使用します。RFC 9525では、TLS接続時にDNS名やIPアドレスをどのように照合するかが定められています。RFC 5280は、その照合に用いるSANを含むX.509証明書の基本プロファイルを定めた文書です。

重要なのは、各Webサーバー固有のホスト名ではなく、利用者が実際に接続する共通のFQDNをSANに登録することです。

内部のサーバー名が次のようになっていたとします。

web01.internal.example.com
web02.internal.example.com

公開URLがhttps://www.example.comだけであれば、公開用証明書に必要なのは原則としてwww.example.comです。各Webサーバー固有の内部ホスト名を公開用証明書へ含める必要はありません。

この記事で扱う「同じ証明書を複数サーバーで使用する構成」とは、1つのFQDN向けに発行された同じ証明書と、それに対応する秘密鍵を複数のWebサーバーへ配置する構成を指します。

PacemakerとCorosyncによるActive-Standby検証

Active-Standby構成では、通常時にサービスを提供するWebサーバーは1台です。障害が発生した場合に、仮想IPアドレスやWebサーバープロセスを待機系へ切り替えます。

                    利用者
                      │
                  仮想IPアドレス
                      │
           ┌──────────┴──────────┐
           │                     │
       Web01:Active         Web02:Standby

今回の検証では、クラスタ内のノード間通信とメンバーシップ管理をCorosyncが担い、PacemakerがApache HTTP Serverや仮想IPアドレスなどのリソースを監視・制御する構成を作成しました。

Active側とStandby側の両方に、同じ証明書と秘密鍵をあらかじめ配置しています。フェイルオーバー後も、同じFQDNでHTTPS接続できることを確認しました。

HTTPS接続が継続できる理由は、仮想IPアドレスが証明書にひもづいているためではありません。利用者が接続するFQDNと、切り替え後のWebサーバーが提示する証明書のSANが一致しているためです。

Active-Active構成でも同じ証明書を使用できる

同じ証明書を複数サーバーで使用できるのは、Active-Standby構成に限りません。

ロードバランサー配下でWeb01とWeb02を同時稼働させるActive-Active構成でも、同じ証明書を使用できます。

                    利用者
                      │
                ロードバランサー
                 ┌────┴────┐
                 │         │
               Web01     Web02
              Active     Active

どちらのWebサーバーが応答しても、利用者がアクセスするFQDNは変わりません。Web01とWeb02に同じ証明書と秘密鍵を配置すれば、両方のサーバーでHTTPS通信を処理できます。

ただし、同じ証明書を配置できることと、Webサービス全体をActive-Active化できることは別の話です。

Active-Active構成を成立させるには、複数のApacheを起動するだけでは不十分です。ロードバランサーによる通信振り分けに加え、セッション管理、共有データ、データベース接続、障害ノードの検知と切り離しまで設計する必要があります。

Pacemakerは複数ノード上のリソースを監視・制御できますが、Active-Active構成そのものは、Pacemakerだけで完結するものではありません。

Active-Active構成の可否を決めるのは証明書ではなく、通信振り分けやアプリケーションの状態管理を含めたシステム全体の設計です。

TLS終端位置によって証明書の配置先が変わる

Active-Active構成を設計する際は、TLS通信をどこで終端するかを決めます。代表的な構成は次の3つです。

構成公開用証明書の配置先バックエンド通信
各WebサーバーでTLS終端各WebサーバーHTTPS
ロードバランサーでTLS終端ロードバランサーHTTP
ロードバランサーで終端後に再暗号化ロードバランサーHTTPS

各WebサーバーでTLSを終端する構成では、Web01とWeb02の両方に証明書と秘密鍵を配置します。クライアントからWebサーバーまでTLS通信を維持できます。サーバー台数が増えるほど、秘密鍵の配布先、証明書の更新対象、Webサーバーの再読み込み対象も増えます。

ロードバランサーでTLSを終端する構成では、公開用の証明書と秘密鍵をロードバランサーだけに配置します。Webサーバーの台数が増えても、公開用証明書を各サーバーへ配布する必要がありません。証明書更新と秘密鍵管理を一元化しやすい構成です。ロードバランサーからWebサーバーまでの通信はHTTPになるため、内部区間の暗号化要件を事前に確認する必要があります。

内部区間にも暗号化が必要な場合は、ロードバランサーで外部からのTLS通信を終端した後、Webサーバーとの間で新たなTLS通信を確立します。公開用証明書をロードバランサーへ配置し、バックエンドには内部認証局が発行した証明書を使用する構成も可能です。公開用の秘密鍵を各Webサーバーへ配布せずに、バックエンド通信も暗号化できます。

同じFQDNを提供する場合でも、同じ証明書と秘密鍵を必ず共有しなければならないわけではありません。サーバーごとに異なる鍵ペアを作成し、それぞれ別の証明書を発行する方法もあります。

各証明書のSANにwww.example.comが登録され、クライアントから信頼される認証局によって発行されていれば、どちらのサーバーが応答しても名前検証は成立します。秘密鍵の共有を避けられるため、1台から鍵が漏えいした場合の影響範囲を限定できます。証明書の発行、更新、監視の対象はサーバー台数分増えます。

少数のオンプレミスサーバーでActive-Standbyを構成する場合は、同じ証明書と秘密鍵を共有する方法が比較的シンプルです。多数のWebサーバーを運用する場合は、ロードバランサーでの一元管理や、サーバーごとの証明書自動発行も選択肢になります。

秘密鍵管理こそが本当の論点

複数サーバーで同じ証明書を使用する場合、最も注意すべき対象は秘密鍵です。

サーバー証明書には公開鍵が含まれています。TLS通信を成立させるには、その公開鍵に対応する秘密鍵が必要です。

同じ証明書をWeb01とWeb02で使用する場合は、同じ証明書と秘密鍵の組み合わせを配置します。

Web01
  ├─ server.crt
  └─ server.key

Web02
  ├─ server.crt
  └─ server.key

Web01で作成したCSRをもとに発行された証明書を、Web02で新たに作成した別の秘密鍵と組み合わせることはできません。

証明書と秘密鍵が対応しているかは、それぞれから公開鍵を取り出して比較できます。

openssl x509 -in server.crt -pubkey -noout | openssl sha256
openssl pkey -in server.key -pubout | openssl sha256

両方の結果が一致すれば、証明書と秘密鍵は対応しています。

CSRの作成にはopenssl reqを使用します。

openssl req -new \
  -key server.key \
  -out server.csr \
  -config openssl.cnf

openssl x509は、証明書の内容確認や形式変換、証明書への署名などに使用するコマンドです。通常のCSR作成にはopenssl reqを使用します。

秘密鍵を複数サーバーへ配置すると、鍵が漏えいする可能性のある場所も増えます。転送には暗号化された経路を使用し、作業後の一時ファイルを削除します。ファイルの所有者と権限は必要最小限に絞り、バックアップやスナップショットにも同等のアクセス制御を適用します。

サーバーを廃止、返却、再利用する際は、秘密鍵とその複製を削除します。仮想マシンのイメージやテンプレートに鍵が残っていないかも確認が必要です。

同じ秘密鍵を複数サーバーで共有している環境では、1台から鍵が漏えいした時点で、その鍵を利用するすべてのサーバーが影響を受けます。証明書を失効させ、新しい鍵ペアを作成し、全ノードの証明書と秘密鍵を交換する必要があります。

秘密鍵を共有すると平常時の管理は単純になります。インシデント発生時の影響範囲は広がります。このトレードオフを理解したうえで採用する必要があります。

証明書更新を全ノードへ反映する

複数サーバー構成で起きやすいトラブルが、証明書更新の反映漏れです。

Web01だけ新しい証明書に更新し、Web02が古い証明書のまま残っていると、接続先によって異なる証明書が返されます。Web02側の証明書が期限切れになれば、証明書エラーが発生したり、発生しなかったりする不安定な状態になります。

証明書更新時は、サーバー証明書だけでなく、対応する秘密鍵、中間CA証明書、Webサーバーへの読み込み結果まで全ノードで確認します。ApacheやNginxを再読み込みした後、各サーバーが新しい証明書を提示していることを確認します。ロードバランサー経由の接続確認も必要です。

中間CA証明書やTLSプロトコル、暗号スイート、OCSP Staplingなどの設定も全ノードで統一します。証明書ファイルだけを管理するのではなく、TLS設定全体を構成管理の対象にする考え方が重要です。

Active-Standby構成では、Standby側が通常時に外部通信を処理していません。更新漏れに気づきにくい構成です。Active側だけを確認して作業完了とせず、Standby側でも証明書のシリアル番号、有効期限、SAN、証明書チェーン、Webサーバーへの読み込み結果を確認します。

証明書の自動更新を導入した場合も、複数サーバーへの反映方法が必要です。1台で更新した証明書と秘密鍵を他のサーバーへ配布する方法と、各サーバーが独自の鍵ペアで証明書を取得する方法があります。

前者では、配布処理の失敗検知、再実行、権限設定、Webサーバーの再読み込みまで監視します。後者では、各サーバーがドメイン認証を完了できる仕組みを用意します。

自動更新コマンドの正常終了だけでは、更新完了を証明できません。各サーバーが実際に提示している証明書の有効期限やシリアル番号を、外部から監視する必要があります。

まとめ

同じFQDNでサービスを提供する複数のWebサーバーでは、同じSSL証明書を使用できます。Active-Standby構成だけでなく、ロードバランサー配下のActive-Active構成でも同じです。

証明書のSANには、各Webサーバー固有のホスト名ではなく、利用者が接続する共通のFQDNを登録します。同じ証明書を使用する場合は、その証明書に対応する同じ秘密鍵を各サーバーへ配置します。

証明書はActive-Active構成を妨げる要因ではありません。設計上の論点は、秘密鍵の管理方法、TLSの終端位置、証明書更新の全ノードへの反映、退役サーバーからの秘密鍵削除にあります。

今回のPacemakerとCorosyncによる検証は、Active-Standby構成で同じ証明書を使用できることを実例として確認したものです。

同じ証明書を複数サーバーへ配置すること自体は難しくありません。秘密鍵の配布、証明書更新、漏えい時の影響範囲まで含めて運用設計することが重要です。

コメント

タイトルとURLをコピーしました