はじめに
EasyBlocks SyslogのS3バックアップ送信について、以下のような質問を立て続けにいただきました。

S3にバックアップを送るために、IAMユーザーにはどの権限を付ければよいか?最小権限で構成したい。

バケットポリシーは設定する必要があるか?

装置からS3への通信プロトコルは何か?
いずれも「設定手順を教えてほしい」ではなく、「必要な権限を絞りたい」「通信プロトコルを確認したい」という、一段細かい内容です。
私が以前書いた記事でS3へのバックアップ送信の手順を紹介したときは、IAMポリシーに AmazonS3FullAccess を使いました。動かすまでの説明としてはこれで足りていたのですが、最小権限を前提とした質問が増えています。装置側の設定だけでは終わらず、AWS側の設計に関わる話です。
そこで、必要な権限を1つずつ剥がしながら、どこまで下げられるのかを実機で確かめました。この記事はその結果をまとめたものです。
先に結論
以下、確かめた手順と、そこから分かったことを順に書きます。
背景:なぜ導入前に権限を聞かれるのか
導入を検討する段階になると、最初に決めなければならないのは装置側ではなくAWS側です。
IAMユーザーにどのアクションを許可するのか、バケットへの通信をどう制限するのか。ここが固まらないとAWS側の構成が確定せず、装置の設定にも進めません。
そのため、まだ導入前の段階で権限とプロトコルを聞かれることになります。
装置側でなければ分からないこと
製品マニュアルには、S3のアクセスキーをどこに登録するかが書かれています。装置の操作を説明する文書なので、AWS側でどう権限を切るかは範囲の外です。そこは本来、利用する側のクラウド設計として決める領域でもあります。
ただ、装置が実際にどのアクションを使うのかは、装置側でなければ分かりません。ここが分からないと、絞りようがありません。
私が以前書いた記事でも AmazonS3FullAccess を使っていました。動かすところまでを説明するには十分でしたが、最小権限を求める場合の答えにはなっていません。今回はここを埋めます。
設計の勘所:IAMポリシーとバケットポリシーは別のもの
IAMポリシーとバケットポリシーをまとめて聞かれるのには理由があります。名前も似ていますし、どちらもJSONで書きます。ただ、役割は別です。
| IAMポリシー | バケットポリシー | |
|---|---|---|
| 設定場所 | IAM → ポリシー | S3 → バケット → アクセス許可 |
| 誰に対する設定か | アクセスする側(IAMユーザー) | 受け入れる側(バケット) |
| 装置が要求するもの | s3:PutObject のみ | なし |
| 実際に書く内容 | 上記で固定 | 環境ごとに変わる |
装置がS3に対して要求する権限は、先に書いたとおり1つだけです。一方で、実際にAWS側へ何を書くかは環境によって変わります。同一アカウント構成なのか、HTTPS通信のみに絞るのか。条件次第で書くものが増えます。
「必要な権限は何ですか」に一律の答えが出せないのは、装置側で決まる部分とAWS側の設計で決まる部分が混ざっているからです。装置側は固定、AWS側は可変。この線引きを先に共有しておくと、話が早くなります。
実機で確かめる
方針は「足す」のではなく「剥がす」ことにしました。
AmazonS3FullAccess から始めて権限を削り、失敗するまで下げます。足していく方法だと、たまたま動いた組み合わせで止まってしまい、最小限が分かりません。
検証用のIAMユーザーを用意する
EasyBlocks Syslogに登録するアクセスキーは、専用のIAMユーザーで用意しました。マネジメントコンソールへのログインは無効にしています。
ポリシーは直接アタッチした1本のみで、ユーザーグループには所属させていません。グループ経由で別の権限が効いてしまうと、剥がした結果が測れないためです。

s3:PutObject だけにする
ポリシーの中身はこれだけです。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::<バケット名>/*"
}
]
}
Resource はオブジェクト側だけを指定し、バケット本体のARNは書いていません。

この状態で、EasyBlocks Syslog側の3つの送信機能それぞれにある「設定確認」を押します。バックアップ送信、CSVログ送信、当月テーブル自動バックアップ送信の3つです。

PutObject を外して ListBucket だけにする
次に、剥がしすぎた状態を作ります。Action を s3:ListBucket のみに差し替え、PutObject を外しました。装置側の設定は一切変えていません。

同じ画面、同じ入力値のまま、結果だけが「失敗しました。」に変わります。この症状が出たとき、装置側の設定をいくら見直しても解決しません。
HTTPS通信のみを許可するバケットポリシーを当てる
最後にバケット側です。冒頭の3つめ、通信プロトコルの質問に答えるための検証でもあります。暗号化されていない通信を拒否するバケットポリシーを当ててみます。
aws:SecureTransport が false のとき、つまりHTTPで来たリクエストを拒否する書き方です。

この状態でテスト送信が通れば、HTTPSで送信されている証拠になります。
結果
4つの条件で、3機能それぞれのテスト送信を実施した結果です。
| IAMポリシー | バケットポリシー | バックアップ送信 | CSVログ送信 | 当月テーブル自動 |
|---|---|---|---|---|
| AmazonS3FullAccess | なし | 成功 | 成功 | 成功 |
| s3:PutObject のみ | なし | 成功 | 成功 | 成功 |
| s3:ListBucket のみ | なし | 失敗 | 失敗 | 失敗 |
| s3:PutObject のみ | HTTPS のみ許可 | 成功 | 成功 | 成功 |
読み取れることは3点です。
1つめ。必要なアクションは s3:PutObject のみでした。PutObject だけで成功し、PutObject を外すと失敗したので、他の権限が代わりに効いていたわけでもありません。候補に挙がりやすい GetBucketLocation や ListBucket は必要ありません。
2つめ。3機能で違いはありませんでした。機能ごとに権限を分けて考える必要はありません。
3つめ。HTTPを拒否するバケットの下で送信が通りました。プロトコルはHTTPSです。
S3にはどう置かれるか
権限とあわせてよく聞かれるのが、ファイルの置かれ方です。日付フォルダができるのか、フォルダなしでファイル名に日付が入るのか。

日付フォルダは自動生成されませんでした。バケット直下にフラットに並び、日付はファイル名に入ります。月次のダンプが ilogs_YYYYMM.sql.gz、日次のCSVが syslog-YYYYMMDD.csv.gz です。
送信のタイミングも同じ画面から読み取れます。日次CSVは1日1回でした。装置側で処理開始時刻に0時2分を設定していたので、S3にも0時2分台に置かれています。ファイル名の日付と最終更新日時が1日ずれて連続しているので、送信されるのは前日分です。月をまたぐ日も同じで、7月31日分のCSVが8月1日に送信されています。
プレフィックスを付けたい場合
フォルダを分けて整理したい場合は、装置側の「中間パス」に値を書きます。

末尾のスラッシュは不要でした。ebtest と書けば ebtest/ の配下に置かれます。ebtest/sub のように多階層も指定できました。日付フォルダが自動でできないだけで、プレフィックスは自分で設計できます。
テスト送信で確認できる範囲
ここまで権限の判定にはすべて「設定確認」を使ってきましたが、これで確認できるのは疎通だけです。置かれるのは test_backup.data のようなテスト用のファイルで、9バイトしかありません。実運用で送信されるファイルとは名前もサイズも別物です。設定確認が通っても、実運用のファイルが期待どおりに置かれるとは限りません。

もう1点、運用面での注意です。
当月テーブル自動バックアップ送信は当月分を送るため、同じ名前のファイルが繰り返し上書きされます。世代を残したい場合は、S3側のバージョニングをご検討ください。
まとめ
EasyBlocks Syslogに集めたログは、装置の中だけに置いておくと、万が一装置が故障した際に一緒に失われてしまう可能性があります。ストレージ使用率が一定の水準に達すると古いログは削除されます。長期間の運用という観点ではバックアップ機能はぜひ使っていただきたい機能です。
その一方で、外に出した先をどう守るかが問われてくるようになりました。権限やプロトコルの細部は、装置を作っている側でなければ答えられません。こうした部分については、今後も必要に応じて解説していきます。
