RFC 1918定義外のIPアドレスをVPCのCIDRブロックに指定してみた

良い子は絶対にマネしないでね
2022.06.14

RFC 1918定義外のIPアドレスをVPCのCIDRブロックに指定するとどうなるのかな

こんにちは、のんピ(@non____97)です。

皆さんはRFC 1918定義外のIPアドレスをVPCのCIDRブロックに指定するとどうなるか気になったことはありますか? 私は今とても気になっています。

RFC 1918では以下のようにプライベートIPアドレスとして使用されるIPアドレスが定義されています。

  • 10.0.0.0/8
  • 172.16.0.0/12
  • 192.168.0.0/24

もし、この範囲外のIPアドレスをVPCのCIDRブロックとして設定したらどのような挙動になるのでしょうか。

AWS公式ドキュメントを確認すると、以下のように記載がありました。

VPC を作成するときは、RFC 1918 に指定されているように、プライベート IPv4 アドレス範囲からの CIDR ブロックを指定することをお勧めします。

(中略)

VPC を作成する場合、RFC 1918 に指定されているプライベート IPv4 アドレスの範囲から外れる、パブリックにルーティングできる CIDR ブロックを使うこともできますが、本書ではプライベート IPv4 アドレスを VPC の CIDR 範囲内にある IPv4 アドレスという意味で使います。

VPC とサブネットの概要 - Amazon Virtual Private Cloud

どうやら、RFC 1918で定義されているIPアドレスである必要はないようですね。

これは検証するしかない

いきなりまとめ

  • RFC 1918定義外のIPアドレスをVPCのCIDRブロックに指定することは可能
  • 以下の通信は可能
    • 名前解決
    • 時刻同期
    • VPC内の通信
    • VPC間の通信
    • Interface型のVPCエンドポイントを経由した通信
    • Gateway型のVPCエンドポイントを経由した通信
  • インターネット上のリソースへのアクセスする場合は、パブリックIPアドレスが割り当てられているか、NAT Gatewayを経由する必要がある
  • 良い子は絶対にマネしてはいけない
    • RFC 1918のIPアドレスでなければサポートされないリスクがある
    • 例) ALB、NLBのターゲットグループではターゲットをIPした場合、RFC 1918とRFC 6598のIPアドレスしか指定できない

やってみた

検証環境の構築

早速やってみます。

流石に実際に使用されているグローバルIPアドレスを使用するのはよろしくないので、RFC 6890で定義されているテスト用のIPアドレスを指定します。

  • 192.0.2.0/24
  • 198.51.100.0/24
  • 203.0.113.0/24

今回は192.0.2.0/24198.51.100.0/24を使ってVPCを2つ作成します。

構成は以下の通りです。

構成図

検証の構成はAWS CDKで定義しました。使用したコードは以下リポジトリに保存しています。

作成したリソースの確認

VPC

AWS CDKで作成されたリソースを確認します。

まず、VPCです。

RFC 1918定義外のIPアドレスをVPCのCIDRブロックとして割り当てましたが、状態はAvailableと元気にやっているようです。

VPC A

VPC B

EC2インスタンス

次にEC2インスタンスです。

4台全て実行されていますね。

EC2インスタンス

NAT Gateway

NAT Gatewayも確認してみましょう。

プライベートIPアドレス、Elastic IPアドレス共にRFC 1918定義外のIPアドレスとなっていますね。

NAT Gateway

VPCエンドポイント

最後にVPCエンドポイントを確認します。

Gateway型、Interface型どちらのVPCエンドポイントも使用可能になっています。

VPCエンドポイント

名前解決確認

以降はVPC上のEC2インスタンス上から色々動作確認してみます。

まずは、名前解決です。

VPC AのPublic subnet上のEC2インスタンスにSSMセッションマネージャーで接続します。

接続後、名前解決できるか確認します。

# 自身のIPアドレスを確認
# RFC 1918定義外のIPアドレスであることを確認
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
    link/ether 0e:7a:fe:48:2b:45 brd ff:ff:ff:ff:ff:ff
    inet 192.0.2.8/28 brd 192.0.2.15 scope global dynamic eth0
       valid_lft 3030sec preferred_lft 3030sec
    inet6 fe80::c7a:feff:fe48:2b45/64 scope link
       valid_lft forever preferred_lft forever

# Amazon Provided DNSで名前解決できるかを確認
$ dig dev.classmethod.jp

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>> dev.classmethod.jp
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39900
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;dev.classmethod.jp.            IN      A

;; ANSWER SECTION:
dev.classmethod.jp.     300     IN      A       75.2.71.201
dev.classmethod.jp.     300     IN      A       99.83.185.173

;; Query time: 3 msec
;; SERVER: 192.0.2.2#53(192.0.2.2)
;; WHEN: Tue Jun 14 01:41:54 UTC 2022
;; MSG SIZE  rcvd: 79

# Google Public DNSで名前解決できるかを確認
$ dig dig dev.classmethod.jp @8.8.8.8

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>> dig dev.classmethod.jp @8.8.8.8
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 57249
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;dig.                           IN      A

;; AUTHORITY SECTION:
.                       1745    IN      SOA     a.root-servers.net. nstld.verisign-grs.com. 2022061302 1800 900 604800 86400

;; Query time: 5 msec
;; SERVER: 192.0.2.2#53(192.0.2.2)
;; WHEN: Tue Jun 14 04:59:22 UTC 2022
;; MSG SIZE  rcvd: 107

;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62224
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;dev.classmethod.jp.            IN      A

;; ANSWER SECTION:
dev.classmethod.jp.     300     IN      A       75.2.71.201
dev.classmethod.jp.     300     IN      A       99.83.185.173

;; Query time: 10 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Tue Jun 14 04:59:22 UTC 2022
;; MSG SIZE  rcvd: 79

名前解決はできるようですね。

時刻同期確認

次に時刻同期されているかを確認します。

$ chronyc sources -v

  .-- Source mode  '^' = server, '=' = peer, '#' = local clock.
 / .- Source state '*' = current best, '+' = combined, '-' = not combined,
| /             'x' = may be in error, '~' = too variable, '?' = unusable.
||                                                 .- xxxx [ yyyy ] +/- zzzz
||      Reachability register (octal) -.           |  xxxx = adjusted offset,
||      Log2(Polling interval) --.      |          |  yyyy = measured offset,
||                                \     |          |  zzzz = estimated error.
||                                 |    |           \
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^* 169.254.169.123               3   4   377    11    +30us[  +30us] +/-  525us
^- 107-194-210-155.lightspe>     2   6   377    52   -581us[ -583us] +/-   46ms
^- 44.190.6.254                  1   6   377    51  +2377us[+2375us] +/-   34ms
^- eterna.binary.net             2   6   377    52   +471us[ +469us] +/-   57ms
^- time.cloudflare.com           3   6   377    51  -1281us[-1283us] +/-   26ms

169.254.169.123のAmazon Time Sync Serviceと時刻同期しているようです。

インターネット上のリソースへのアクセス

パブリックIPアドレスが割り当てられているEC2インスタンス

次に、インターネット上のリソースにアクセスできるか確認します。

まず、パブリックIPアドレスが割り当てられているEC2インスタンスから確認します。

VPC AのPublic subnet上のEC2インスタンスにSSMセッションマネージャーで接続して、DevelopersIOにアクセスできるか確認します。

# 割り当てられたパブリックIPアドレスを確認
$ curl checkip.amazonaws.com
52.86.168.35

# DevelopersIOにアクセスできるか確認
$ curl -I https://dev.classmethod.jp
HTTP/2 200
date: Tue, 14 Jun 2022 01:43:44 GMT
content-type: text/html; charset=utf-8
content-length: 163188
set-cookie: AWSALB=DMIY7GPpPPtM5yZ5stNMEoKGvV8BoouQkdaNxtkyz7t3XEStqu1OLEyEO/MH0L4zpPB45HQua5ziHLffNlEgXZkxM3aEkfTLaTar85Tmr30JnBjkeI8gnbRIDSDG; Expires=Tue, 21 Jun 2022 01:43:44 GMT; Path=/
set-cookie: AWSALBCORS=DMIY7GPpPPtM5yZ5stNMEoKGvV8BoouQkdaNxtkyz7t3XEStqu1OLEyEO/MH0L4zpPB45HQua5ziHLffNlEgXZkxM3aEkfTLaTar85Tmr30JnBjkeI8gnbRIDSDG; Expires=Tue, 21 Jun 2022 01:43:44 GMT; Path=/; SameSite=None; Secure
server: nginx/1.20.0
vary: Accept-Encoding
x-amzn-requestid: c41cfd2e-ddb6-43a7-b2a2-5c693cb4b122
x-amzn-remapped-content-length: 163188
x-amz-apigw-id: TsEncHRotjMFVCQ=
cache-control: max-age=300
etag: "27d74-J3systv+xBoJsM1edNX7+iqXy/I"
x-powered-by: Express
x-amzn-trace-id: Root=1-62a7e7c9-469ae1de6eb318900ea75c2a;Sampled=0
via: 1.1 3576e59a290d96db1fe4f3fc4ce2e3d8.cloudfront.net (CloudFront), 1.1 f27b99e1dcf2dfec4d479038623819b0.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT57-C3
vary: Accept-Encoding
x-cache: Hit from cloudfront
x-amz-cf-pop: NRT20-C2
x-amz-cf-id: jeCvZjGM6SjtwyadHI2iOuDYlfJwQquQI2AnTGdFyqaw2Ir2BS_bAg==
age: 7
expires: Tue, 14 Jun 2022 01:48:44 GMT
strict-transport-security: max-age=31536000; includeSubDomains
accept-ranges: bytes

HTTPステータスコード200が返って来たことからインターネット上のリソースへのアクセスもできそうです。

ついでにtracerouteでどんな経路を通っているのかニヤニヤしてみましょう。

$ sudo traceroute -T dev.classmethod.jp
traceroute to dev.classmethod.jp (99.83.185.173), 30 hops max, 60 byte packets
 1  * * *
 2  240.3.12.67 (240.3.12.67)  0.241 ms 240.3.12.65 (240.3.12.65)  0.250 ms 240.3.12.64 (240.3.12.64)  0.250 ms
 3  243.254.16.129 (243.254.16.129)  0.230 ms 243.254.22.9 (243.254.22.9)  0.224 ms 243.254.17.137 (243.254.17.137)  0.209 ms
 4  240.3.12.48 (240.3.12.48)  0.206 ms 240.3.12.49 (240.3.12.49)  0.186 ms 240.3.12.59 (240.3.12.59)  0.316 ms
 5  240.1.40.6 (240.1.40.6)  0.349 ms 240.1.40.5 (240.1.40.5)  0.356 ms 240.1.40.6 (240.1.40.6)  0.337 ms
 6  240.1.40.17 (240.1.40.17)  0.290 ms 240.1.40.20 (240.1.40.20)  0.296 ms 240.1.40.31 (240.1.40.31)  0.280 ms
 7  240.0.40.12 (240.0.40.12)  0.377 ms 240.0.40.15 (240.0.40.15)  0.361 ms 240.0.36.14 (240.0.36.14)  0.395 ms
 8  243.254.1.9 (243.254.1.9)  0.356 ms 243.254.0.1 (243.254.0.1)  0.360 ms 243.254.5.137 (243.254.5.137)  0.797 ms
 9  240.0.36.29 (240.0.36.29)  0.552 ms 240.0.36.24 (240.0.36.24)  0.547 ms 240.0.40.16 (240.0.40.16)  0.527 ms
10  242.0.163.161 (242.0.163.161)  0.518 ms 242.0.162.33 (242.0.162.33)  1.720 ms 242.0.162.49 (242.0.162.49)  1.713 ms
11  52.93.28.163 (52.93.28.163)  1.648 ms 52.93.28.197 (52.93.28.197)  1.678 ms 52.93.28.139 (52.93.28.139)  1.671 ms
12  100.100.10.98 (100.100.10.98)  1.645 ms 100.100.10.74 (100.100.10.74)  1.591 ms 100.100.10.96 (100.100.10.96)  1.630 ms
13  * * *
14  a5b041b48e73d3807.awsglobalaccelerator.com (99.83.185.173)  2.565 ms  2.503 ms  2.541 ms

色々なネットワークをホップしているのが分かってテンション上がりますね。

NAT Gateway経由

次に、NAT Gatewayを経由してインターネット上のリソースにアクセスできるか確認します。

VPC AのPrivate subnet上のEC2インスタンスにSSMセッションマネージャーで接続して、DevelopersIOにアクセスできるか確認します。

# 自身のIPアドレスを確認
# RFC 1918定義外のIPアドレスであることを確認
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
    link/ether 0e:84:41:bf:1b:a9 brd ff:ff:ff:ff:ff:ff
    inet 192.0.2.25/28 brd 192.0.2.31 scope global dynamic eth0
       valid_lft 2570sec preferred_lft 2570sec
    inet6 fe80::c84:41ff:febf:1ba9/64 scope link
       valid_lft forever preferred_lft forever

# 割り当てられたパブリックIPアドレスを確認
$ curl checkip.amazonaws.com
34.226.9.234

# tracerouteでDevelopersIOのIPアドレスに到達できることを確認
$ sudo traceroute -T dev.classmethod.jp
traceroute to dev.classmethod.jp (75.2.71.201), 30 hops max, 60 byte packets
 1  ip-192-0-2-7.ec2.internal (192.0.2.7)  0.088 ms  0.089 ms  0.067 ms
 2  * * *
 3  240.3.12.67 (240.3.12.67)  1.027 ms 240.3.12.65 (240.3.12.65)  0.887 ms 240.3.12.64 (240.3.12.64)  0.899 ms
 4  243.254.17.1 (243.254.17.1)  0.637 ms 243.254.19.1 (243.254.19.1)  0.738 ms 243.254.23.129 (243.254.23.129)  0.768 ms
 5  240.3.12.58 (240.3.12.58)  0.650 ms 240.3.12.49 (240.3.12.49)  0.790 ms 240.3.12.53 (240.3.12.53)  0.705 ms
 6  240.1.40.4 (240.1.40.4)  1.272 ms 240.1.40.7 (240.1.40.7)  1.011 ms 240.1.40.5 (240.1.40.5)  1.037 ms
 7  240.1.40.19 (240.1.40.19)  0.925 ms 240.1.40.29 (240.1.40.29)  0.944 ms 240.1.40.31 (240.1.40.31)  2.425 ms
 8  240.0.40.14 (240.0.40.14)  1.061 ms 240.0.36.15 (240.0.36.15)  1.150 ms 240.0.40.12 (240.0.40.12)  1.089 ms
 9  243.254.1.1 (243.254.1.1)  1.029 ms 243.254.3.9 (243.254.3.9)  1.295 ms 243.254.0.129 (243.254.0.129)  0.920 ms
10  240.0.36.19 (240.0.36.19)  1.365 ms 240.0.36.31 (240.0.36.31)  1.085 ms 240.0.40.30 (240.0.40.30)  1.605 ms
11  242.0.163.33 (242.0.163.33)  4.523 ms 242.0.163.161 (242.0.163.161)  1.041 ms 242.0.163.49 (242.0.163.49)  1.166 ms
12  52.93.28.165 (52.93.28.165)  2.519 ms 52.93.28.171 (52.93.28.171)  1.935 ms 52.93.28.179 (52.93.28.179)  1.771 ms
13  100.100.10.80 (100.100.10.80)  1.935 ms 100.100.10.24 (100.100.10.24)  9.618 ms 100.100.10.62 (100.100.10.62)  2.186 ms
14  * * *
15  a5b041b48e73d3807.awsglobalaccelerator.com (75.2.71.201)  1.635 ms  1.783 ms  1.733 ms

最初にNAT GatewayのプライベートIPアドレスである192.0.2.7にホップしていることからNAT Gatewayを経由して通信していることが分かります。

パブリックIPアドレスが割り当てられていないEC2インスタンス

次に、パブリックIPアドレスが割り当てられていないEC2インスタンスからインターネット上のリソースにアクセスできるか確認します。

VPC AのPublic subnet上のEC2インスタンスにパブリックIPアドレスを持たないEC2インスタンスを作成します。

VPC AのPublic subnet上のEC2インスタンスにパブリックIPアドレスを持たないEC2インスタンスを作成

EC2インスタンス作成後、SSMセッションマネージャーで接続して、DevelopersIOにアクセスできるか確認します。なお、SSMセッションマネージャーが使えるのはVPCエンドポイントを用意しているためです。

# 自身のIPアドレスを確認
# RFC 1918定義外のIPアドレスであることを確認
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
    link/ether 0e:59:9a:1d:7a:37 brd ff:ff:ff:ff:ff:ff
    inet 192.0.2.14/28 brd 192.0.2.15 scope global dynamic eth0
       valid_lft 3434sec preferred_lft 3434sec
    inet6 fe80::c59:9aff:fe1d:7a37/64 scope link
       valid_lft forever preferred_lft forever

# 割り当てられたパブリックIPアドレスを確認
$ curl -m 5 checkip.amazonaws.com
curl: (28) Failed to connect to checkip.amazonaws.com port 80 after 4924 ms: Connection timed out

割り当てられたパブリックIPアドレスを確認するためにcheckip.amazonaws.comにアクセスしようとしたところタイムアウトしました。パブリックIPアドレスがないとインターネットには出ていけないようですね。

EC2インスタンス間の通信

同一VPCのEC2インスタンス間

EC2インスタンス間の通信ができるか確認します。

VPC AのPublic subnetとIsolated subnetのEC2インスタンス間で疎通確認してみます。

$ ping 192.0.2.43 -c 5
PING 192.0.2.43 (192.0.2.43) 56(84) bytes of data.
64 bytes from 192.0.2.43: icmp_seq=1 ttl=255 time=2.05 ms
64 bytes from 192.0.2.43: icmp_seq=2 ttl=255 time=0.300 ms
64 bytes from 192.0.2.43: icmp_seq=3 ttl=255 time=0.350 ms
64 bytes from 192.0.2.43: icmp_seq=4 ttl=255 time=0.340 ms
64 bytes from 192.0.2.43: icmp_seq=5 ttl=255 time=0.286 ms

--- 192.0.2.43 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4050ms
rtt min/avg/max/mdev = 0.286/0.665/2.053/0.694 ms

余裕ですよと言わんばかりに通信できました。

異なるVPCのEC2インスタンス間

次に異なるVPCのEC2インスタンス間で疎通確認をしてみます。

VPC AのPublic subnetのEC2インスタンスからVPC BのPublic subnetのEC2インスタンスに疎通確認します。

$ ping 198.51.100.8 -c 5
PING 198.51.100.8 (198.51.100.8) 56(84) bytes of data.
64 bytes from 198.51.100.8: icmp_seq=1 ttl=255 time=0.630 ms
64 bytes from 198.51.100.8: icmp_seq=2 ttl=255 time=0.268 ms
64 bytes from 198.51.100.8: icmp_seq=3 ttl=255 time=0.267 ms
64 bytes from 198.51.100.8: icmp_seq=4 ttl=255 time=0.330 ms
64 bytes from 198.51.100.8: icmp_seq=5 ttl=255 time=0.363 ms

--- 198.51.100.8 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4081ms
rtt min/avg/max/mdev = 0.267/0.371/0.630/0.136 ms

こちらも疎通確認できました。

VPCエンドポイント

Interface型

最後にVPCエンドポイント経由でAWSのエンドポイントに通信できるかを確認します。

まずはInterface型のVPCエンドポイントの動作確認をします。

先ほどパブリックIPアドレスが割り当てられていないEC2インスタンスにSSMセッションマネージャーができることを確認できました。そのため、Interface型のVPCエンドポイントを経由して通信できることは分かっていますが、改めて検証してみます。

VPC AのIsolated subnet上のEC2インスタンスにSSMセッションマネージャーで接続して、SSMのサービスエンドポイントに通信できるか確認します。

# 自身のIPアドレスを確認
# RFC 1918定義外のIPアドレスであることを確認
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
    link/ether 0e:2d:9c:20:e9:15 brd ff:ff:ff:ff:ff:ff
    inet 192.0.2.43/28 brd 192.0.2.47 scope global dynamic eth0
       valid_lft 2280sec preferred_lft 2280sec
    inet6 fe80::c2d:9cff:fe20:e915/64 scope link
       valid_lft forever preferred_lft forever

# 割り当てられたパブリックIPアドレスを確認
$ curl -m 5 checkip.amazonaws.com
curl: (28) Failed to connect to checkip.amazonaws.com port 80 after 4922 ms: Connection timed out

# SSMのサービスエンドポイントを名前解決
# VPCエンドポイントのプライベートIPアドレスが返ってくることを確認
$ dig ssm.us-east-1.amazonaws.com

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>> ssm.us-east-1.amazonaws.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7321
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;ssm.us-east-1.amazonaws.com.   IN      A

;; ANSWER SECTION:
ssm.us-east-1.amazonaws.com. 34 IN      A       192.0.2.39

;; Query time: 0 msec
;; SERVER: 192.0.2.2#53(192.0.2.2)
;; WHEN: Tue Jun 14 02:20:16 UTC 2022
;; MSG SIZE  rcvd: 72

# VPCエンドポイントを経由してSSMのサービスエンドポイントに到達できることを確認
$ sudo traceroute -T -p 443 ssm.us-east-1.amazonaws.com
traceroute to ssm.us-east-1.amazonaws.com (192.0.2.39), 30 hops max, 60 byte packets
 1  ip-192-0-2-39.ec2.internal (192.0.2.39)  0.154 ms  0.287 ms  0.124 ms
 2  * * *
 3  * * *
 4  * * *
 5  ip-192-0-2-39.ec2.internal (192.0.2.39)  1.427 ms  1.318 ms  1.458 ms
 6  ip-192-0-2-39.ec2.internal (192.0.2.39)  1.398 ms *  1.418 ms
 7  ip-192-0-2-39.ec2.internal (192.0.2.39)  1.339 ms *  1.568 ms
 8  ip-192-0-2-39.ec2.internal (192.0.2.39)  1.321 ms  53.667 ms  1.659 ms
 9  ip-192-0-2-39.ec2.internal (192.0.2.39)  3.448 ms  2.134 ms  3.604 ms
10  ip-192-0-2-39.ec2.internal (192.0.2.39)  2.866 ms  2.252 ms *
11  ip-192-0-2-39.ec2.internal (192.0.2.39)  2.525 ms  2.964 ms  2.219 ms
12  ip-192-0-2-39.ec2.internal (192.0.2.39)  1.458 ms  1.266 ms  1.238 ms

VPCエンドポイントを経由してSSMのサービスエンドポイントに到達できることを確認できました。

AWS CLIでSSMのコマンドも叩けるか確認してみます。

$ aws ssm list-associations \
    --region us-east-1
{
    "Associations": [
        {
            "ScheduleExpression": "cron(0 00 03 ? * TUE *)",
            "Name": "AWS-UpdateSSMAgent",
            "LastExecutionDate": 1655173766.639,
            "Overview": {
                "Status": "Success",
                "DetailedStatus": "Success",
                "AssociationStatusAggregatedCount": {
                    "Success": 4
                }
            },
            "AssociationId": "0b3f9648-c9fc-4eb5-bddc-9ab6636081eb",
            "AssociationVersion": "1",
            "Targets": [
                {
                    "Values": [
                        "*"
                    ],
                    "Key": "InstanceIds"
                }
            ]
        }
    ]
}

対応したサービスのVPCエンドポイントがあればAWS CLIの実行も問題なくできそうですね。

Gateway型

最後のGateway型のVPCエンドポイントの動作確認をします。

VPC AのIsolated subnet上のEC2インスタンスにSSMセッションマネージャーで接続して、S3上のオブジェクト(SSM Agentのインストーラ)にアクセスできるか確認します。

# VPCがあるリージョンと同じリージョンを指定してアクセス
$ curl -I -m 5 https://s3.us-east-1.amazonaws.com/amazon-ssm-us-east-1/latest/linux_amd64/amazon-ssm-agent.rpm
HTTP/1.1 200 OK
x-amz-id-2: wgljHdLpSxaKPdWxpYr3B9cQMoVOTqhwYTJndg3PfqFOE0x3sBh+/iL3t/p0voWGqtXrIUVbdUI=
x-amz-request-id: 3FCN3CY6N458BFVG
Date: Tue, 14 Jun 2022 02:37:00 GMT
Last-Modified: Fri, 27 May 2022 21:34:39 GMT
ETag: "bd29775c367db967f1c6c11ebe7a305d-4"
x-amz-version-id: bP604IuhMNbziA0OuJjJ3Ob_WPa_nEFT
Accept-Ranges: bytes
Content-Type: binary/octet-stream
Server: AmazonS3
Content-Length: 26739016

# グローバルURLを指定してアクセス
$ curl -I -m 5 https://s3.amazonaws.com/amazon-ssm/latest/linux_amd64/amazon-ssm-agent.rpm
HTTP/1.1 301 Moved Permanently
x-amz-bucket-region: eu-west-1
x-amz-request-id: HGSZX056AV4T8CRY
x-amz-id-2: oj7lqtPIYvcc130LTGLrL6Mvd9HdiEUbXoKS4I6f9hhNNZGldQClWpNjNNHJuftW6gJTy4X5WKPITbKADDwtzg==
Content-Type: application/xml
Date: Tue, 14 Jun 2022 02:37:25 GMT
Server: AmazonS3

# VPCがあるリージョンと異なるリージョンを指定してアクセス
$ curl -I -m 5 https://s3.ap-northeast-1.amazonaws.com/amazon-ssm-ap-northeast-1/latest/linux_amd64/amazon-ssm-agent.rpm
curl: (28) Connection timed out after 5001 milliseconds

# tracerouteでも確認
$ sudo traceroute -T -p 443 s3.us-east-1.amazonaws.com
traceroute to s3.us-east-1.amazonaws.com (52.217.83.118), 30 hops max, 60 byte packets
 1  * * *
 2  * * *
 3  * * *
 4  * * *
 5  * * *
 6  * * *
 7  * * *
 8  s3-1.amazonaws.com (52.217.83.118)  0.202 ms  0.264 ms  0.241 ms

$ sudo traceroute -T -p 443 s3.amazonaws.com
traceroute to s3.amazonaws.com (52.216.97.237), 30 hops max, 60 byte packets
 1  * * *
 2  * * *
 3  * * *
 4  * * *
 5  * * *
 6  * * *
 7  * s3-1.amazonaws.com (52.216.97.237)  0.930 ms  0.902 ms

$ sudo traceroute -T -p 443 s3.ap-northeast-1.amazonaws.com
traceroute to s3.ap-northeast-1.amazonaws.com (52.219.0.254), 30 hops max, 60 byte packets
 1  * * *
 2  * * *
 3  * * *
 4  * * *
 5  * * *
 6  * * *
 7  * * *
 8  * * *
 9  * * *
10  * * *
11  * * *
12  * * *
13  * * *
14  * * *
15  * * *
16  * * *
17  * * *
18  * * *
19  * * *
20  * * *
21  * * *
22  * * *
23  * * *
24  * * *
25  * * *
26  * * *
27  * * *
28  * * *
29  * * *
30  * * *

VPCがあるリージョンと同じリージョンを指定した場合はアクセスでき、異なるリージョンを指定した場合はアクセスできないことから、S3のGateway型のVPCエンドポイントを経由して通信できていることが確認できました。

念の為、Public subnet上のEC2インスタンスから、VPCがあるリージョンと異なるリージョンを指定してアクセスできるか確認します。

$ curl -I -m 5 https://s3.ap-northeast-1.amazonaws.com/amazon-ssm-ap-northeast-1/latest/linux_amd64/amazon-ssm-agent.rpm
HTTP/1.1 200 OK
x-amz-id-2: ZDL/EPQwLgTOGUuVx/wSIPL8KFwTuVv+ToQJUPrlpxCSlk8uAhI5qx3VlRUzV83Hshtcc6sBHJE=
x-amz-request-id: B9N7VGY0D41106JE
Date: Tue, 14 Jun 2022 05:16:13 GMT
Last-Modified: Mon, 13 Jun 2022 17:06:18 GMT
ETag: "659565c08417dd0067bceb2157e2a0da-4"
x-amz-version-id: vbaaIrgvuJt_C_9lA0pOmH1v9ZUXnVXJ
Accept-Ranges: bytes
Content-Type: binary/octet-stream
Server: AmazonS3
Content-Length: 26746476

$ sudo traceroute -T -p 443 s3.ap-northeast-1.amazonaws.com
traceroute to s3.ap-northeast-1.amazonaws.com (52.219.8.136), 30 hops max, 60 byte packets
 1  * * *
 2  240.3.12.65 (240.3.12.65)  0.229 ms  0.225 ms 240.3.12.67 (240.3.12.67)  0.203 ms
 3  243.254.18.129 (243.254.18.129)  0.349 ms 243.254.23.5 (243.254.23.5)  0.331 ms 243.254.19.129 (243.254.19.129)  0.317 ms
 4  240.3.12.58 (240.3.12.58)  0.298 ms 240.3.12.52 (240.3.12.52)  0.299 ms 240.3.12.59 (240.3.12.59)  0.289 ms
 5  240.1.40.5 (240.1.40.5)  0.371 ms 240.1.40.4 (240.1.40.4)  0.405 ms  0.400 ms
 6  240.1.40.19 (240.1.40.19)  0.327 ms 240.1.40.18 (240.1.40.18)  0.297 ms 240.1.40.28 (240.1.40.28)  0.287 ms
 7  240.0.36.13 (240.0.36.13)  0.507 ms 240.0.40.14 (240.0.40.14)  0.392 ms 240.0.36.14 (240.0.36.14)  0.428 ms
 8  243.254.2.137 (243.254.2.137)  0.356 ms 243.254.4.5 (243.254.4.5)  0.344 ms 243.254.1.1 (243.254.1.1)  0.351 ms
 9  240.0.36.24 (240.0.36.24)  0.399 ms 240.0.40.30 (240.0.40.30)  0.338 ms 240.0.36.21 (240.0.36.21)  0.328 ms
10  242.0.163.161 (242.0.163.161)  0.496 ms 242.0.163.49 (242.0.163.49)  1.137 ms 242.0.162.161 (242.0.162.161)  0.335 ms
11  52.93.28.145 (52.93.28.145)  1.158 ms 52.93.28.149 (52.93.28.149)  1.203 ms 52.93.28.185 (52.93.28.185)  1.028 ms
12  100.100.8.78 (100.100.8.78)  1.021 ms 100.100.6.28 (100.100.6.28)  1.011 ms 100.100.6.84 (100.100.6.84)  9.703 ms
13  100.91.137.145 (100.91.137.145)  147.102 ms 100.91.149.245 (100.91.149.245)  193.792 ms 100.91.149.87 (100.91.149.87)  143.056 ms
14  15.230.161.61 (15.230.161.61)  146.656 ms 52.93.72.83 (52.93.72.83)  170.126 ms 15.230.161.7 (15.230.161.7)  143.715 ms
15  15.230.129.143 (15.230.129.143)  169.931 ms 52.93.72.182 (52.93.72.182)  145.346 ms 15.230.129.139 (15.230.129.139)  168.634 ms
16  15.230.154.143 (15.230.154.143)  170.378 ms  145.993 ms 27.0.0.72 (27.0.0.72)  143.717 ms
17  240.0.252.7 (240.0.252.7)  143.649 ms 240.0.252.5 (240.0.252.5)  143.872 ms  143.780 ms
18  240.0.252.28 (240.0.252.28)  167.276 ms 240.0.252.30 (240.0.252.30)  166.251 ms 240.0.252.23 (240.0.252.23)  144.760 ms
19  241.0.7.196 (241.0.7.196)  144.361 ms 241.0.7.192 (241.0.7.192)  144.485 ms 241.0.7.199 (241.0.7.199)  170.047 ms
20  * * *
21  * * *
22  * * *
23  s3-ap-northeast-1.amazonaws.com (52.219.8.136)  143.920 ms  144.888 ms  143.843 ms

Public subnet上のEC2インスタンスはパブリックIPアドレスが割り当てられているため、異なるリージョンを指定した場合も通信できることを確認できました。

良い子は絶対にマネしないでね

RFC 1918定義外のIPアドレスをVPCのCIDRブロックに指定してみました。

意外と通信できるということが分かりスッキリしました。

しかし、AWSではVPCにRFC 1918に指定されたIPアドレスをCIDRブロックに割り当てることが推奨されており、それ以外のIPアドレスを指定すると予期せぬトラブルに遭遇することが考えられます。

例えば、ALB、NLBのターゲットグループではターゲットをIPした場合はRFC 1918とRFC 6598のIPアドレスしか指定できません。

Q: 任意の IP アドレスに負荷分散できますか?

A: ロードバランサーの VPC CIDR の任意の IP アドレスをロードバランサーの VPC 内のターゲットとして使用できます。また、RFC 1918 範囲 (10.0.0.0/8、172.16.0.0/12、192.168.0.0/16) または RFC 6598 範囲 (100.64.0.0/10) の IP アドレスをロードバランサーの VPC 外のターゲットとして使用できます (たとえば、ピアリング接続された VPC、Amazon EC2 Classic、AWS Direct Connect または VPN 接続によって到達可能なオンプレミスのロケーションのターゲットなど)。

よくある質問 - Elastic Load Balancing | AWS

同様に、「RFC 1918定義外のIPアドレスは非サポートだった」という場面に遭遇するリスクがあると思いますので、良い子は絶対にマネしないでください。

この記事が誰かの助けになれば幸いです。

以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!