この記事はアピリッツの技術ブログ「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://<バケット名>