こんにちはますのです。
S3バケットへのGet、Putをする際に、機密情報モリモリなS3バケットだけを内部的なプライベート接続に出来ないか?と思うことがありました。
今回は特定のS3バケットのみ内部通信を実現する方法がないか調べて実装しましたので紹介です。
実現したいこと
- 特定のS3バケットへのAWS CLIアクセスをプライベート接続にしたい
- プライベートサブネットに所属するEC2インスタンスのみ接続許可としたい
- パブリックサブネットに所属するEC2インスタンスは接続不可とする
- yumやdnfコマンドでAmazon Linuxリポジトリへのアクセスはパブリックでアクセスしたい
- なるべく費用はかけない
構成図
- パブリックサブネットからの通信はゲートウェイ型VPCエンドポイントのみ接続許可とする
- 名前解決はRoute53リゾルバ経由でプライベートホストゾーンを参照する
- 特定のS3バケットはインターフェース型VPCエンドポイント(AWS PrivateLink)経由のみ許可とする
Route 53 Resolver アウトバウンドエンドポイントは不要
今回はオンプレ環境やAWSリソース以外の名前解決は実施しません。
AWSリソースの名前解決(S3バケットへのアクセス)となるため、アウトバウンドエンドポイントの作成は不要です。
引用:AWS BLACK BELT ONLINE SEMINAR Amazon Route 53 Resolver(p.18)
Route53 Resolverは自動的にVPCに配備されるDNSサーバとなります。
引用:AWS BLACK BELT ONLINE SEMINAR Amazon Route 53 Resolver(p.22)
・プライベート接続したいS3バケットが増える度にプライベートホストゾーンの作成が必要 今回は「1つだけプライベート接続したい」という前提のため、運用面でも問題なかろうと採用に至りました。
プライベート接続するS3バケットが増える場合は「Route 53 Resolver ルールの利用、レコード設計の工夫」などもう少し踏み込む必要があり、余力があれば研究したい所存。
発生する費用:おおよそ 21 USD/月
- 前提
- 1ヶ月=30日=720時間で計算
- インターフェース型エンドポイントで1TB/月の通信を行う
- VPCエンドポイントは1つのAZにだけ作成
試算結果は2023/6月時点の内容となり、参考値となります。
最新の金額は公式サイトから念のためご確認ください。
・Amazon Route 53 料金表
・AWS PrivateLink の料金
計算方法のメモ
- Route53 プライベートホストゾーン:0.5 USD/月
- VPCエンドポイントのエイリアスレコードでクエリ処理をするため追加料金なし(参考)
- VPCエンドポイント(AWS PrivateLink):10.08 USD + 10.24 USD = 20.32 USD
- 各 AZ の VPC エンドポイント 1 つあたりの料金: 0.014USD/h (※マルチAZの場合は2倍)
- 処理データ 1 GB あたりの料金 :0.01 USD
- 各種リソース代金(EC2、S3など)
通信容量が少なければさらに金額は下がりますが、基本はマルチAZ構成にすると思うので「20~30USD」が目安になるかと予想です。
対応方法
- インターフェース型VPCエンドポイント(S3用)を作成する
- Route53にプライベートホストゾーンを作成する
- エンドポイント通信用のセキュリティグループでアクセス制御をする
- (余談)EC2インスタンスにプロキシ設定をしている場合は、プロキシ除外設定を行う
作業1:インターフェース型VPCエンドポイント(S3用)を作成する
VPC > エンドポイント > エンドポイントを作成より、インターフェース型のS3エンドポイントを作成します。
作成方法
- サービスカテゴリ:AWSのサービス
- サービス
- サービス名:com.amazonaws.ap-northeast-1.s3
- タイプ:Interface
- VPC:実装したい環境のVPCを指定
- セキュリティグループ:後ほど作成
- ポリシー:フルアクセス
作成されたインターフェース型のS3エンドポイントから、IPアドレスを確認します。
今回は「172.31.1.152」です。
このIPアドレスを介して「xxxxx-bucket」へアクセスします。
今回はセキュリティグループで制御することにするため、ポリシーはフルアクセスとします。
作業2:Route53にプライベートホストゾーンを作成する
続いてRoute53にプライベートホストゾーンを作成します。
- ドメイン名:<S3バケット名>.s3.<リージョン名>.amazonaws.com
- 各AZのS3エンドポイントは「Amazon Simple Storage Service エンドポイントとクォータ」を確認
- タイプ:プライベートホストゾーン
- リージョン:S3バケットが保存されているリージョンを選択
- VPC:アクセスしたいEC2が所属するVPCを指定
作成したプライベートホストゾーンにAレコードを登録し、「xxxxx-bucket.s3.ap-northeast-1.amazonaws.com」と作業1のVPCエンドポイントを紐づけます。
作成方法
- レコード名:(空欄)xxxxx-bucket.s3.ap-northeast-1.amazonaws.com
- レコードタイプ:A
- エイリアス:有効化
- トラフィックのルーティング先:
- VPCエンドポイントへのエイリアス
- アジアパシフィック(東京)
- 「作業1で作成したVPCエンドポイント」
- az名が入っていないVPCエンドポイントを指定
- az名が入っていないVPCエンドポイントを指定
作業3:セキュリティグループでアクセス制御をする
最後にプライベートサブネットのEC2とインターフェース型エンドポイント間の接続を許可設定します。
そのためにはセキュリティグループで疎通を許可とします。
- エンドポイント用のセキュリティグループを新規作成
- インバウンド / アウトバウド:プライベートサブネットのEC2に設定されているセキュリティグループIDを指定
- インバウンド / アウトバウド:プライベートサブネットのEC2に設定されているセキュリティグループIDを指定
- VPC > エンドポイント > 作成したインターフェース型エンドポイントを選択
- タブ:セキュリティグループ > 「セキュリティグループの管理」を選択
- 作成したセキュリティグループを選択 > セキュリティグループの変更をクリック
- 作成したセキュリティグループを選択 > セキュリティグループの変更をクリック
プライベートサブネットのEC2(172.31.1.5)にセキュリティグループを追加
- プライベートサブネットのEC2を選択 > アクション > セキュリティ > セキュリティグループを変更を選択
- 関連付けられたセキュリティグループ
- VPCエンドポイントで作成したセキュリティグループを追加 > 保存
- VPCエンドポイントで作成したセキュリティグループを追加 > 保存
作成したセキュリティグループをEC2にアタッチすることで、同じセキュリティグループがアタッチされている同士の接続を許可します。※プライベートサブネットのEC2全てに設定したい場合は、下図のようにEC2のセキュリティグループ内に、VPCエンドポイントのセキュリティグループを設定することで実現可能です。
動作確認
プライベートサブネットのEC2(172.31.1.5)で名前解決状況を見てみます。
「bbbbb-bucket」と「xxxxx-bucket」でパブリックIP、プライベートIPで分岐されたことがわかります。
[ec2-user@ip-172-31-1-5 ~]$ nslookup bbbbb-bucket.s3.ap-northeast-1.amazonaws.com
Server: 172.31.0.2
Address: 172.31.0.2#53
Non-authoritative answer:
Name: bbbbb-bucket.s3.ap-northeast-1.amazonaws.com
Address: 52.219.199.14
[ec2-user@ip-172-31-1-5 ~]$
[ec2-user@ip-172-31-1-5 ~]$ nslookup xxxxx-bucket.s3.ap-northeast-1.amazonaws.com
Server: 172.31.0.2
Address: 172.31.0.2#53
Non-authoritative answer:
Name: xxxxx-bucket.s3.ap-northeast-1.amazonaws.com
Address: 172.31.1.152
左:パブリックサブネット → 「xxxxx-bucket」への疎通はタイムアウト
右:プライベートサブネット → 「xxxxx-bucket」へList可能
172.31.0.5、172.31.1.5のいずれも「xxxxx-bucket」へVPCエンドポイントに接続が向かいます。
セキュリティグループで制御することで、プライベートサブネットからの通信を許可として実現しました。また、aws cliでプロキシ設定をしている場合はプロキシ除外の設定はお忘れなくです。
やり方は色々あるので環境に合わせてお試しください。
本記事がどなたかの参考になれば幸いです。
参考資料
- Amazon Linux 1 または Amazon Linux 2 を実行している EC2 インスタンスで、インターネットにアクセスせずに yum を更新したり、パッケージをインストールしたりするにはどうすればよいですか?
- Blackbelt – Amazon Route53 Resolver
- Amazon Route 53 料金表
- エイリアス対象:Choosing between alias and non-alias records
- Amazon Simple Storage Service エンドポイントとクォータ
- [アップデート] S3 インターフェースエンドポイントでプライベート DNS 名を使用できるようになりました