Trivyを利用して、S3のセキュリティチェックや推奨設定の監査を行う
風音屋 兼業エンジニアの “宮地克弥”(@int_tt) です。
データ分析基盤を構築するのに必要な不可欠なものとしてデータレイクが挙げられます。AWS を利用して構築する際には Amazon S3 の利用が推奨されています。
【公式参照】AWS 上でのデータレイク - Amazon S3 データレイクでデータサイロを排し、大規模で簡単な分析を可能にする
Amazon S3 はデータレイク以外にも静的コンテンツ置き場として幅広い用途で利用されています。
安価かつ簡単に利用することが出来る一方、設定を 1 つ間違えると情報流出に繋がる可能性が高く、設定ミスによって情報が流出する事例は今も後を絶ちません。 この記事では Amazon S3 を対象に、OSS である Trivy を利用したセキュリティチェックや推奨設定の監査方法を紹介します。
S3のセキュリティ設定
S3 は多くのセキュリティ項目が存在します。一般的なセキュリティ設定項目には、バケットポリシー、アクセスコントロールリスト、オブジェクト暗号化、バケットのバージョニング、およびログ記録が含まれます。
これらの設定を適切に管理することで、データ漏洩や悪意あるアクセスを防ぎ、企業の信頼性とコンプライアンスを維持できます。
Trivyを利用したS3のアセスメント
Trivy はコンテナや各言語のパッケージ、設定ミス等多くの用途で利用できる脆弱性スキャンツールです。昨年 AWS の設定もスキャンできるようになりました。
https://github.com/aquasecurity/trivy/pull/2493
スキャンする項目については、設定の危険度と理由、推奨の対応方法を以下のページで解説しています。
https://avd.aquasec.com/misconfig/aws/s3/
解説にあたって
以降は以下のバージョンを前提に解説します。
- trivy v0.38.3
trivy のセットアップについては公式ページを参考にセットアップします。
Trivyの実行
まずは簡単に実行してみます。
$trivy aws --service s3
Resource Summary for Service 's3' (AWS Account xxxxxxxxxxxx)
┌───────────────────────────────────────────────────────────────────────┬──────────────────────────────────────────┐
│ │ Misconfigurations │
│ ├──────────┬──────┬────────┬─────┬─────────┤
│ Resource │ Critical │ High │ Medium │ Low │ Unknown │
├───────────────────────────────────────────────────────────────────────┼──────────┼──────┼────────┼─────┼─────────┤
│ arn:aws:s3:::aws-athena-query-results-xxxxxxxxxxxx-ap-northeast-1 │ 0 │ 1 │ 2 │ 0 │ 0 │
│ arn:aws:s3:::aws-cloudtrail-logs-xxxxxxxxxxxx-xxxxxxxx │ 0 │ 1 │ 2 │ 0 │ 0 │
│ arn:aws:s3:::xxxxxxx-xxxxxx-xxxxxxxx │ 0 │ 5 │ 2 │ 1 │ 0 │
│ arn:aws:s3:::kazaneya-dev-datalake-example-xxxxxxxxxxxxxxxxxxxxxxxxxx │ 0 │ 1 │ 0 │ 0 │ 0 │
│ arn:aws:s3:::kazaneya-dev-logging-example-xxxxxxxxxxxxxxxxxxxxxxxxxx │ 0 │ 6 │ 2 │ 1 │ 0 │
│ arn:aws:s3:::kazaneya-xxxxxxxxxxxxxxxxxxxxxxx │ 0 │ 1 │ 2 │ 0 │ 0 │
│ arn:aws:s3:::kazaneya-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx │ 0 │ 1 │ 2 │ 0 │ 0 │
└───────────────────────────────────────────────────────────────────────┴──────────┴──────┴────────┴─────┴─────────┘
--arn
を指定することでより詳細な内容を知ることが出来ます。
$trivy aws --service s3 --arn arn:aws:s3:::aws-athena-query-results-xxxxxxxxxxxx-ap-northeast-1
Results for 'arn:aws:s3:::aws-athena-query-results-xxxxxxxxxxxx-ap-northeast-1' (AWS Account xxxxxxxxxxxx)
arn:aws:s3:::aws-athena-query-results-xxxxxxxxxxxx-ap-northeast-1 (cloud)
Tests: 3 (SUCCESSES: 0, FAILURES: 3, EXCEPTIONS: 0)
Failures: 3 (UNKNOWN: 0, LOW: 0, MEDIUM: 2, HIGH: 1, CRITICAL: 0)
MEDIUM: Bucket does not have logging enabled
════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
Buckets should have logging enabled so that access can be audited.
See https://avd.aquasec.com/misconfig/avd-aws-0089
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
MEDIUM: Bucket does not have versioning enabled
════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
Versioning in Amazon S3 is a means of keeping multiple variants of an object in the same bucket.
You can use the S3 Versioning feature to preserve, retrieve, and restore every version of every object stored in your buckets.
With versioning you can recover more easily from both unintended user actions and application failures.
See https://avd.aquasec.com/misconfig/avd-aws-0090
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
HIGH: Bucket does not encrypt data with a customer managed key.
════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
Encryption using AWS keys provides protection for your S3 buckets. To increase control of the encryption and manage factors like rotation use customer managed keys.
See https://avd.aquasec.com/misconfig/avd-aws-0132
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
結果出力のカスタマイズ
上記コマンドで簡単に結果の出力を得ることができました。 しかし、実際にアセスメントを行う際にはこれらの結果をまとめたり、対応しなくて良い検知結果を除外して上げる必要があります。
そこで、trivy にはtemplate機能があるため、こちらを活用して結果をまとめていきます。
{{-/* 追加したい除外ルールがある場合は以下の変数にIDを追加する */-}}
{{- $ignoreIDList := list "" -}}
# Trivy S3 Assessment Report
## Summary
|Content|Item|
|-----|----|
|Create at|{{ now | date "2006-01-02" }}|
### Overview
|Resource|Critical|High|Medium|Low|
|--------|--------|----|------|---|
{{ range . -}}
{{- $severityLow := 0 -}}
{{- $severityMedium := 0 -}}
{{- $severityHigh := 0 -}}
{{- $severityCritical := 0 -}}
{{- range .Misconfigurations -}}
{{- if (not (has .ID $ignoreIDList)) -}}
{{- if eq .Severity "CRITICAL" -}}
{{- $severityCritical = add $severityCritical 1 -}}
{{- else if eq .Severity "HIGH" -}}
{{- $severityHigh = add $severityHigh 1 -}}
{{- else if eq .Severity "MEDIUM" -}}
{{- $severityMedium = add $severityMedium 1 -}}
{{- else if eq .Severity "LOW"}}
{{- $severityLow = add $severityLow 1 -}}
{{- end -}}
{{- end -}}
{{- end -}}
|{{trimPrefix "arn:aws:s3:::" .Target}}|{{$severityCritical}}|{{$severityMedium}}|{{$severityMedium}}|{{$severityLow}}|
{{end -}}
## All Results
|Resource Name|Title|Severity|Reference|
|-------------|-----|--------|---------|
{{ range . -}}
{{- range .Misconfigurations -}}
{{- if (not (has .ID $ignoreIDList)) -}}
{{ trimPrefix "arn:aws:s3:::" .CauseMetadata.Resource }}|{{ .Title }}|{{ .Severity }}|{{ .PrimaryURL }}|
{{end -}}
{{- end -}}
{{- end -}}
上記テンプレートを保存し、実行します。
$trivy aws --service s3 --format template --template @trivy-template.md.tpl -o report.md
すると以下のような内容が出力され、結果を見やすくまとめることが出来ます。
特定ルールの検知除外に関しても template 内で実現しています。
- S3 のバケットログは CloudTrail で取得しているから S3 個別には必要ない。
- 外部サービスのデータを定期的に S3 へエクスポートしたいが、KMS のカスタマーマネージドキーに対応してないので検知から除外したい。
という際は以下のように先頭に該当する ID を追加してください。ID は検知結果に含まれる URL 等から確認することが出来ます。
{{- $ignoreIDList := list "AVD-AWS-0089" "AVD-AWS-0065" -}}
カスタムルール
また、デフォルトでは検知しないが、特別な要件で検知したいケースではカスタムルールを利用するのが有効です。 詳しくは公式ページを参考にしてみてください。
継続的な監視と改善
ここまでの方法で現状の課題点の洗い出すための手段とレポーティングを行うための準備が整いました。 これらの仕組みは実行するだけで気軽にチェックを行うことが出来るので、定期的な実行や S3 イベントと組み合わせることで常に状態をチェックすることが出来るようになります。
また、trivy には AWS Security Hub へレポート内容を送信する機能もあるため、より柔軟な通知や管理を実現できます。
https://aquasecurity.github.io/trivy/v0.38/tutorials/integrations/aws-security-hub/
こういった結果を伝えた人に合わせて合わせてカスタマイズしたり管理できるのも trivy の大きな強みです。
余談
今回この機能を使ったアセスメント実施時に、バグを見つけたので issue と PR を投げました。 素早く丁寧に対応頂き、コミュニティの活発さも伺えました!
https://github.com/aquasecurity/defsec/issues/1067
まとめ
本稿では trivy を使った現場で使える S3 のセキュリティアセスメントの方法について紹介しました。
データ分析では大量かつ大事なデータを扱うことが多いため、しっかり設定を精査し安心安全のデータ分析ライフを送っていきましょう!