Memo/AmazonWebServices/S3

https://dexlab.net:443/pukiwiki/index.php?Memo/AmazonWebServices/S3
 

S3(Simple Storage Service)

  • Element Descriptions Version, Statement, Sid, Effect, Principal, Action, NotAction, Resource, NotResource, Condition, This section describ

大量のオブジェクトの削除

s3 bucketにobjectが100GBくらいあると消すのも時間がかかる。

  • life cycle ruleを設定する。1日かかるが自動で消してくれる
  • AWS console: ページから離れたり、セッションが切れると止まる。

S3 Storage Lens: S3の利用状況の分析

  • CloudWatchメトリクスでも、オブジェクト数やバケットサイズはあったが、2,3日に1回の頻度だった。

s3オブジェクトの変更・削除を禁止

  • retention periods(保持期間設定)
  • legal holds(法定保留)

S3オブジェクトの所有権を強制する

  • s3 objectはownerしかread/writeできない。アカウントBから、アカウントAのs3 bucketにアップロードすると、アカウントAのuserでread/writeできない状態になる。
  • s3 bucketの所有者にも読み書きを許可するにはobject毎にACL「bucket-owner-full-control」を付与する必要があった。
  • s3 bucketの設定で、objectの所有者をs3 bucketの所有者に強制できるようになった。
    • 既にアップロード済みのobjectは変わらない

正規ユーザーID/正規ID:

  • 正規ユーザーIDの取得方法
    aws s3api list-buckets --query Owner.ID --output text --profile example
  • s3 bucket aclのOwner.IDに正規ユーザIDがあるので、どのアカウントが所有者か確認できる。
    aws s3api get-bucket-acl --bucket terraform-nichigas-stg --profile example
    {
        "Owner": {
            "DisplayName": "example12345",
            "ID": "79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be"
        },
        "Grants": [
            {
                "Grantee": {
                    "DisplayName": "example12345",
                    "ID": "79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be",
                    "Type": "CanonicalUser"
                },
                "Permission": "FULL_CONTROL"
            }
        ]
    }

s3-tree: tree形式で表示

  • S3はkey=valueストアで、フォルダは無い。
  • AWS Consoleではkeyに '/' があると、フォルダっぽく表示しているだけ
  • tree形式で見たい場合は便利?ファイル数が多いと辛そう

S3 Event Notification: S3にアップロードされたらLambdaを起動する等


アクセスログ


セキュリティ


インターネットへ公開


Public Accessの検出


マルチバイトのオブジェクト名

S3のオブジェクト名にマルチバイト文字を使うのは止めた方が良い。
macOSでアップロードすると、Windows/Linuxでは別のファイル名として扱われる。

Unicode正規化方法:

  • NFC
    • Windows, Linux
  • NFD
    • macOS

バージョニング: 履歴管理

  • objectのバージョン一覧。削除されたオブジェクトは、DeleteMarkersが付くようだ。
    • IsLatest: 最新かどうか
      PROFILE=example
      BUCKET=bucket
      
      aws s3api list-object-versions \
       --bucket $BUCKET \
       --profile $PROFILE
      
      {
          "DeleteMarkers": [
              {
                  "Owner": {
                      "DisplayName": "hoge",
                      "ID": "*****"
                  },
                  "IsLatest": true,
                  "VersionId": "****",
                  "Key": "example/example.txt",
                  "LastModified": "2020-03-25T08:48:10.000Z"
              },
  • objectの復元。DeleteMarkersから消す = 復元のようだ。
    PROFILE=example
    BUCKET=bucket
    VERID=****
    KEY=example/example.txt
    
    aws s3api delete-object \
     --bucket $BUCKET \
     --version-id $VERID \
     --key $KEY \
     --profile $PROFILE

オンプレミス環境からのS3アクセス


料金削減

  • multipart-uploadsが残っている件数。巨大なファイルの転送が中断したりした場合、multipartの残骸が残りっぱなしになる。
    AWS_PROFILE=example
    AWS_REGION=ap-northeast-1
    S3_BUCKET=example-bucket
    aws s3api list-multipart-uploads --bucket $S3_BUCKET --profile $AWS_PROFILE --region $AWS_REGION --query 'length(Uploads)'

S3 Access Points: bucketに対して、アクセスポイント名でアクセスする

https://[access_point_name]-[accountID].s3-accesspoint.[region].amazonaws.com

コスト削減

S3自体のコストはEC2と較べたら安いが、容量が貯まるとバカにできないくらいの金額になる。


削除保護

  • S3 bucket policy: delete操作を一切禁止する。tag, policy, versionの削除操作もできない。
    {
        "Version": "2012-10-17",
        "Id": "Policy1574220010459",
        "Statement": [
            {
                "Sid": "DenyDeleteOperation",
                "Effect": "Deny",
                "Principal": "*",
                "Action": "s3:Delete*",
                "Resource": [
                    "arn:aws:s3:::my-bucket",
                    "arn:aws:s3:::my-bucket/*"
                ]
            }
        ]
    }
  • DeleteBucket, DeleteObjectだけを禁止。tag, policy, versionの削除は出来る
    {
        "Version": "2012-10-17",
        "Id": "Policy1574220010459",
        "Statement": [
            {
                "Sid": "DenyDeleteBucket",
                "Effect": "Deny",
                "Principal": "*",
                "Action": [
                    "s3:DeleteBucket"
                ],
                "Resource": [
                    "arn:aws:s3:::my-bucket"
                ]
            },
            {
                "Sid": "DenyDeleteObject",
                "Effect": "Deny",
                "Principal": "*",
                "Action": [
                    "s3:DeleteObject"
                ],
                "Resource": [
                    "arn:aws:s3:::my-bucket/*"
                ]
            }
        ]
    }
  • バージョニングの機能としてロック、MFA deleteがある

バケット間レプリケーション


マルチパートアップロード

  • awscliのcp, syncは自動的にマルチパートアップロードが使われる。
    • Amazon S3 マルチパートアップロード CLI
    • 途中で中断すると、転送中のファイルが残り、課金されるの注意。
      # マルチパートアップロードの確認
      aws s3api list-multipart-uploads --bucket example-bucket --profile example
      
      # 明らかにInitiated古いファイルがあれば削除
      aws s3api abort-multipart-upload \
      --profile example \
      --bucket example-bucket \
      --key <object path> \
      --upload-id <long id>

特定IAM userのみに許可


Bucket Policy


リダイレクト


S3 Batch Operations: 多数のオブジェクトを対象にバッチジョブの実行


サーバレスでブラウザからs3へのファイルアップロード


Presigned URL: 有効期限付URLの発行


2020-09-30日以降、パス形式での S3 APIリクエスト廃止

  • NG:
    http://s3.amazonaws.com/<bucket> # us-east-1のみ
    http://<region>.amazonaws.com/<bucket> 
  • OK:
    http://<bucket>.s3.amazonaws.com
    http://<bucket>.s3-ap-northeast-1.amazonaws.com

S3 Select/Glacier Select: SQLでバケット上のCSV/JSON/Apache Parquet形式を集計

  • s3上にS3 selectの仕様を満たしたcsvをgzip圧縮して置いておく
    s3://<bucket>/<prefix>/id=<id>/year=<year>/month=<month>/day=<day>/<id>.<host>.<timestamp>.csv.gz
  • awscliの場合
    • AllowQuotedRecordDelimiter=True: カラムに改行が含まれている場合、Trueにしないとエラーが出る
    • QuoteFields=ALWAYS: 出力時に必ずダブルクオートで囲む
  • s3-select.sh
    main(){
        local prefix=${1:-}
        local id=${2:-}
        local year=${3:-}
        local month=${4:-}
        local day=${5:-}
        local sql=${6:-"select count(*) from s3object s"}
    
        if [ "$prefix" != "" ]; then
            prefix="${prefix}/"
        fi
    
        local keys=$(
        aws s3 ls \
        "s3://${S3_BUCKET}/${prefix}id=${id}/year=${year}/month=${month}/day=${day}/" \
        --profile $AWS_PROFILE \
        --output text \
        | awk '{print $4;}'
        )
    
        local tmpfile="${BASENAME}.$$.tmp"
        for key in $keys; do
            aws s3api select-object-content \
            --bucket "${S3_BUCKET}" \
            --key "${prefix}id=${id}/year=${year}/month=${month}/day=${day}/${key}" \
            --input-serialization 'CSV={FileHeaderInfo=USE,AllowQuotedRecordDelimiter=True},CompressionType=GZIP' \
            --output-serialization 'CSV={QuoteFields=ALWAYS}' \
            --expression "${sql}" \
            --expression-type SQL \
            "$tmpfile" \
            --profile $AWS_PROFILE \
    
            if [ -f "$tmpfile" ]; then
                cat "$tmpfile"
                rm "$tmpfile"
            fi
        done
    }

署名アルゴリズムv2の廃止と、v4への移行

  • リージョンによっては、v4しか既に受け付けない。Mumbai等
  • 最新のAWS SDKは大丈夫だが、古いSDKや独自実装しているツール系が動かなくなるため更新が必要。

ストレージクラスとライフサイクル

ログを保存するS3 bucketはそのままだと、保存容量が増え続けて、月額費用も上がり続けるためライフサイクルを設定したほうが良い。

  • 例: ログ保存用のバケットのlifecycleの場合
    • AbortIncompleteMultipartUpload を7日に設定
    • 30日経過後、STANDARD_IA へ移動(オブジェクトサイズ128KB、最低利用30日)
    • 90日経過後、GLACIER へ移動(最低利用90日。再取得するには、3〜5時間かかる)
    • 365日経過後、削除

web hosting: 静的サイト

S3単体でweb hostingできるが、https非対応等の制限がある。
CloudFrontやWAFと組みあわせで出来る事が広がる。

  • Amazon S3 での静的ウェブサイトのホスティング - Amazon Simple Storage Service

    Amazon S3 ウェブサイトエンドポイントは HTTPS をサポートしていません。Amazon S3 バケットで HTTPS を使用する方法については、「CloudFront を使用して Amazon S3 バケットに HTTPS リクエストを提供するには、どうすればよいですか?」と「CloudFront と Amazon S3 オリジンとの通信で HTTPS を必須にする」を参照してください。

  • S3単体
    • http対応
      http://<bucket name>.s3-website-<region name>.amazonaws.com/<file path>
    • AWSのSSL証明書を使ったhttpsアクセス。
      https://<bucket name>.s3-website-<region name>.amazonaws.com/<file path>
      • AWSのSSL証明書は「*.s3-website-<region name>.amazonaws.com」なので、S3 Bucket名に".", "_"等のドメイン名に使えない文字が入るとアクセスできない。
      • ウェブサイトエンドポイントはhttps非対応
    • カスタムドメイン
      • ドメインと同名のS3 Bucketが必要。www.example.com, example.com の場合は2つ。
    • IP制限
      • S3 bucket policyで設定
  • S3 + CloudFront
    • https対応
    • カスタムドメイン
  • S3 + CloudFront + WAF
    • https対応
    • カスタムドメイン
    • IP制限
      • WAFで設定
  1. Route53で名前解決
  2. CloudFront
    • WAFでIP制限
      • Allow: 許可IPリスト
      • Deny: all
    • ACMにSSL証明書をインポート
      • SSL: *.example.com
    • Aliasを設定
      • my-s3-bucket.example.com
  3. S3で静的ファイル配信
    • s3://my-s3-bucket/
    • ACLはPrivateで、web hostingは使用しない。

S3対応クライアント

  • WinSCP:Download オープンソース。GUI。v5.13以降でS3に対応。言語ファイル追加で日本語UI対応
    • 接続時にバケット名の指定ができないため、"s3:ListAllMyBuckets?"権限が必要。

Windowsでエクスプローラから参照


linuxファイルシステムとしてマウント


S3でyumリポジトリ構築

  • 必要な要素
    • [S3 WebHosting] rpmファイルを公開
    • createrepoコマンドでrpm metaデータ生成。EC2で行う?
    • [オプション] basic認証等も付けられる

s3cmdで"ERROR: S3 error: The provided security credentials are not valid."

  • Cloudian使用時に発生する S3互換のストレージサービス
    s3cmd ls s3://bucket-name
    ERROR: S3 error: The provided security credentials are not valid.
  • 解決
    echo "signature_v2 = True" >> ~/.s3cfg

s3cmdで"WARNING: Redirected to..."

  • エラー
    s3cmd ls s3://com.example.www/
    WARNING: Redirected to: com.example.www.s3-us-west-2.amazonaws.com
  • 修正
    vim ~/.s3cfg
    ----
    bucket_location = us-west-2
    host_base = s3-us-west-2.amazonaws.com
    host_bucket = %(bucket)s.s3-us-west-2.amazonaws.com
    simpledb_host = sdb.us-west-2.amazonaws.com
    ----

S3のSSL証明書エラーの回避

  • S3のSSL証明書は'*.s3.amazonaws.com'のため、バケット名に「.」が含まれると証明書エラーになる
    cURL error: SSL: certificate subject name '*.s3.amazonaws.com' does not match target host name 'com.example.www.s3.amazonaws.com'
  • 回避方法
    • S3バケット名に"."を使わない。バケットの制約と制限 - Amazon Simple Storage Service
    • SSLを使わず、httpで通信すれば解消する
      $s3->use_ssl = false; // SSLを使わない
    • メソッドによっては、cURLのオプションでSSL証明書のチェックをしない
      $ret = $s3->list_buckets ( array(
          "curlopts" => array(CURLOPT_SSL_VERIFYPEER => false),
      ) );

バケット毎にオブジェクトの有効期限(自動削除)

  • バケット毎に100個までルールを追加できる
  • prefix: 削除対象のバケット名を除いたフルパスの前方一致を指定。ワイルドカードや正規表現は指定できない。指定しなければ全オブジェクトが対象
    • 同じパスを含むprefixは指定できない。例:「logs/」「logs/2013」
  • 一定期間をすぎたオブジェクトをGlacierに移動もできる
  • 例:com.example.wwwバケットの「group01/logs」以下を対象に、作成日から7日経過したオブジェクトを消したい
    \---com.example.www
        \---group01
            \---logs
                \---2013
                    \---01
                        +---01
                        |   +---server01
                        |   |       message.log
                        |   |       
                        |   \---server02
                        |           message.log
                        |           
                        \---02
                            +---server01
                            |       message.log
                            |       
                            \---server02
                                    message.log
  1. 対象バケットを選択して右クリック > Properties > Lifecycle
  2. Add rule
    • Enabled: チェック
    • Name: delete logs(適当)
    • Prefix: group01/logs/
    • Time Period Format: Days from the creation date (オブジェクトの生成日) または Effective from date(任意の日)
    • Expiration: 7 days (7日すぎたら削除)
  3. Save
  4. 確認
    • Manegement Console: message.log の Propertiesに「Expiry Date: Thu Dec 06 09:00:00 GMT+900 2012」
    • ObjectをGET/HEADしたときのHTTP Headers に「x-amz-expiration: expiry-date="Thu, 06 Dec 2012 00:00:00 GMT", rule-id="delete logs"」

別アカウントに許可する

  • 以前はS3FoxでEdit ACL > Share > With UserID でAWSアカウントID(数字の羅列)を入力すれば良かったがエラー「Undefined」になる(2012-11-14現在)
    ただし、一度ManegementConsoleで設定すればRead/Write個別に設定できる
  • AWSアカウント user1@example.com の com.example.user1 バケットを AWSアカウント user2@example.com(AWSアカウント番号:123456789012) と共有する例
  1. user1でAWS Manegement Consoleにログイン
  2. S3 > com.example.user1 > properties
  3. Permissions Tab > Edit bucket policy
    {
      "Id": "Policy0000000000000",
      "Statement": [
        {
          "Sid": "Stmt1000000000000",
          "Effect": "Allow",
          "Principal": {
            "AWS": [
              "arn:aws:iam::123456789012:user/iam-user-name"
            ]
          },
          "Action": [
            "s3:GetObject",
            "s3:ListBucket"
          ],
          "Resource": [
            "arn:aws:s3:::com.com.example.user1",
            "arn:aws:s3:::com.com.example.user1/*"
          ]
        }
      ]
    }
  4. Save
  • 以下ではListBucketは成功するが、GetObjectが成功せず
  1. Add more permissions に「user2@example.com」を入力
  2. Grantee: user2@example.com / List,Upload/Delete 等にチェック
  3. Save

s3://bucket/iam-user/ 以下だけを許可する


特定バケットのみ許可

  • さらに "hoge/*" 以下だけ許可。以下の書き方では"hoge"にはマッチしない。StringLikeは"s3:ListBucket"他特定メソッドにだけ使える
    {
      "Statement": [
        {
          "Sid": "Stmt0000000000001",
          "Action": [
            "s3:ListBucket"
          ],
          "Effect": "Allow",
          "Resource": [
            "arn:aws:s3:::com.example.test",
            "arn:aws:s3:::com.example.test/*"
          ],
          "Condition": {
            "StringLike": {
              "s3:prefix": [ "hoge/*"]
            }
          }
        },
        {
          "Sid": "Stmt0000000000002",
          "Action": [
            "s3:GetObject"
          ],
          "Effect": "Allow",
          "Resource": [
            "arn:aws:s3:::com.example.test/hoge/*"
          ]
        },
      ]
    }

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2020-12-01 (火) 14:02:53 (9m)