こんにちは、医療ユニットの片岡です。
オプティムでは、企業・自治体・医療・農業などさまざまな分野に対してサービスを展開しています。
一般的なWebサービスと異なり、さまざまなネットワーク環境下でサービスを提供しています。 今回は、顧客拠点とのセキュアなネットワーク構築に着目し、いくつかのケースを紹介します。
セキュアなネットワークについて
ネットワークレベルで顧客を限定してサービスを展開するケースとして、以下を調査しました。
mTLS(Mutual TLS)- 相互
TLS認証という技術で、通常のHTTPS(TLS)では、サーバーの身元を確認し、本物かどうか認証を行うだけですが、mTLSではクライアント側の身元も確認を行います。 - 信頼できるクライアントのみに通信を絞ることで、なりすましを防止します。
- 相互
IPsec VPN- IPパケット単位で暗号化・認証を行い、インターネット上にセキュアなトンネルを構築する方式です。
- 接続端点(拠点・端末)を認証し、なりすましを防止します。
- 利用形態には、拠点間を接続するサイト間VPNと、端末から社内/クラウドへ接続するリモートアクセスVPNがあります。
- 本稿では、顧客拠点とサービス側を接続するサイト間VPNを主に扱います。
IP-VPN- 通信事業者が提供する閉域網の上で
VPNを構築する方式です。 - オープンなネットワークを利用する場合と異なり、契約した通信事業者の通信網でのみ通信が行われます。
- 通信事業者が提供する閉域網の上で
- 専用線
- 拠点間で完全に独立した専用の通信網を構築する方式です。
今回は、AWS上で構築しているマルチテナントのサービスを、顧客の拠点に提供するケースを取り上げます。
本記事では、複数顧客が同一VPC内のサービスを利用し、各顧客拠点からVPNまたはmTLSで接続する構成を想定しています。
また、IP-VPN/専用線とIPsec VPNを比較したときの主な違いは、AWSと拠点の接続経路です。
IP-VPN/専用線はAWS Direct Connect1を利用し、IPsec VPNはインターネット経由で接続します。
本稿では、構成がもっともシンプルなIPsec VPNのケースを取り上げます。
mTLSのケース
次のような構成で実現できました。

この図は、顧客拠点のNginxプロキシからALBを経由してバックエンドサービスに通信する構成を示しています。
Nginx(クライアント)とALB(サーバー)の間でmTLSによる相互認証が行われます。
この構成は、ALBにHTTPSリスナーが設定済みであることを前提とします。
mTLSを利用する場合、次の2点に対応する必要があります。
- サーバーに、CA証明書とCRL2を配置する
- クライアント(Nginx)に証明書と秘密鍵を配置する
サーバーに、CA証明書とCRLを配置する
CA証明書を配置するのは簡単に対応できます。
S3にCA証明書とCRLを配置するALBのHTTPSリスナーで、S3上のCA証明書を参照するように設定する
Webサービスを提供する際、一般的な構成ではALBを配置しますが、
ALBのHTTPSリスナーで、S3上に配置されているCA証明書を参照するように設定します。
S3にCA証明書を配置する
S3バケットを作成し、ALBから証明書を参照できるように、以下のようなバケットポリシーの設定が必要です。
// 一部抜粋 { "Sid": "AllowElbv2ReadMtlsArtifacts", "Effect": "Allow", "Principal": { "Service": "elasticloadbalancing.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::<バケット>/<パス>/ca.crt", "Condition": { "StringEquals": { "aws:SourceAccount": "AWSアカウントID" }, "ArnLikeIfExists": { "aws:SourceArn": "arn:aws:elasticloadbalancing:<リージョン>:<AWSアカウントID>:truststore/*" } } }
ALBのリスナーにmTLSの設定
ALBのHTTPSのリスナーを設定します。

ALBのリスナーの設定で、相互認証(mTLS)の項目が存在します。
ここのトラストストア(信頼するCA証明書を格納する場所)の項目で、CA証明書とCRLを配置したS3を指定することで、HTTPSの通信においてmTLSの設定が完了します。
クライアント(Nginx)に証明書と秘密鍵を配置する
クライアント証明書を利用するパターンとしては、いくつかありますが、
今回は、クライアントがNginxプロキシを経由してALBに接続するパターンで解説します。
Nginxのproxy_ssl_certificateとproxy_ssl_certificate_keyに、クライアント証明書と秘密鍵を設定します。
# 一部抜粋
location ^~ /api/ {
proxy_ssl_certificate /etc/nginx/ssl/mtls_client.crt;
proxy_ssl_certificate_key /etc/nginx/ssl/mtls_client.key;
proxy_ssl_verify on;
proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
}
これにより、NginxとAWS ALB間の通信でクライアント認証が行われ、
mTLSを利用した通信が可能となります。
VPNのケース
VPNを利用する場合、mTLSと異なり、双方向に通信することが可能になります(AWS内から顧客拠点への通信も可能です)。
これは、mTLSがアプリケーション層(HTTPSリクエスト単位)での認証であるのに対し、VPNはネットワーク層で拠点間をトンネル接続するため、あたかも同一ネットワーク内にいるかのように双方向通信が可能になるためです。
一方向のみ必要なケースも考えられるため、一方向のケースから確認しますが、
その前に、VPNを利用する上での落とし穴について確認します。
CIDR重複の落とし穴
VPNを接続するケースに共通して考慮が必要な点として、
顧客ネットワーク同士のCIDR重複があります。
通常、拠点間VPNのよくある例として、会社の複数拠点を繋ぐといったケースがあります。
この場合、全体のネットワーク構成を一括して設計可能です。
しかし、不特定多数の顧客の拠点と接続する場合、サービス提供者側でネットワーク構成を左右できない場合があるため、CIDR重複した場合でも問題なく通信を行えるようにする必要があります。
CIDRが重複した場合を考えてみます。

この図では、以下の構成を示しています:
- 192.168.0.0/24のネットワークがA拠点・B拠点と存在
Virtual Private Gateway(VGW)3、Customer Gateway(CGW)4を用いて、拠点間VPNが貼られている状態
顧客ネットワークからVPNを経由して、提供するサービスに対しての通信(192.168.1.2宛)は問題なく行えます。

顧客拠点(192.168.0.0/24)からサービスVPC(192.168.1.2)への通信は、VPNを経由して正常に到達します。
しかし、戻りの通信には問題があります。

サービスVPCからの戻り通信では、送信元が192.168.0.1の場合、A拠点とB拠点のどちらに送信すべきか判別できません。
そこで、プロキシVPCを用いて送信元IPアドレスを置き換える方法で解決します。

各顧客拠点ごとに一意なCIDR(例: 10.1.0.0/24、10.2.0.0/24)を持つプロキシVPCを用意し、プロキシで送信元IPアドレスを置き換えることで、サービス側から見た顧客ネットワークを一意に特定できるようになります。
このように、サービス側でCIDRの重複を吸収するための小さなネットワークを用意し、プロキシすることで、CIDRの重複に対応できます。
このプロキシの具体例を2パターン解説します。
VPC Endpoint+Route 53 ResolverEC2プロキシ +Route 53 Resolver
VPC Endpoint + Route 53 Resolver
次の構成となります。

この図は、サービスVPCとプロキシVPC間をVPC Endpoint5で接続し、プロキシVPCと顧客拠点間をVPNで接続する構成を示しています。
Route 53 Resolver Inbound6によってDNSによる名前解決が可能になっています。
VPC EndpointによるプロキシとVPC間の通信
これまでCIDR重複の問題とプロキシによる解決策を説明してきましたが、サービスVPCとプロキシVPC間をどのように接続するかについては触れていませんでした。
この接続方法として、VPC Endpointを利用することができます。
VPC Endpointは、一般的にはS3やECRなどのAWSサービスへプライベート接続するために利用します。加えて、NLBをバックエンドとするPrivateLinkエンドポイントサービスを介して、他VPCのサービスへ接続する構成も選択できます。
この仕組みを利用することで、VPC間通信とプロキシを一体的に実現できます。
冗長化に対する解決策: Route 53 Resolver Inbound
VPC Endpointを冗長化する場合、可用性を高めるために複数のアベイラビリティゾーン(AZ)に配置します。
この場合、顧客拠点側からは、各AZごとに1つずつ、複数のIPアドレスが存在することになります。
これらのIPアドレスへ適切にルーティングするために、DNSによる名前解決を活用する方法があります。
DNSを使うことで、複数のIPアドレスに対するラウンドロビンや、ヘルスチェックに基づいた通信の振り分けが可能になります。
Route 53 Resolver Inboundを用いることで、顧客ネットワークから、VPC経由でAWSリソース(VPC Endpointなど)の名前解決が可能になります。
顧客拠点側では、DNSサーバーの設定でRoute 53 Resolver InboundのIPアドレスを参照するように設定することで、VPC Endpointなどの名前解決が可能になります。
注意点として、ALBとは異なり、AZ障害時のフェイルオーバーは自動では行われないため、クライアント側でタイムアウト設定や再接続ロジックの実装などを検討することが推奨されます。
EC2プロキシ + Route 53 Resolver
次の構成となります。

この図は、Transit Gateway(TGW)を使用してサービスVPCとプロキシVPC間を接続する構成を示しています。
プロキシVPCにはEC2上にNginxなどのプロキシが構築されており、顧客拠点とはVPNで接続されています。
VPC Peeringの接続数上限
VPC同士で通信を行う場合、通常はVPC Peeringと、Transit Gateway(以降TGWと表記)がよく挙げられます。
VPC Peeringは、接続可能な数に上限があり、デフォルトで50接続、上限緩和申請を行った上でも 125接続までとなります。
そのため、1 VPCあたりの接続数制約が厳しいVPC Peeringよりも、多数接続ではTGWで集約設計する方式が現実的となります。
TGWを用いた VPC間の通信
EC2に、Nginxなどのプロキシを構築し、TGWでVPC間を接続する方式となります。
この方法の一番の特徴は、双方向通信が可能な点です。
VPC Endpointでは、一方向の通信となっていましたが、サービス側から顧客拠点側に対しての通信を行いたい場合(例: Webhookによる通知、データ同期処理の起動など)に、この構成が有効です。
ただし、通信経路・到達範囲を広く設定できるという点で、ルーティング設定を誤ると、意図しない顧客拠点への通信が発生するなど、セキュリティインシデントの原因になる可能性も考えられます。
まとめ
mTLSとVPNは二者択一ではなく、要件に応じて併用できます。VPNは拠点間の通信をトンネルで暗号化し、mTLSは接続元を証明書で認証します。- マルチテナントで顧客拠点を収容する場合は、
CIDR重複を前提に設計することが重要です。プロキシVPCで送信元IPを置き換えることで、戻り通信の曖昧さを回避できます。 - 片方向通信が要件であれば、
VPC Endpoint+Route 53 Resolverは構成が比較的シンプルで、運用負荷を抑えやすい方式です。 - 双方向通信が必要であれば、
EC2プロキシ +TGWで要件を満たせますが、ルーティング制御を厳密に行わないと到達範囲が広がりやすく、セキュリティリスクが高まります。
mTLSとVPNは優劣を比べる関係ではなく、異なるレイヤーを守る補完的な技術です。
要件に応じて、mTLS、VPN、mTLS+VPNを使い分けるのが適切です。
本稿が、企業向けマルチテナントサービスにおけるネットワーク方式選定の判断材料になれば幸いです。
当社では、AWSを使って様々なサービスの開発を行っています。技術的な挑戦を楽しみながら、一緒にプロダクトを成長させていける仲間を募集していますので、ご興味のある方は、ぜひご連絡ください。
-
AWS Direct Connect: オンプレミス環境とAWSを専用線で接続するマネージドサービス↩ - CRL(Certificate Revocation List): 失効した証明書のリストで、セキュリティ侵害や秘密鍵の漏洩などの理由で無効化された証明書を管理するための仕組み↩
-
Virtual Private Gateway(VGW):AWS側のVPNゲートウェイで、VPCに接続してサイト間VPN接続を実現する↩ -
Customer Gateway(CGW): 顧客側(オンプレミス側)のVPNゲートウェイの情報をAWSに登録したもの↩ -
VPC Endpoint:VPCからAWSサービスやVPCエンドポイントサービスへ、インターネットを経由せずに接続する仕組み↩ -
Amazon Route 53 Resolver Inbound endpoint: オンプレミスなどの外部ネットワークから、VPC内のDNS解決を可能にする受信用エンドポイント↩