ホーム DoRuby s3cmdでオブジェクトストレージのバケットにIP制限
s3cmdでオブジェクトストレージのバケットにIP制限
 

s3cmdでオブジェクトストレージのバケットにIP制限

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

‘aws-sdk’のようなgemを使用せずに、s3cmdコマンドを使用して s3のオブジェクトストレージバケットにIP制限を行ったのでメモ代わりに

s3cmd設定

※事前にAWSのアカウント作成してください。

$ yum -y --enablerepo epel install s3cmd
$ s3cmd —-configure
Access Key: xxxx
Secret Key: xxxx
(ほかは全てエンターのみでOK)

s3cmd lsで一覧が表示されれば設定完了。
接続できない場合はここら辺の設定を変えてください。

$ vim ~/.s3cfg
host_base = hedgehog
host_bucket = tegetege
signature_v2 = True

バケットにポリシーが設定されていないことを確認。

$ s3cmd info バケット名
   Location:  us-east-1
   Payer:     BucketOwner
   Expiration Rule: none
   policy:    none
   cors:      none
   ACL:       xxxx: FULL_CONTROL

実践

わかりやすいようにバケット名と制限IPのカラムを持つテーブルを用意。

# Table name: hoges
#  id                  :integer          not null, primary key
#  bucket_name :string           not null
#  limit_ips           :text     # json形式で保持
#  created_at          :datetime         not null
#  updated_at          :datetime         not null

class Hoge < ActiveRecord::Base
  def parse_limit_ips
    limit_ips.present? ? JSON.parse(limit_ips) : []
  end

  def set_policy_to_bucket
    create_extract_dir
    open(json_tmp_path, 'w') do |io|
      io.puts(tmp_policy_format)
    end
    # s3cmdのsetpolicyオプションを使用して、対象バケットにポリシーを設定する
    `s3cmd setpolicy #{json_tmp_path} s3://#{bucket_name}`
    delete_extract_dir
  end

  private

  # policyファイルを保持するディレクトリを作成
  def create_extract_dir
    FileUtils.mkdir_p extract_dir
  end

  # ディレクトリ名
  def extract_dir
    File.join Rails.root, :tmp.to_s, :bucket_policy.to_s
  end

 # ファイルパス
  def json_tmp_path
    File.join extract_dir, 'policy.json'
  end

 # ディレクトリごと削除
  def delete_extract_dir
    FileUtils.rm_rf extract_dir
  end

  def tmp_policy_format
    <<-"EOS"
    {
      "Id": "#{SecureRandom.hex}",  # 任意の文字列
      "Statement": [
        {
          "Sid": "#{SecureRandom.hex}", # 任意の文字列
          "Action": ["s3:GetObject"],
          "Effect": “Deny”, # 指定した内容に対しアクセスを拒否する <=> Allow
          "Resource": "arn:aws:s3:::#{bucket_name}/*”,
          "Condition": {
            “NotIpAddress": {  # 以下に含まれるIP以外
              "aws:SourceIp": #{parse_limit_ips}
            }
          },
          "Principal": {
            "AWS": ["*"]
          }
        }
      ]
    }
    EOS
  end
end

Allowだとなぜか効かない…。なのでDenyとNotIpAddressの組み合わせにしました。
(原因は不明。他記事にもAllowは効かなかったという記載がちらほら)

注意点

  • Resourceオプションはダウンロード時とアップロード時によって若干異なる。 上記のコードはダウンロード時のポリシー設定の内容ですが、アップロード時は少し異なります。
"Action": ["s3:PutObject”, “s3:PutObjectAcl”],
.
.
"Resource": [
  “arn:aws:s3:::#{bucket_name}”,
  “arn:aws:s3:::#{bucket_name}/*”
]
.
.

Actionはオブジェクトストレージにファイル(Object)を置くのでPut。
Resourceはバケット自体の記載も必要みたいです。(記載がないと403 or 404)

  • SourceIPに設定できるIPの表記方法はCIDRフォーマット
可
123.123.234.123
123.213.234.21/24

不可
123.231.23.*

反映確認/ポリシー解除

バケットにポリシーが設定されているか
$ s3cmd info バケット名

ポリシーをデフォルトに戻す
$ s3cmd delpolicy s3://<バケット名>

記事を共有

最近人気な記事