特定のS3バケットへの通信だけプライベート接続を実現したい

  • 2023年6月18日
  • 2023年7月22日
  • AWS, IT
AWS

こんにちはますのです。
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にだけ作成
     試算結果:20.82 USD/月+各種リソース代金

    試算結果は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
        • タイプ:プライベートホストゾーン
        • リージョン: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エンドポイントを指定

        作業3:セキュリティグループでアクセス制御をする

        最後にプライベートサブネットのEC2とインターフェース型エンドポイント間の接続を許可設定します。
        そのためにはセキュリティグループで疎通を許可とします。

        VPCエンドポイント側のセキュリティグループ設定

        • エンドポイント用のセキュリティグループを新規作成
          • インバウンド / アウトバウド:プライベートサブネットの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でプロキシ設定をしている場合はプロキシ除外の設定はお忘れなくです。
        VPCエンドポイントで制御、S3バケットで制御といった方法も考えることが出来ますが、セキュリティグループが一番簡単です。
        やり方は色々あるので環境に合わせてお試しください。
        なお、他にも良い方法が無いかは引き続き模索出来ればと思います。
        本記事がどなたかの参考になれば幸いです。

        参考資料

        最新情報をチェックしよう!