VPC間接続とVPCエンドポイント
接続先が存在することだけでなく、往復経路と名前解決・制御の条件から到達範囲を説明します。
説明
ネットワークを接続しても、相手への経路だけでは往復通信は成立しません。戻り経路、接続方式が許す転送範囲、名前解決、接続先の制御を順に調べます。VPC peeringと中継用hub、サービス用endpointでは、つながる対象と役割が異なります。
A・B・Cの三つのVPCと、A内のサービス用interface endpointを使います。片方向だけの経路を直し、peeringの連鎖を通れない条件を確認した後、hub経由の往復と、endpointへの名前解決・443許可を調べます。固定構成の接続条件を一つずつ変更します。
接続先が存在することだけでなく、往復経路と名前解決・制御の条件から到達範囲を説明します。
1三つのVPCとendpointの役割
Aは10.0.0.0/16、Bは10.1.0.0/16、Cは10.2.0.0/16です。サービス用endpointはAの10.0.2.5へ接続するための別の入口です。
cat topology.txt接続方式ごとの構成を読む
cat config.json往復経路とendpointの初期条件を読むA-BとB-Cのpeeringがあり、別案としてAとCをhubへ接続しています。endpointはサービス向けの接続先で、三つのVPCを相互接続するルーターではありません。
2行きだけのpeering経路
AからBへの経路はありますが、BからAへの戻り経路を設定していない条件で確認します。
python3 connect.py peer --target BA-Bの行きと戻りを照合するforward=True、return=Falseでbidirectional=Falseです。接続の作成や片側の経路追加だけで、要求と応答の両方が通るとは限りません。
3戻り経路を追加する
BからAへの経路を有効にして同じ接続を確認します。
python3 connect.py set --key b_to_aBからAへの戻りを有効にする
python3 connect.py peer --target B同じ接続を再確認する行きと戻りがそろってbidirectional=Trueになります。この経路モデルでは他の通信制御は許可済みとし、経路の有無を確認しています。
4peeringを二つ並べても中継できない
AからBを経由してCへ行けるかを確認します。
python3 connect.py peer --target Cpeeringの連鎖を使う経路を確認するpeering is not transitiveとして拒否されます。A-BとB-Cがあっても、BをA-C間の中継点として使う接続にはなりません。必要な直接接続や、中継を扱う構成を別に設計します。
5hubでも戻りの経路が必要
AとCのhub接続は存在しますが、最初はhubからAへの戻りがありません。戻りを有効にして前後を確認します。
python3 connect.py hubhub接続と往復経路を確認する
python3 connect.py set --key hub_to_ahubからAへの戻りを有効にする
python3 connect.py hub変更後の往復を再確認するattachmentは両方存在していても、最初はreturn=Falseです。戻りを追加するとbidirectional=Trueになります。中継装置へ接続した事実と、宛先ごとの経路は別の設定です。
6接続するCIDRが重なる場合
Aの範囲と、10.0.128.0/17を比較します。
python3 connect.py overlap --cidr 10.0.128.0/17Aの範囲内に含まれるCIDRを照合するoverlaps=Trueです。10.0.128.0/17はAの10.0.0.0/16の一部なので、別の宛先範囲として扱えません。AWSのVPC peeringでは重複するCIDRを持つVPC間の接続は作成できません。
7名前がpublic側を指している状態
api.service.exampleの解決先と、endpoint経路を使うかを確認します。
python3 connect.py dnsサービス名の解決先を読む
python3 connect.py endpointendpoint経路が選ばれるか確認する解決先は198.51.100.40で、endpoint_pathはnot selected by DNSです。A内にendpointが存在していても、アプリがその接続先を使う名前解決になっているかを確認する必要があります。
8private側の名前解決だけを有効にする
名前解決をendpointの10.0.2.5へ向けます。
python3 connect.py set --key private_dnsサービス名をendpointのIPへ向ける
python3 connect.py dns変更後の解決先を確認する
python3 connect.py endpoint接続先の制御も評価する解決先は10.0.2.5へ変わりますが、endpointのSGに443の許可がなくblockedです。DNSがprivate IPを返すことと、そこへ接続できることは別の確認です。
9endpoint側の接続許可を追加する
endpointの443許可を有効にします。
python3 connect.py set --key endpoint_sg_443endpointへの443を許可する
python3 connect.py endpoint名前解決と接続制御がそろった結果を読むendpoint経路はreachableになります。ただしサービス操作にはIAMやendpoint policyなどの認可も必要です。ネットワーク到達の成功を、任意のデータを取得できる許可と同一視しないようにします。
まとめ
接続の作成と、行き・戻りの経路をそれぞれ確認します。
peeringの連鎖は中継経路にならず、重複するCIDRも接続の制約になります。
endpointは名前解決と接続制御を確認し、サービス操作の認可も別に調べます。
操作履歴と解説を振り返れます。
シェル / Python 3
cat topology.txt
cat config.jsonA 10.0.0.0/16 ── peering AB ── B 10.1.0.0/16 ── peering BC ── C 10.2.0.0/16
AとCの直接peeringはない。B経由の転送は許可しない。
別案: A ── hub ── C (両側attachmentと往復routeが必要)
サービス用interface endpoint: A内のENI 10.0.2.5へ名前解決する。
endpointの到達確認と、サービス操作の認可は別の検査。
{
"a_to_b": true,
"b_to_a": false,
"b_to_c": true,
"c_to_b": true,
"a_hub": true,
"c_hub": true,
"hub_to_c": true,
"hub_to_a": false,
"private_dns": false,
"endpoint_ip": "10.0.2.5",
"endpoint_sg_443": false
}python3 connect.py peer --target Bforward=True return=False bidirectional=False
python3 connect.py set --key b_to_a
python3 connect.py peer --target Bb_to_a=true forward=True return=True bidirectional=True
python3 connect.py peer --target CA -> B -> C blocked: peering is not transitive
python3 connect.py hub
python3 connect.py set --key hub_to_a
python3 connect.py hubattachments=True forward=True return=False bidirectional=False hub_to_a=true attachments=True forward=True return=True bidirectional=True
python3 connect.py overlap --cidr 10.0.128.0/17A=10.0.0.0/16 peer=10.0.128.0/17 overlaps=True
python3 connect.py dns
python3 connect.py endpointapi.service.example -> 198.51.100.40 destination=198.51.100.40 endpoint_path=not selected by DNS
python3 connect.py set --key private_dns
python3 connect.py dns
python3 connect.py endpointprivate_dns=true api.service.example -> 10.0.2.5 destination=10.0.2.5 endpoint_path=blocked by endpoint SG
python3 connect.py set --key endpoint_sg_443
python3 connect.py endpointendpoint_sg_443=true destination=10.0.2.5 endpoint_path=reachable (service authorization still required)
演習完了