Amazon S3 バケットへのインターネット経由でのセキュアなリモートアクセス設定(ポリシーによるリモートアクセス設定)について解説します。
基本的に S3 バケットへのアクセスはインターネット経由(パブリックサブネットからのアクセス)になります。
しかし S3 の権限周りでのアクセス権での設定ミスで情報が漏えいする事故が多いため、極力セキュアな環境を保ったままアクセスできるように設計し設定する必要があります。
【AWS】【S3】作成手順 & アップロード手順 & アクセス権限設定手順
ネットワーク構成図
以下のネットワーク構成図で設定します。
クライアントが、インターネット経由で Amazon S3 のバケットにアクセスをする想定です。
要件
要件をまとめると以下のようになります。
- インターネット経由で S3 バケットにアクセスしたい
- 各コンピュータは AWS CLI より S3 にアクセスする
- 特定の IAM ユーザーのみアクセスさせたい
- 特定のグローバル IP からのみアクセスさせたい
インターネット経由でアクセスしてくる場合のセキュアな設定
基本的に S3 バケットにはインターネット経由でアクセスします。
(VPC エンドポイントの設定をしなければ、EC2 インスタンスからもインターネット経由でアクセスすることになります。)
しかしインターネット経由でのアクセスとなると全世界からアクセスできることになるため、セキュアな環境を構築するためには「ホワイトリスト形式」でアクセス権を設定する必要があります。
アクセスキーとグローバル IP で絞りセキュアな環境を構築する
Amazon S3 環境で、ホワイトリスト形式(特定のホスト、特定のアカウントのみアクセスを許可する)でアクセス権を設定する場合、以下の 2点を考慮して設定をする必要があります。
- アクセスキーとシークレットアクセスキーで絞る【認証】
- 特定のグローバル IP のみ許可して絞る
この 2つ合わせることでセキュアな環境が構築できます。
どちらか一方で拒否になるともう一方で許可となったとしてもアクセスはできなくなります。
作業概要及び設計
今回の設定をまとめると以下の作業となります。
- 自宅のインターネット環境のグローバル IP アドレスを調べる
- S3 バケットアクセス用のポリシーを作成する
- S3 バケットアクセス用の IAM ユーザーを作成する(アクセスキーとシークレットアクセスキーを取得する)
- S3 バケットを作成する
- バケットポリシーを設定する
- アクセスするコンピュータに AWS CLI の設定をする
- 動作確認をする
設計
設計というほどでもないですが、最初に名前を決めておきます。
- S3 バケット名 : s3-access-xxxxxx
- IAM ユーザー名 : S3AccessTestUser
- ポリシー名 : S3-Access-Test-Policy
自宅のインターネット環境のグローバル IP アドレスを調べる
自宅のインターネット環境のグローバル IP アドレスを調べます。
パソコンから「確認くん」のサイトにアクセスします。
■確認くん
https://www.ugtop.com/spill.shtml
下図の「あなたの IP アドレス(IPv4)」の数字が自分のグローバル IP アドレスになります。
S3 バケットアクセス用のポリシーを作成する
S3 バケットアクセス用のポリシーを作成します。
AWS 管理画面より「サービス」–「セキュリティ、ID、およびコンプライアンス」–「IAM」をクリックします。
IAM ダッシュボードに移動したら左側ペインより「ポリシー」をクリックします。
「ポリシーの作成」ボタンをクリックします。
「ポリシーの作成」画面に移動したら「ビジュアルエディタ」タブをクリックし、「サービス」に「S3」を選択します。
下図のように「アクション」で細かく「アクセスレベル」を選択できるので、必要なアクションにチェックを入れて「ポリシーの確認」ボタンをクリックします。
「ポリシーの作成」画面で「名前」を設定し「ポリシーの作成」ボタンをクリックします。
下図のようにポリシーが作成されることを確認します。
S3 バケットアクセス用の IAM ユーザーを作成する(アクセスキーとシークレットアクセスキーを取得する)
次に S3 バケットアクセス用の「IAM ユーザー」を作成し、「アクセスキー」と「シークレットアクセスキー」を取得します。
AWS 管理画面より「サービス」–「セキュリティ、ID、およびコンプライアンス」–「IAM」をクリックします。
IAM ダッシュボードに移動したら、左側ペインより「ユーザー」をクリックします。
「ユーザーを追加」ボタンをクリックします。
「ユーザーを追加」画面で、「ユーザー名」を設定し、「アクセスの種類」を「プログラムによるアクセス」にチェックを入れ、「次のステップ:アクセス権限」ボタンをクリックします。
「アクセス許可の設定」で「既存のポリシーを直接アタッチ」をクリックして「次のステップ:タグ」ボタンをクリックします。
「ポリシーのフィルタ」に咲くほど作成したポリシー(例では S3-Access-Test-Policy)を入力して該当のポリシーにチェックを入れ「次のステップ:タグ」ボタンをクリックします。
必要な場合はタグを設定して「次のステップ:確認」ボタンをクリックします。
設定内容を確認し「ユーザーの作成」ボタンをクリックします。
ユーザーが作成されたら、下図のように「.csv のダウンロード」ボタンをクリックして「アクセスキーID」と「シークレットアクセスキー」を取得します。
ダウンロードされる「.csv」ファイルは下図のようになっています。
S3 バケットの作成
次に「S3 バケット」を作成します。
AWS 管理コンソールより「サービス」–「ストレージ」–「S3」をクリックします。
「Amazon S3」ダッシュボードに移動したら「バケットを作成する」ボタンをクリックします。
「バケットの作成」画面に移動したら以下のように設定を入れて「次へ」ボタンをクリックします。
- バケット名 : s3-access-xxxxx(任意のバケット名で作成します)
- リージョン : アジアパシフィック(東京)
■バケット名の命名規則
S3 バケット名の欄に「DNS 準拠のバケット名を入力する」とあります。
S3 バケットの命名規則は以下で解説します。
S3バケットの命名規則
Amazon S3 バケットの命名規則は以下のようにまとめられています。
■バケットの制約と制限
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/BucketRestrictions.html
バケット名は「DNS 命名規則に沿って命名する必要があります。」とありますが、「DNS 命名規則」とはなんでしょうか。
■ DNS 命名規則とは
DNS 命名規則を簡単にまとめると以下のようになります。
- 長さが 25 文字を超えない
- 文字で始まり、英数字で終わる。英数字とハイフン以外は使用しない
- 末尾にハイフンと数字を付けない
次に「オプションの設定」画面で「サーバーアクセスのログ記録」で「バケットへのアクセスリクエストを記録します。」にチェックを入れて以下のように設定します。
- ターゲットバケット : あらかじめ S3 のアクセスログを記録するための S3 バケットを作成しておいて指定します。
- ターゲットプレフィックス : 適当に分かりやすいプレフィックスを設定します。(下図では例として logs と設定しています)
「デフォルト暗号化」は必要な場合は「S3 に保存されているオブジェクトを自動的に暗号化します。」にチェックを入れて「AES-256」か「AWS-KMS」の暗号化方式を選択します。
設定をしたら「次へ」ボタンをクリックします。
「アクセス許可の設定」画面で「パブリックアクセスをすべてブロック」にチェックを入れて下にスクロールします。
「システムのアクセス許可の管理」の設定で「Amazon S3 ログ配信グループにこのバケットへの書き込みアクセス権限を付与しない」を選択し「次へ」ボタンをクリックします。
最後に設定内容を確認し「バケットを作成」ボタンをクリックします。
■作成後の S3 バケットの状態
作成後の S3 バケットは、「アクセス」が「バケットとオブジェクトは非公開」の状態になっています。
バケットポリシーの作成
S3 バケットへのアクセス権限を詳細に設定するため「バケットポリシー」を作成します。
アクセス権限を設定する方法
アクセス権限を設定する方法ですが、以下の方法がありますが、今回の要件を実現するには「バケットポリシー」の設定が必要になります。
- バケット ACL
- オブジェクト ACL
- バケットポリシー
今回設定する対象の S3 バケットをクリックします。
下図のように「アクセス権限」タブをクリックします。
「バケットポリシー」をクリックします。
「AWS Policy Generator」画面が開くので、下図のように設定します。
※【追記】後述しますが、Effect が Allow(許可)では要件通りに動かなかった(想定していた拒否が出来なかった)ので、Effect を Deny(拒否)で設定しなおしました。
- Select Type of Policy : S3 Bucket Policy を選択します。
- Principal :arn:aws:iam::xxxxxxxxxxxxx:user/S3AccessTestUser(ユーザーの ARN)を入力します。
- AWS Service : Amazon S3 を選択します。
- Amazon Resource Name(ARN) : arn:aws:s3:::s3-access-xxxxxxxxx(S3 バケットの ARN)を入力します。
設定が完了したら「Add Condition(Options)」をクリックします。
Principal エレメントは、リソースへのアクセスを許可または拒否するユーザー、アカウント、サービス、または他のエンティティを指定します。
■ユーザーの ARN の確認方法
ユーザーの ARN の確認方法です。
下図のようにユーザーの詳細画面に移動すると確認ができます。
■S3 バケットの ARN の確認方法
S3 バケットの ARN の確認方法ですが、S3 バケットを選択すると、下図のように「バケット ARN をコピーする」ボタンをクリックすると「バケット ARN」をコピーできます。
「Add Condition」ボタンをクリックすると下記の画面が表示されるので下図のように設定します。
- Condition ← IpAddress を選択します。
- Key ← aws:SourceIp を選択します。
- Value ← 確認くんで確認したグローバル IP アドレスを入力します。
設定したら「Add Condition」ボタンをクリックします。
設定が完了したら「Add Statement」ボタンをクリックします。
ポリシー内容を確認し「Generate Policy」ボタンをクリックします。
「Policy JSON Document」画面上にポリシーが作成されるので、コピーをして「Close」ボタンをクリックします。
「バケットポリシーエディター」に先ほどのポリシーを貼り付けます。
アクセスするコンピュータに AWS CLI の設定をする
設定が完了したらインターネット経由で S3 バケットにアクセスするコンピュータに AWS CLI の設定をします。
具体的には「AWS CLI」をインストールし「Configure」コマンドで「アクセスキー」と「シークレットアクセスキー」の設定をします。
AWS CLI インストール方法
AWS CLI のインストール方法は以下の記事を参考にしてください。
【AWS】【Windows&Linux】「EC2 インスタンス」または「パソコン」に AWS CLI(aws コマンド)及び jq コマンドをインストールする手順
■動作確認
以下のように「aws –version」コマンドが実行出来てエラーが出力しなければ設定は問題ありません。
PS C:\Program Files\PowerShell\6.0.3> aws –version |
AWS CLI を実行するための AWS 認証情報を設定する
「aws configure」コマンドを実行して AWS CLI を実行するための AWS 認証情報を設定します。
PS C:\Program Files\PowerShell\6.0.3> aws configure |
動作確認
aws s3 コマンドで動作確認をします。
■バケットの中身を確認する
PS C:\Program Files\PowerShell\6.0.3> aws s3 ls s3://s3-access-xxxxxxxxx |
■ローカルのファイルをバケットにアップロードする
ファイルを確認します。
PS C:\test> ls |
「text.txt」ファイルを S3 バケットにアップロードします。
PS C:\test> aws s3 cp test.txt s3://s3-access-xxxxxxxxx/ |
「text.txt」ファイルがアップロードされていることを確認します。
PS C:\test> aws s3 ls s3://s3-access-xxxxxxxxx |
アクセスはできました。
次にポリシーの IP アドレスを変更し、拒否されるか確認します。
(失敗)ポリシーを変更して他の IP アドレスからはアクセスできないことを確認する
今回はホワイトリスト方式で、特定のグローバル IP アドレスで絞りましたが、ポリシーを変更して他の IP アドレスからはアクセスできないことを確認したところ・・・
■Allow で構成したバケットポリシー【失敗例】
{ |
IP アドレスが異なるにもかかわらず、問題なくアクセスできてしまいました。
PS C:\Program Files\PowerShell\6.0.3> aws s3 ls s3://s3-access-xxxxxxxxx |
Deny で構成する(Allow ではなく)【成功例】
設定方法が間違っていたのかと調べていたところ、「Deny(拒否)」を中心に構成しているケースがあったので試しました。
Allow の設定で「許可する IP アドレス」を指定しても、それ以外の IP は拒否されない(ブロックされない)ということだそうです。
確かにいろいろ設定を変えて動作検証をしてみたところ、動作的にはそうでしたが、AWS の公式サイトを調べた限りではハッキリと Allow の設定で「許可する IP アドレス」を指定しても、それ以外の IP は拒否されるわけではないとの記述はありませんでした。(調査が足りないだけかもしれませんが)
Deny で再構成するため、再度「ポリシージェネレーター」を起動してポリシーを作成します。
「AWS Policy Generator」画面が開くので、下図のように設定します。
※こちらは成功例です。
- Select Type of Policy : S3 Bucket Policy を選択します。
- Effect : Deny を選択します。
- Principal : arn:aws:iam::xxxxxxxxxxxxx:user/S3AccessTestUser(ユーザーの ARN)を入力します。
- AWS Service : Amazon S3 を選択します。
- Actions : All Actions にチェックを入れます。
- Amazon Resource Name(ARN) : arn:aws:s3:::s3-access-xxxxxxxxx(S3 バケットの ARN)を入力します。
各種設定をしたら「Add Conditions(Optional)」をクリックします。
「Add Condition」ボタンをクリックすると下記の画面が表示されるので下図のように設定します。
- Condition ← NotIpAddress を選択します。
- Key ← aws:SourceIp を選択します。
- Value ← 確認くんで確認したグローバル IP アドレスを入力します。
設定したら「Add Condition」ボタンをクリックします。
下図のように先ほど設定した「Condition」が追加されていることを確認し「Add Statement」ボタンをクリックします。
最後にポリシー内容を確認し「Generate Policy」ボタンをクリックします。
■バケットポリシー
{ |
■バケットポリシーの IP アドレスを正しく設定した場合
問題なく S3 にアクセスして情報を取得できました。
PS C:\Program Files\PowerShell\6.0.3> aws s3 ls s3://s3-access-xxxxxxxxx |
■バケットポリシーの IP アドレスをわざと間違えて設定した場合
S3 へアクセスしたところ「An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied」のエラーメッセージが出力されアクセスできませんでした。【成功】
PS C:\Program Files\PowerShell\6.0.3> aws s3 ls s3://s3-access-xxxxxxxxx |
他に引っ掛かったポイント
他にポリシー作成で引っ掛かったポイントです。
- アクセスポリシーを「Deny」中心に設定する場合、「Principal」ではなく「NotPrincipal」にする必要があるかと勘違いした
結論
今回の件でポリシー周りをいろいろ調べてみましたが、デフォルトの状態ではこうなっている、この場合は「Allow」での設定で問題がある?ない?など、まだいまいち何が正しいのか分からない状態です。
【補足】AWS CLI での S3 へのアクセスは HTTPS プロトコルでの通信となる(暗号化される)
AWS CLI での S3 へのアクセスは HTTPS プロトコルでの通信となります。
つまり通信内容は暗号化されています。
参考サイト
以下、参考にさせていただきました。
ありがとうございます。
AWS S3でホワイトリスト形式でIP制限する(特定IPのみアクセス許可)
コメント