PublicSubnetって?Publicじゃなければ絶対安全??


## この記事のまとめ

- Subnet の情報に IsPublic のような情報はない.
- Public Subnet かどうかは,Subnet に関連づいている RouteTable の Route に Internet Gateway が指定されているかどうか.
- Internet Gateway へのルートがない Subnet でも外部からの通信を受け付けることはできる.
  - ただし Internet Gateway に接続していないため受け付けた通信へのレスポンスは難しい.
- Subnet が Public かどうかに関わらず SecurityGroup などの対策はしっかりすることが重要.

# はじめに

最近 Public Subnet に存在しているインスタンスなどを全て列挙したい,という要件がありました.
DescribeSubnets API を叩いてレスポンスの IsPublic のような属性から Public Subnet を炙り出そうと思いましたが **API レスポンスにそんなフィールドはなかった**です.そこで Public Subnet かどうかの見分け方を調査したので本記事にまとめました.

また,調査した結果生じた疑問についても検証し,まとめましたので,よければ一読していただけると嬉しいです!
(この検証の話の方が分量多いです...)

## IsPublic は無い.じゃあどうする?

上でも述べていますが,Subnet の属性に IsPublic はありません.[公式のページ](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/configure-subnets.html#:~:text=%E3%83%91%E3%83%96%E3%83%AA%E3%83%83%E3%82%AF%E3%82%B5%E3%83%96%E3%83%8D%E3%83%83%E3%83%88%20%E2%80%93%20%E3%82%B5%E3%83%96%E3%83%8D%E3%83%83%E3%83%88%E3%81%AB%E3%81%AF%E3%80%81%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%8D%E3%83%83%E3%83%88%E3%82%B2%E3%83%BC%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A4%E3%81%B8%E3%81%AE%E7%9B%B4%E6%8E%A5%E3%83%AB%E3%83%BC%E3%83%88%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82%E3%83%91%E3%83%96%E3%83%AA%E3%83%83%E3%82%AF%E3%82%B5%E3%83%96%E3%83%8D%E3%83%83%E3%83%88%E5%86%85%E3%81%AE%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%AF%E3%80%81%E3%83%91%E3%83%96%E3%83%AA%E3%83%83%E3%82%AF%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%8D%E3%83%83%E3%83%88%E3%81%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82) を見てみると,**Internet Gateway との直接のルートがある場合に Public Subnet**と呼ばれるみたいです.

そのため,Public Subnet を列挙するには,

1. 全ての Subnet を列挙
2. それぞれの Subnet に関連付けられている RouteTable の Route に Internet Gateway が Target に指定されているかどうか確認する
3. 2 の結果が true であれば Public Subnet とみなす

といった手順で達成できると考えました(もっとクールな案があれば教えていただきたいです).

また少し話は変わりますが,上の公式ページから**Private Subnet**と**隔離された Subnet**という二つの Subnet のタイプがあることがわかりました.

- Private Subnet は NAT によるインターネットアクセスが可能な Subnet
- 隔離された Subnet は同じ VPC 内のリソースのみにアクセスできる Subnet

## ここで少し疑問:Public Subnet でなくても通信は受け付けるのでは?

Private Subnet と隔離された Subnet は,あたかも**外からの通信を受け付けなさそうな名前**です.
しかし EC2 は Public Subnet に所属せずとも Public IP アドレスを関連づけることは可能です.
(もちろんほとんど意味のない行為だと思っています.)

そこで **Public IP アドレスを EC2 に付与すれば,Public Subnet に所属していなくても,外部からの最初の通信は受け付けてしまうのでは?** と疑問に思いました.
(ただし PublicSubnet でなければ, 外部へレスポンスすることは難しいです.)

## 検証してみた

::: note alert
本検証は検証目的の環境であり,ベストプラクティスから逸脱している環境です.
同様の検証を行いたい場合はご自身の責任で行ってください.
:::

### 検証条件/環境

以下の環境を構築し,自身の PC から EC2 に向けて ping を実行し, Subnet に紐づける VPC Flow Logs で ICMP 通信が ACCEPT しているかを確認しました.

- VPC
  - 下の Internet Gateway をアタッチ
- Internet Gateway
- Network ACL
  - 外部からの ICMP を許可
- Subnet

  - VPC Flow Logs を設定
  - 隔離された Subnet になるように下の RouteTable を関連付け

- RouteTable
  - Route が Local のみ
- SecurityGroup

  - 外部からの ICMP を許可

- EC2

  - Public IP アドレスを有効化
  - 上の Subnet に所属させる

### 検証結果

以下の図は Subnet に紐付けた VPC Flow Logs の結果です.

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510833/f171218b-6be0-3bb3-6951-f122df39bf81.png)

このように多くの通信が Subnet まで到達していることがわかります.
また,私の PC からの通信と思われる ICMP(ping)はちゃんと ACCEPT されていました.
もちろん,以下のように reply は私の PC へは返ってきませんでした.

```
$ ping $EC2_PUBLIC_IP

Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
Request timeout for icmp_seq 3
...
```

### 検証のまとめと所感

- Private Subnet や隔離された Subnet であっても,VPC に Internet Gateway がアタッチされているかつ EC2 に Public IP が関連づいていれば最初の通信は到達する.
  - ただし,レスポンスは返せない.
  - 上記のような条件でインシデントを起こすような通信が可能なのかは気になる...
- Public Subnet 以外の Subnet 内の EC2 には Public IP を関連づけない方が良さそう.
  - 逆に意味があるケースはあるのか?
- Private とか隔離されたとか安全そうに感じるものに対しても SecurityGroup などの多層防御の設定はしっかりやり込むのが重要だと思った.
- 少し話が逸れるが,多くの方が通信を仕掛けにきていて,噂には聞いていたが怖いと思った...

## さいごに

Public Subnet ってどうやって探すの?から,いろいろ話が変わってしまった中,ここまで読んでくださりありがとうございました!!
私自身,いろいろと勉強になり楽しかったです.

## おまけ(次回記事の予告?)

今回の検証環境は CDK で構築しましたが,無茶した?環境の構築だったため,いろいろハマりました.
また別の記事に書こうと思います.