目次
はじめに
お疲れさまです、寺井です。
最近なんだかAWSのアップデートが頻繁ですよね。
これが嵐(re:Invent)の前触れか……。
そんな中、VPCに関する興味深いアップデートを目にしました!
本日、インターネットアクセス制御を簡素化する強力な新機能をご紹介します。
Amazon VPCブロックパブリックアクセスは、AWS が提供するインターネットパスを介した VPC の受信 (イングレス) および送信 (エグレス) トラフィックを正式にブロックする、シンプルな宣言型制御です。AWS アカウントのリージョンごとに Amazon VPC ブロックパブリックアクセスを有効にすることができ、近々 AWS Organizations もサポートする予定です。
Enhancing VPC Security with Amazon VPC Block Public Access | Networking & Content Delivery
※日本語訳
イイ!!
「この環境のリソースは、ぜっっったいにインターネットに出るなよ…?😠👉️」
みたいな要件があるケースで、有効そうですね。
どうやって設定して、実際どんな挙動になるのか、試してみたいと思います💪
先にまとめ
「VPC - Block Public Access(VPC BPA)」は、インターネット経由の不要なアクセスリスクを排除するための追加防御策を提供するソリューション
「Block Public Access」のポイント
数クリックで、有効化したリージョン内すべてのVPCに対するインターネットアクセス制御が可能
- セキュリティグループやNACLの設定ミスによる意図しないインターネット公開を防止
- VPCやサブネット単位での柔軟な除外設定が可能(一部のみ許可する運用にも対応)
Network ACL(NACL) と Block Public Access(BPA)の違い
最初このアップデートを見たとき、
「NACLでも似たようなことができるのでは?何がちゃうんや?🤔」
となったので、自分なりに違いをまとめました。
項目 | NACL | VPC BPA |
---|---|---|
適用範囲 | サブネット単位 | 有効化したリージョン全体 |
設定内容 | ポート, CIDR単位で細かく設定可能 | インターネットアクセスを一括で制御 |
ユースケース | 内部トラフィックの詳細な管理 | インターネット公開リスクの迅速な排除 |
例外設定 | 個別ルールの追加が必要 | VPC, サブネット単位で例外設定が可能 |
BPAはあくまでも『インターネット↔AWS間の通信における追加の防御策』なので、内部リソース間のトラフィック(ポート・CIDR)制御をする場合には、引き続きNACLの利用が必要 という感じかと思います。
有効化する前の準備
有効化を実施するユーザには [ec2:ModifyVpcBlockPublicAccessOptions] という権限が必要なようです。
[ReadOnlyAccess]ポリシーのみ付与したユーザで設定変更してみるとエラーとなる様子↓
また、有効化すれば対象リージョン内のインターネット通信が遮断されてしまいますので、実際に試す場合は普段使っていないリージョンでやってみることをオススメします。
実際にやってみる
以下の構成を用いて、VPCブロックパブリックアクセスが無効化状態の挙動と、有効化状態の挙動を比べてみたいと思います。
パブリックアクセスがブロックされた後もサーバに接続できるよう、Instance Connect エンドポイントを介して、マネジメントコンソールからSSH接続します。
『ブロックパブリックアクセス有効化前』の動作確認
Ingress(インターネット →AWS)
パブリックサブネットに配置したWebサーバには、Apacheをセットアップしてインターネットからアクセスできる状態にしてあります。
IPアドレスでアクセスすると、問題なくWebページが表示されます。
Egress(AWS →インターネット)
プライベートサブネットに配置したEC2から、インターネットへ出られる状態を確認します。
弊社のホームページに対して curl
コマンドを叩いたところ、問題なくレスポンスが返ってきました。
$ curl "https://denet.ad.jp/" -o /dev/null -w '%{http_code}\n' -s
200
ブロックパブリックアクセスの設定
リソース(VPCやサブネット)毎ではなく、リージョン単位で行う設定なので、VPCのダッシュボード画面から設定できます。
(S3の[アカウントのブロックパブリックアクセス設定]みたいな雰囲気)
[[パブリックアクセスをブロック]をオンにする]にチェック
[インターネットゲートウェイのブロック方向]の設定は[双方向]もしくは[Ingress-only]の選択が可能です。
今回は[双方向]をブロックする設定を入れて、[変更を保存]。
※この設定が有効化された時点でインターネットからのSSH接続もできなくなってしまいますので、ご注意ください。
(事前にSSMやInstance Connect等の接続経路を用意しておく必要があります。)
『ブロックパブリックアクセス有効化後』の動作確認
インターネット側 →パブリックサブネットに配置したEC2 へのインバウンドアクセス
インターネットからアクセスしてもタイムアウトエラーとなりました。
ちゃんとブロックパブリックアクセスが効いているようですね!😌
プライベートサブネットに配置したEC2 →インターネット へのアウトバウンドアクセス
サーバ内からインターネット向けのトラフィックにおいても、想定通りブロックされました。
$ curl "https://denet.ad.jp/" -o /dev/null -w '%{http_code}\n' -s
(反応なし)
# タイムアウト値を設定
$ curl "https://denet.ad.jp/" -o /dev/null -w '%{http_code}\n' --connect-timeout 5
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- 0:00:05 --:--:-- 0
curl: (28) Failed to connect to denet.ad.jp port 443 after 5002 ms: Timeout was reached
000
除外設定の作成
問題なくブロックパブリックアクセスの挙動が確認できたので、次は“除外設定”を試してみます。
同じようにVPCのダッシュボードから設定画面へ遷移します。
(VPC - BPAが有効な状態が分かりやすく示されてますね。)
任意でNameタグが設定できるので、分かりやすい名前をつけておきます。
[インターネットゲートウェイの許可方向]については[双方向]を設定してみます。
許可対象となるサブネットもしくはVPCを選択し、[除外を作成]に進みます。
こちらも3分程度経過したら、状態がアクティブになっていました。
『ブロックパブリックアクセス除外設定後』の動作確認
インターネット側 →パブリックサブネットに配置したEC2 へのインバウンドアクセス
インターネットからのWebアクセスも、内部からインターネット向けのアクセスも問題ありませんでした。
パブリックサブネットに配置したEC2 →インターネット へのアウトバウンドアクセス
アウトバウンド通信も問題なしです。
$ curl "https://denet.ad.jp/" -o /dev/null -w '%{http_code}\n' -s
200
プライベートサブネットに配置したEC2 →インターネット へのアウトバウンドアクセス
プライベート配置のサーバでも、問題なく疎通できました。
$ curl "https://denet.ad.jp/" -o /dev/null -w '%{http_code}\n' -s
200
“除外設定”を行うことで、特定のVPCにおける例外的な許可を設定することができました!👏
(おまけ)除外設定における想定外の事象
現在の除外設定(双方向許可)の状態から、Egress-onlyに変更してみたいと思います。
現在双方向の除外がされている状態ですので、[Egress-only]に変更します。
変更が反映されたことを確認します。
インターネット側 →パブリックサブネットに配置したEC2 へのインバウンドアクセス
想定通り、インターネットからのWebアクセスでタイムアウトエラーとなりました。
パブリックサブネットに配置したEC2 →インターネット へのアウトバウンドアクセス
サーバからのアウトバウンド(Egress)アクセスはできるはず……。
⋮
⋮
なのに出られない!!!!
$ curl --connect-timeout 5 -v -o /dev/null https://denet.ad.jp/
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Host denet.ad.jp:443 was resolved.
* IPv6: (none)
* IPv4: 18.65.159.85, 18.65.159.25, 18.65.159.83, 18.65.159.79
* Trying 18.65.159.85:443...
0 0 0 0 0 0 0 0 --:--:-- 0:00:02 --:--:-- 0* ipv4 connect timeout after 2493ms, move on!
* Trying 18.65.159.25:443...
⋮
* ipv4 connect timeout after 621ms, move on!
* Failed to connect to denet.ad.jp port 443 after 5001 ms: Timeout was reached
0 0 0 0 0 0 0 0 --:--:-- 0:00:05 --:--:-- 0
* Closing connection
curl: (28) Failed to connect to denet.ad.jp port 443 after 5001 ms: Timeout was reached
タイムアウトしちゃうので、完全に外に出られない感じのようですね……
「反映に時間がかかっているのかも?」と思って1日待ってみたりしたんですが、変わらずでした。
色々試行錯誤してみたんですが、原因の特定には至れなかったので一旦諦めます😇
(今後何かわかれば、追記したいと思います……。)
プライベートサブネットに配置したEC2 →インターネット へのアウトバウンドアクセス
こっちはちゃんと出られるようになってました。(ナンデヤ……)
[root@ip-10-0-3-14 ~]# curl "https://denet.ad.jp/" -o /dev/null -w '%{http_code}\n' --connect-timeout 5
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 134k 100 134k 0 0 251k 0 --:--:-- --:--:-- --:--:-- 251k
200
感想・まとめ
使い所としてはそこまで多くはないかもしれないですけど、手軽に保険を追加できる、素晴らしいアップデートだと感じました。
新機能をサクッと試してブログに上げるつもりが、想定外の挙動により思いの外時間がかかりましたけど、楽しかったです!!
最後までお付き合いいただきありがとうございました。
好きなこと:音楽、猫、お酒、ゲーム、効率化
経歴:テレビ業界AD → 通信回線販売代理店 → IT関連職業訓練 → 株式会社ディーネット