🗑️

先づS3より始めよ - あるいはS3バケット57個削除した話 -

2022/03/08に公開

はじめに

これはAWS入門者の方に向けたセキュリティ啓発の記事、に見せかけたポエムです。

最初にこのタイトルについてですが、先づ隗より始めよという故事成語になぞらえています。
「手近なところから始めよう」と言った意味ですが、もう少し奥行きのある表現でこちらのページの解説がイラスト入りで分かりやすく素敵でした。(漢文は苦手でした...)

それはさておき、このポエムの主題は 「中長期的なAWSアカウントの運用においてS3のセキュリティ設定を最初に考えたい」 という話です。
なぜS3なのか? どうやるのが良いか? に加え、後半は実際に過去のプロジェクトでS3バケットを整理した際の辛かった思い出作業内容を紹介できればと思います。

背景

なぜS3から始めるのか? ですが単純にS3の公開設定ミスなどによるデータ漏洩の記事を多く見かけるからです。
大規模なものだと、以下のようなデータリークが過去にありました。

そもそもデータ漏洩はデータが保存されている場所から起きるため、AWSサービスの中でS3が話題の中心になることはある意味当然ですね。
一般的なクラウド環境のセキュリティ検討項目としてはより重要な項目[1]もあるかもしれませんが、データ流出を足元から考えるという意味では、S3バケットの設定を最初に見直すことをお薦めしたいです。加えて、上記の記事の中でも触れられていますが、この点検・修正には時間も人的コストもかかります。(このあたりの話は後半に)

S3の設定項目

それでは、S3の設定と言うとどんなものがあるのか? について。
S3バケットに関連したセキュリティ機能やAWSサービスとしては、現在以下のようなものがあります。

etc.

もちろんこれだけではないです。
御存知の通りAWSの黎明期からあるサービスですが、近年のアップデートも凄まじく、非常に充実している印象があります。

何を基準にすべきか

このような機能や設定項目が多い中で、具体的にどういった方針でやれば良いか? ですが、方針となる一つの指標としてSecurity HubというAWSのセキュリティサービスに、AWS基礎セキュリティのベストプラクティスというものがあります。
Security Hubはセキュリティ運用のためのツールで、他のAWSサービスとのインテグレーションも可能です。
中心となる機能は、アカウント内のセキュリティ設定を横断的に検出し重要度ごとに一元的に可視化して、どう修正すれば良いのか(公式ドキュメントのリンク)まで示唆してくれる機能です。

この機能のAWS基礎セキュリティのベストプラクティスを見ると、S3に関しては具体的に以下の8個の項目[2](コントロールと呼ばれます)があります。

  • [S3.1] 重要度:Medium S3 Block Public Access setting should be enabled
  • [S3.2] 重要度:Critical S3 buckets should prohibit public read access
  • [S3.3] 重要度:Critical S3 buckets should prohibit public write access
  • [S3.4] 重要度:Medium S3 buckets should have server-side encryption enabled
  • [S3.5] 重要度:Medium S3 buckets should require requests to use Secure Socket Layer
  • [S3.6] 重要度:High Amazon S3 permissions granted to other AWS accounts in bucket policies should be restricted
  • [S3.8] 重要度:High S3 Block Public Access setting should be enabled at the bucket level
  • [S3.9] 重要度:Medium S3 bucket server access logging should be enabled

ここで考えたいことは 「将来的に、AWS基礎セキュリティのベストプラクティスを運用チームとして採用する可能性があるか?」 という点です。
すぐに有効化して使い始める必要はないのですが、このSecurity Hubの各項目に則っていない運用で月日が経過してしまい、後付でこれらの推奨設定に寄せようとすると工数が嵩みます。(平たく言うと、ひたすら確認作業になります)

システムの特性によって検討項目それぞれの温度感は変わってくるかもしれません。また、オリジナルの優先度や指標を用いる方法もありますが、このような標準的な指標から取捨選択して検討するメリットも多いと想像できます。
定量的に数値で説明できるため、マネージメントチームや情報システム室、他部署に対してもシステムの状態を共有しやすく、内部監査を担当されている方などにも好まれるはずです。

そのため、現時点でSecurity Hubを採用していなかったとしても

1. バケットの新規作時には、Medium以上のコントロールを可能な限り満たした設定にする
2. 既に作成済みのバケットは、これらのコントロールに対応出来るよう順次修正する

といった方針をとっておくのが良いと思います。

Security Hubの導入について

少し話はそれますが、Security Hubの導入についての補足です。

「とりあえず有効化すればいいじゃん!」という向きもあり、多くの場合でその通りなのですが、一方で費用もかかるため判断はケースバイケースかもしれません。(個人的な考えです)
既に稼働中のシステムの思いがけない落とし穴を探す意味では、一度有効化することはおそらく重要です。しかしながらSecurity Hubを有効にしただけではセキュリティ強度は1ミリも上がらないため、有効化したことで安心してしまい、改善作業や振り返りなどを実施しないといった状況は避けたいです。
そのため、他のサービスを導入する際と同じようにメリット・デメリットを検討し、継続的な改善作業ができるだけの時間的なリソースの確保をすることも重要だと思います。
もちろん基本的なセキュリティ設定については、既に実施されている前提ですね。

Security Hubは、見方を変えると(AWSのセキュリティに詳しくないチームであっても)意思決定をベストプラクティスに委ね、次のアクションを決定づけるための強力なツールという側面もあり、くどいようですが準備をして適切に導入することがお薦めです。

とあるWebサービスでS3バケットを整理した話

ここからは私が以前に携わった、とあるWebサービスのプロジェクトの話です。
上に書いたような設定をしておけたらよかった! という思いに至ったキッカケとなる出来事でした。(当時はまだ実装されて無い機能も多く、現実的にそれは不可能だったわけですが)

そのシステムは、ユーザー数が少ないながらもAWS上で10年近くの長きに渡り稼働しているものでした。
このアカウントで使用しているS3バケットは非常に多く、サービスのリリース当初と比べると運用担当者の数も減り、一方で当時の「すぐにトライせよ」といった社内カルチャーも相まって、挑戦した結果不要となったバケットもいくつかある状態でした。
(すぐにトライできる環境は素晴らしいのですが、後片付けも忘れずに行いたいものですね...!)

そしてある日、チームメンバーの1人がS3バケットを作成しようとした際に、ついにエラーが発生します。
上限である100バケット[3]を超えたため、新規のS3バケットが作成できなくなりました(!)

というわけで、これをきっかけにS3バケット100個の棚卸しを開始しました。
そして3ヶ月以上かけて不要なS3バケットの削除と、全てのS3バケットの設定を確認しました。

具体的にどうしたか

1. 棚卸し・削除

当然まず考えたことは、S3バケットの数を減らすことでした。
セキュリティ設定以前の話ですが、アカウント内で使用していないバケットを紐解くには、そのアカウント内で動いているほぼ全てのワークロード/リソースの関係性を洗い出す必要があり、仕様書や構成図のアップデートが追いついていない環境だったために苦労しました。

関係者へのヒアリングや、アクセスログ・put/getメトリクスの確認なども行い、それでも削除ボタンを押すのに勇気が必要なときは、アーカイブ用のバケットを作成し、データを一度退避させました。
最近になってEBSのごみ箱機能がリリースされましたが、作業者の心理的な負荷にならない方法でバケット数を減らせるなら、原始的な方法であってもありじゃないかなと思います。

2. バケットの集約/共有利用

可能であればS3バケットは集約したいです。どの単位でバケットをまとめるかという点は悩ましく、チーム内でも議論の余地がありそうですが、特に公開設定のバケットなどは限定しておきたいと考え、整理しました。
また、Serverless Frameworkで使用しているデプロイメントバケットの集約も行いました。
作業は私自身が実施したわけではないのですが、これは非常に効率の良い方法だと思われます。

3. 別アカウントへの移行

システムのワークロードに関係のないバケットは、別のアカウントのS3バケットへ移行するか、そもそもアカウントを分ける等検討したいです。
珍しいケースかもしれませんが、公開リポジトリとしてパブリックに使用されているバケットがあり、他部署の協力も仰いで、別アカウントのバケットへ移行しました。
組織が大きいと調整に時間がかかりそうなタスクですが、関係者のAWSに対する理解度が高く(自分より詳しい)、すぐに適切なアカウントで運用を引き継いでいただくことができました。

S3バケットのバケット名は世界中でユニークですが、削除した後に同名のものを作成することも可能なため、影響範囲やリスクを考慮の上で移行を検討しても良さそうです。
逆にもしそのアカウント内でホストしなければならない理由があるなら、一度確認すべきと思います。

4. 設定の見直し

このような作業の結果、最終的に57個のS3バケットを削除することができました。

必要なバケットが明確になり、過去に作られた各バケットの経緯や目的・関係者も判明し、ようやくここからが本題です。公開設定や暗号化設定など、残りの43個について一つひとつ確認しました。
幸い特に問題は見つからず、そのためより強固なセキュリティ設定を適用する作業を実施しました。

マネージメントコンソールで設定を適用するだけであればポチポチとすぐにできそうですが、既に複数のIaCを導入している場合には、それぞれのツールごとに設定を適用していく必要があります。
ここでは一例として、パブリックアクセスブロックのCloudFormation、Terraformのそれぞれの設定を紹介します。

CloudFormation

s3.yaml
Resources:
  HogeBucket:
    Type: AWS::S3::Bucket
    Properties:
      PublicAccessBlockConfiguration:
        BlockPublicAcls: True
        BlockPublicPolicy: True
        IgnorePublicAcls: True
        RestrictPublicBuckets: True

Terraform

s3.tf
resource "aws_s3_bucket_public_access_block" "hoge" {
  bucket                  = aws_s3_bucket.hoge.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

このパブリックアクセスブロック設定は何をおいても実施したいところですが、アクセス制御の仕組み上この機能はやや複雑なため、本番環境の設定時にはご注意ください。

おわりに

この作業、言うは易しで実際にはスプレッドシートとにらめっこな泥臭い作業になります。
当然やりたがるエンジニアは少ないと思います。そもそも何かを開発するわけではなく、ひたすらリソースを削除していく行為に対しての評価も(評価する側から見て)難しいです。
結果として、優先度の低いタスクとしてマネージメントされる事も少なくないかもしれません。

しかし、それでも「誰かが」やったほうが良い。これは確かです。

そこで、この記事のタイトルに戻り ”先づ隗より始めよ” の故事に則ります。
こういった改善作業を担うエンジニアの待遇について省み、どこの馬の骨とも知らない私のような人間だとしても高く設定することで、よりセキュリティ意識の高いエンジニアの応募が増え、ひいては「割れ窓をみんなで減らそう」というカルチャーの醸成に繋がるかもしれません。
是非ご検討ください。(直訳:5000兆円ください)

最近またAWSリソースの削除を実施する機会が増えました。もしかすると、システムの成熟度や運用期間によっては削除リソースの数をKPIにしても良いフェーズと言うのもあり得るのかなぁ、とぼんやり考えている今日この頃です。

最後まで読んでいただき、ありがとうございました。

脚注
  1. 例えば、rootアカウントのMFA設定や、認証情報の適切な保存などでしょうか。 ↩︎

  2. コントロールはAWSのアップデートによって不定期に追加/削除されることがあります。 ↩︎

  3. 上限緩和申請は可能のようです。 ↩︎

Discussion