基礎: リンクローカルとSNI
対象範囲: VPC Latticeのサービス/リソースAPIとAWS Gateway API Controller。選択したリリースとインストール済みCRDを確認してください。 最終更新日: September 13, 2026
このドキュメントで扱うこと
- リンクローカルアドレスとは何か、Latticeがそれを選んだ理由、その結果生じる2つの運用上の問題
- 証明書を選ぶ際の「鶏と卵」の問題から、SNIを平文で送信する必要がある理由
- サービスリスナーで見える情報と、TCPリソース接続およびその独立したアクセスモデルの違い
リンクローカルアドレス
リンクローカルアドレスとは
リンクローカルアドレスとは、1つのリンク(同じブロードキャストドメイン)内だけで有効なアドレス範囲に属するものです。ルーターを越えないことが定義です。
| 範囲 | プロトコル | スコープ | 標準 |
|---|---|---|---|
169.254.0.0/16 | IPv4 | リンクローカル | RFC 3927 |
fe80::/10 | IPv6 | リンクローカル | RFC 4291 |
これらの範囲は、「DHCPサーバーもルーティング設定もなくても、直近の隣接先とは通信できること」という要件を満たすためにあります。そのため、これらのアドレスはグローバルに一意である必要がなく、リンクごとに再利用できます。
AWSですでに使われている例
EC2を使ったことがある人には、すでになじみのある方式です。
| アドレス | 用途 |
|---|---|
169.254.169.254 | EC2 Instance Metadata Service(IMDS): インスタンス自身のメタデータとIAMロールの認証情報 |
169.254.170.2 | ECSタスクの認証情報エンドポイント |
169.254.170.23 | EKS Pod Identity Agent(IPv4) |
fd00:ec2::23 | EKS Pod Identity Agent(IPv6) |
169.254.171.0/24 | VPC Lattice(IPv4) |
AWSはこれらのアドレスに特別な動作を割り当てていますが、すべて同じスコープや実装を共有するわけではありません。IPv4リンクローカル、IPv6 ULA、ノードエージェントのエンドポイントを区別してください。アドレス標準だけから、ハイパーバイザーによる横取りがあるとは判断できません。
Latticeについて説明する際は、リンクローカルアドレスの一般的な定義や、推測したAWS内部実装ではなく、文書化されたVPC固有のアドレス動作を扱ってください。
LatticeのIPv4とIPv6の範囲は種類が異なる
VPC LatticeサービスのDNS名は、2種類のアドレスに解決されます。
| 範囲 | 種類 | 性質 |
|---|---|---|
169.254.171.0/24 | IPv4 | リンクローカル(169.254.0.0/16内) |
fd00:ec2:80::/64 | IPv6 | ユニークローカルアドレス(ULA)(fc00::/7内、RFC 4193)。リンクローカルではない |
IPv6 ULAはリンクローカルではなく、廃止されたサイトローカルアドレスのクラスでもありません。ULAアドレスはプライベートネットワーク内でルーティングでき、アドレスのスコープはグローバルです。意図した経路到達性とアドレスのスコープは別です。Latticeについては、プレフィックスから実装を推測せず、AWSのDNSと接続性のドキュメントに従ってください。
名称は異なりますが、運用上重要な性質は両方の範囲に共通します。グローバルに一意ではなく、VPCごとに再利用され、インフラストラクチャによって横取りされます。
Latticeがこの方式を使う理由
ドキュメント01で説明したとおり、Latticeはサイドカーなしでトラフィックを処理する必要があります。サイドカーがないとき、誰がトラフィックを横取りするのでしょうか。リンクローカルアドレスがその答えです。
仕組みは次のとおりです。
- クライアントがLatticeサービスのDNS名を解決する
- DNSから
169.254.171.x(またはfd00:ec2:80::の範囲)のアドレスが返る - クライアントは通常どおりそのアドレスに接続する。アプリケーションはLatticeの存在を認識しない
- その範囲宛てのパケットがVPC内のLattice ingressエンドポイントへ転送される
- Latticeがリスナールールを評価し、ターゲットを選択して実際のPod IPへ転送する
トラフィックは、アプリケーションコード、Pod仕様、iptablesルールを変更せずにインフラストラクチャを通過します。このアドレス範囲により、Latticeはサイドカーを取り除きながらトラフィックの横取りポイントを維持できます。
リンクローカルを選んだ結果として生じる2つの問題
この設計は洗練されていますが、代償があります。どちらの問題も移行計画に含めてください。
問題1: Envoyのiptablesによる横取りとの競合
サイドカーメッシュ(App Mesh、Istio)は通常、initコンテナでiptablesルールを設定してPodのトラフィックをプロキシへ送ります。一般的には「このPodからのすべてのアウトバウンド通信をEnvoyのポートへリダイレクトする」形です。
広範囲なアウトバウンドREDIRECTがLatticeの通信も捕捉することがあります。問題になるかどうかは、メッシュのポリシー、設定済み経路、署名方式によって異なります。CIDRの明示的なバイパスを追加する前に、それらを確認してください。
対処は例外CIDRを登録することです。Latticeのアドレス範囲を横取り対象から除外し、トラフィックがEnvoyを迂回するようにします。
| メッシュ | 例外の登録方法 |
|---|---|
| App Mesh | App Mesh CNI/initコンテナの設定にあるegress-ignore CIDR一覧へLatticeの範囲を追加する |
| Istio | traffic.sidecar.istio.io/excludeOutboundIPRangesアノテーションにLatticeの範囲を追加する |
共存させる場合は、メッシュのアウトバウンドポリシー、登録済みの外部宛先、署名経路、両方のアドレスファミリーを確認します。未知の宛先を転送するEnvoy設定もあれば、拒否する制限付き設定もあります。CIDRの除外は意図的なバイパス方式の1つであり、例外を設定しなければ共存するすべてのメッシュが失敗する証拠ではありません。
逆向きの用途もあります。ドキュメント03のegress proxy方式ではiptablesを使い、Latticeの範囲だけを選択して署名プロキシに送ります。反対の目的で同じツールを使います。
問題2: 宛先IPベースの可観測性と制御が意味をなさなくなる
リンクローカルアドレスはグローバルに一意ではなく、サービスも識別しません。そのため、既存の運用ツールが前提とする仕組みが成り立たなくなります。
| 影響を受ける機能 | 理由 |
|---|---|
| フローログの宛先IPからピアを特定する | 宛先は常に169.254.171.xとして表示されます。どのLatticeサービスかを判別できません |
| 宛先CIDRベースのSecurity Groupアウトバウンドルール | すべてのLatticeサービスが同じ範囲にあります。サービスごとに許可/拒否できません |
| 宛先IPベースのNetworkPolicy | 同上です。Kubernetes NetworkPolicyのipBlockではLatticeサービスを区別できません |
| IPベースのモニタリングダッシュボードとアラーム | IPだけでは安定したサービス識別ができません。DNS、リクエストID、サービスを認識するログで補ってください |
| IP範囲ベースの資産インベントリ | LatticeサービスはIPとしてインベントリに現れません |
代わりに制御レイヤーを移します。
- IPではなく認証ポリシーで認可する: プリンシパル、パス、メソッド、ヘッダーの条件(ドキュメント03)
- フローログではなくLatticeアクセスログで観測する: 呼び出されたサービスが記録されます
- CIDRではなく管理プレフィックスリストでSecurity Groupを開放する(以下を参照)
これはツールの置き換えではなく、制御モデルを「IPとポートによる制御」から「アイデンティティとポリシーによる制御」へ移すことです。ネットワークチームが運用してきた既存資産のかなりの部分は、このアドレス範囲では機能しません。金融業界では、組織の責任分界に関わる問題に発展する場合があります。早い段階でネットワークチームと合意してください。
プレフィックスリストでSecurity Groupを開放する
Latticeからのトラフィックを受け取るには、ノードのSecurity Groupでその通信を許可する必要があります。CIDRを直接記述するのではなく、AWS管理プレフィックスリストを使う方法が適切です。
| プレフィックスリスト名 | 用途 |
|---|---|
com.amazonaws.<region>.vpc-lattice | IPv4 |
com.amazonaws.<region>.ipv6.vpc-lattice | IPv6 |
# Read-only lookup; apply the reviewed ingress rule through CDK/Terraform.
: "${AWS_REGION:?Set the reviewed AWS Region}"
aws ec2 describe-managed-prefix-lists --region "$AWS_REGION" \
--query "PrefixLists[?PrefixListName=='com.amazonaws.$AWS_REGION.vpc-lattice'].{Id:PrefixListId,Name:PrefixListName}" \
--output jsonレビュー済みのIaCでは、実際のターゲットSG(設定に応じてノードSGまたはPod SG)で、該当するLatticeプレフィックスリストを、必要なターゲット/ヘルスチェックのポートとプロトコルだけに許可してください。全プロトコルの受信許可は避けます。クライアント/サービスネットワーク関連付け用のSGは別途確認してください。上記の検索ではSGは変更されません。
SNI(Server Name Indication)
ドメイン名を平文で送る必要がある理由
SNIはTLS拡張であり、接続先のサーバーのドメイン名を平文でClientHello内に含めます。暗号化プロトコルの最初のメッセージに宛先ドメインを平文で入れるのは不自然に見えますが、避けられない循環の問題があります。
鶏と卵の問題:
- TLS接続を始めるには、サーバーが提示する証明書を選ぶ必要がある
- 証明書はドメインに結び付いている(
api.example.com用の証明書とwww.example.com用の証明書は異なる) - 1つのIP:ポートで複数のドメインを提供している場合、証明書を選ぶため、サーバーはクライアントがどのドメインに接続したいかを知る必要がある
- しかし、クライアントが希望するドメインはHTTPの
Hostヘッダーにあり、HostヘッダーはTLS内で暗号化されて届く - つまり、暗号化を始めるにはドメインが必要で、ドメインを知るには暗号化が始まっている必要がある
通常のTLSはClientHelloでSNIを送り、HTTPを読む前にサーバーが証明書を選べるようにします。考えられる設計はこれだけではありません。ECHは事前に入手した鍵を使って内側のClientHelloを暗号化します。現在のLattice TLS passthroughではSNIが見える必要があり、ECH/ESNIはサポートされていません。
要するに、SNIが平文で見えることは設計ミスではなく、循環を断ち切るために意図的に選んだ妥協です。そのおかげで、TLSを終端しない中間装置でも宛先ドメインを把握できます。これがTLS Passthroughのルーティングを可能にします。
LatticeがSNIを使う方法
TLS Passthroughリスナーでは、LatticeはTLSを終端しません。では、何を基準にターゲットを選ぶのでしょうか。 SNIです。ClientHello内の平文SNIフィールドを読み取り、それだけを使ってルーティングします。
HTTPSリスナーとTLS Passthrough: Latticeから見える情報
| 情報 | HTTPSリスナー(TLS Terminate) | TLS Passthrough |
|---|---|---|
| SNI(ドメイン) | ✅ | ✅ |
| HTTPパス | ✅ | ❌ |
| HTTPメソッド | ✅ | ❌ |
| HTTPヘッダー | ✅ | ❌ |
| クエリ文字列 | ✅ | ❌ |
Authorizationヘッダー(SigV4) | 読み取り可能。認証済みIAMリクエストをサポート | 暗号化されており、認証済みSigV4アイデンティティは利用不可 |
| リクエスト本文 | ✅(通過する) | ❌ |
| パス/ヘッダーに基づくルーティング | ✅ | ❌(SNIのみ) |
| パス/メソッド/ヘッダーの条件キー | ✅ | ❌ |
| アクセスログのHTTP詳細 | ✅ | 限定的 |
| エンドツーエンド暗号化の維持 | ❌(Latticeで1回終端) | ✅ |
| エンドポイント独自のmTLS | ❌(Latticeはクライアント証明書を要求しない) | ✅(エンドポイント自身が実行) |
| ターゲットグループのプロトコル | HTTP/HTTPS | TCP |
| Gateway APIリソース | HTTPRoute/GRPCRoute(tls.mode: Terminate) | TLSRoute(tls.mode: Passthrough) |
この表は、この節で最も重要なトレードオフを示しています。
TLS passthroughはエンドポイントのTLSを維持し、エンドポイント側のmTLSも使えますが、LatticeはHTTPフィールドを確認できず、SigV4ヘッダーも認証できません。 匿名のネットワークコンテキスト認証ポリシーは、認証済みの呼び出し元アイデンティティとは別のものです。
信頼境界は、1つのサービスで異なる種類のリスナーを決して使えないと主張するのではなく、リスナー/パスごとに選んでください。TLS passthroughでは匿名のネットワークコンテキストポリシーを利用できますが、署名された呼び出し元アイデンティティは提供されません。バックエンドプロトコルは別に設定します。HTTPSリスナーはHTTPまたはHTTPSへ転送でき、LatticeはHTTPSターゲット接続の証明書を検証しません。
Latticeがサポートするプロトコル
| リスナープロトコル | アプリケーションプロトコル | ターゲットグループプロトコル |
|---|---|---|
| HTTP | HTTP/1.1 | HTTP |
| HTTPS | HTTP/1.1、HTTP/2、gRPC(ALPNでネゴシエート。ALPNがない場合はHTTP/1.1) | HTTP/HTTPS |
| TLS_PASSTHROUGH | (Latticeでは解釈しない) | TCP |
単独のraw TCPリスナーはありません。 TCPはTLS_PASSTHROUGH用のターゲットグループプロトコルとしてのみ利用できます。
サービスリスナーとTCPリソース接続
VPC Latticeのサービスリスナーが公開するのはHTTP、HTTPS、TLS_PASSTHROUGHです。これとは別に、リソース設定とリソースゲートウェイはTCPリソースをサポートします。サービスネットワーク認証ポリシーはそれらのリソース設定には適用されません。共有方法、エンドポイント/ネットワーク制御、リソース認証は別途評価してください。
サポートされるHTTPルーティング/認証が必要ならサービスモデルを選び、それらのサービス機能を使わずにTCPアクセスする場合はリソース接続を評価します。raw TCPのサービスリスナーがないことは、API機能の境界を示すものであり、ネットワーキング上の数学的な不可能性を示すものではありません。
- HTTP/HTTPSのサービスルーティングでは、サポートされるアプリケーションフィールドを使います。
- TLS passthroughでは、SNIが設定済みのカスタムドメインと一致する必要があります。
- TCPリソース接続では、リソース設定/リソースゲートウェイと、専用の関連付け/アクセスモデルを使います。
HTTP/2とgRPCのサービスターゲットプロトコルバージョンでは、AWSはHTTPSリスナーを要求します。サポート範囲内であれば、ターゲットグループのトランスポートにはHTTPまたはHTTPSを使えます。バックエンドの平文HTTP/2と、サービスリスナーへの平文h2cクライアント接続を混同しないでください。最初の平文メッセージの後でのみTLSをネゴシエートするデータベースも、ClientHelloを最初に期待するリスナーとは異なります。
公開されているサービスリスナーの制約は、TCPリソースアクセスを除外しません。必要なルーティング/認可モデルに基づき、リソースゲートウェイ、既存のプライベート接続、NLBを評価してください。
現在のリソース設定とTLSリスナーのリファレンスを参照してください。AWS APIに対するControllerのサポートは、サービスの提供状況とは別に確認する必要があります。
セキュリティ上の注意: SNIが平文で見える影響
見える情報
TLSは通信内容を保護しますが、どのドメインに接続したかは経路上の観測者に見えます。これはTLSとSNIの一般的な性質であり、Lattice固有の特性ではありません。
VPC内の通信なので外部の観測者は問題になりませんが、次の2点は把握しておく必要があります。
- 内部の観測者はサービス呼び出しの関係を確認できます。 VPC内のトラフィックを観測できる人は、SNIから呼び出しグラフを再構成できます。
- フローログの宛先IPは意味をなさなくても、SNIは手掛かりになります。 つまり、先述した「宛先IPによる可観測性が崩れる」問題の一部を、SNIベースの可観測性で補える場合があります。
平文SNIが見える問題への対応: ECH
Encrypted Client Hello(ECH)は、SNIが露出しないようClientHello自体を暗号化する標準です。サーバーの公開鍵をDNS経由で事前に配布し、その鍵でClientHelloの機密部分を暗号化します。これにより、先述の「鶏と卵」の問題をDNSを使って回避します。
::: note TLS passthroughの要件 AWSは、TLSリスナーではECHまたはESNIをサポートしないこと、カスタムドメインが必要であること、サービス選択にSNIを使うことを明示しています。長期間維持するプロトコルを移行する前に、アイドル/接続時間の上限とターゲットのTCPヘルスチェックを確認してください。 :::
SNIベースの制御アプライアンスがある環境への影響
金融業界を含む多くの組織では、SNIを基にトラフィックを制御するアプライアンス(許可ドメインのホワイトリスト、SNIベースのログ、ドメイン単位のポリシー適用)を運用しています。Latticeを採用すると、このような環境に2つの面で影響します。
| 構成 | SNIアプライアンスから見た影響 |
|---|---|
| HTTPSリスナー | クライアントが送信するSNIはLatticeサービスのドメインです。既存のホワイトリストにLatticeドメイン(*.vpc-lattice-svcs.<region>.on.awsまたはカスタムドメイン)を追加する必要があります。それ以降のLattice→ターゲット区間はアプライアンスから見えません |
| TLS Passthrough | SNIがエンドツーエンドで維持されるため、SNIベースの制御と相性がよい方式です。ただしIAM Authは利用できません |
| リンクローカル範囲 | 宛先IPベースの制御アプライアンスが機能しなくなります(前述の「問題2」を参照) |
カスタムドメインを使う場合、ここでドキュメント03のHostヘッダーの落とし穴に直面します。 SNI制御のためにカスタムドメインを割り当てても、署名処理が引き続きLattice生成ドメインを使うと403になります。カスタムドメインの導入時には、SNI制御、署名対象のHost値、証明書管理をまとめて決定してください。
まとめ
- リンクローカルアドレスは「このパケットはインフラストラクチャが処理する」という目印です。IMDSやPod Identity Agentと同じアドレス群に属し、Latticeがサイドカーを使わずにトラフィックへ介入する方法です。
- IPv4は
169.254.171.0/24(リンクローカル)ですが、IPv6はリンクローカルではなくULAのfd00:ec2:80::/64です。 LatticeトラフィックはVPC内でルーティングする必要があり、リンクスコープだけでは不十分です。 - 共存時のルーティングとサービスを認識する属性付けを検証します。レビュー済みのプレフィックスリストIaCを使い、ネットワーク/アプリケーションのログを相関させてください。
- SNIが平文なのは、証明書選択における「鶏と卵」の問題に対する意図的な妥協です。また、TLS Passthroughによるルーティングを可能にします。
- TLSを終端しなければ、Latticeは暗号化されたHTTP SigV4ヘッダーを認証できません。匿名のネットワークコンテキストポリシーとエンドポイント認証は、別々の制御です。
- raw TCPはサービスリスナーのプロトコルではありません。TCPリソース設定は別の、サポートされている接続モデルです。
次はワークロードアイデンティティの移行で、IAMがSPIREの役割をどこまで引き継げるかを見ていきます。
参考資料
ターゲットグループとプロトコルバージョン: HTTPSターゲットの証明書動作とHTTP/2/gRPCリスナー要件
TLSリスナーの運用上限も重要です。デフォルトのforwardルールのみがサポートされ、Lambdaターゲットは対象外です。接続時間は最長10分で、サービスのアイドルタイムアウトは60~600秒の範囲で設定できます。TCPターゲットグループのヘルスチェックは既定で無効です。有効化するには、サポートされるプローブプロトコル/バージョンを使う必要があります。長時間接続を採用する前に、現在のAPIとリージョンの設定を確認してください。