一覧CL-04-3 · 仮想ネットワーク

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

1
cat topology.txt cat config.json
A 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
}
2
python3 connect.py peer --target B
forward=True return=False bidirectional=False
3
python3 connect.py set --key b_to_a python3 connect.py peer --target B
b_to_a=true
forward=True return=True bidirectional=True
4
python3 connect.py peer --target C
A -> B -> C blocked: peering is not transitive
5
python3 connect.py hub python3 connect.py set --key hub_to_a python3 connect.py hub
attachments=True forward=True return=False bidirectional=False
hub_to_a=true
attachments=True forward=True return=True bidirectional=True
6
python3 connect.py overlap --cidr 10.0.128.0/17
A=10.0.0.0/16 peer=10.0.128.0/17 overlaps=True
7
python3 connect.py dns python3 connect.py endpoint
api.service.example -> 198.51.100.40
destination=198.51.100.40
endpoint_path=not selected by DNS
8
python3 connect.py set --key private_dns python3 connect.py dns python3 connect.py endpoint
private_dns=true
api.service.example -> 10.0.2.5
destination=10.0.2.5
endpoint_path=blocked by endpoint SG
9
python3 connect.py set --key endpoint_sg_443 python3 connect.py endpoint
endpoint_sg_443=true
destination=10.0.2.5
endpoint_path=reachable (service authorization still required)

演習完了