はじめに
こんにちは!スタイル・エッジのSREチームでPjMを担当しているpeipeiです!
サービス全体の信頼性を高めるべく、SRE文化の浸透や、それを支える仕組みづくりに日々取り組んでいます。
前回の記事では、AWS Security Hub(以下、Security Hub)を導入する背景や、可視化による課題発見についてご紹介しました。
今回はその続編として、Security Hubを活用したセキュリティ対策の「標準化」をどのように進めているのかをご紹介します。
対応方針 〜「可視化 ⇒ 改修 ⇒ 予防」のアプローチ〜
私たちはセキュリティ対策を効果的に進めるため、「可視化 ⇒ 改修 ⇒ 予防」の3ステップでアプローチしています。段階的に対応することで、対応の抜け漏れを防ぎながら継続的な改善を目指しています。
- 可視化:現状の課題を明確にし、全体の状況を把握する(前回の記事で紹介)
- 改修:SREチームがプロダクト開発チームと連携して修正を進める(今回の記事)
- 予防:同じ課題が再発しないよう仕組み化する(今回の記事)
社内のAWSアカウントを統合したダッシュボードの作成や、チャット通知機能の実装によって課題の可視化が進んできています。 次のステップは、可視化された課題にどう対処し、再発をどう防ぐかという点です。
2. 改修 - SREチームがプロダクト開発チームと連携しながら修正を進める
対応ガイドラインの作成
改修作業は各プロダクトの担当者が主体で進め、判断が難しい項目についてはSREチームと一緒に対応方針を検討します。
ただし、いきなり各プロダクトへ対応を依頼をしても、担当者によって対応の質や優先度が異なり、結果として期待通りの進捗を確保できない懸念がありました。そこで、対応方針の統一化を図るため、ガイドラインを作成しました。
ガイドラインには、「Security Hubで指摘されているリソースの確認方法」、「優先順位の考え方」、「対応方針を示したナレッジへの案内(後述)」などを記載しています。
また現在では、各プロダクトの担当者が単独でコントロールを「無効化*1」することや、検出結果を「抑制*2」することは避け、SREチームとの協議を経て実施する運用としています。
「無効化」は社内のポリシーとして検出する必要のないコントロールに対して行うようにしており、「抑制」は以下のようなケースで行うようにしています。
【抑制を行うケース】 1. 正当な理由がある場合 例:正当な理由による特定のポートやプロトコルの使用、業務上必要な例外的なリソース構成。 2. リスクの低い問題であると判断した場合 例:テスト環境や非本番環境での低リスクな問題、期間限定で許容されるリソース構成。
説明会の実施
プロダクト全体の巻き込みを図るため、各プロダクトの担当者を招集し、ガイドラインに関する説明会を実施しました。説明会ではガイドラインの内容を解説するとともに、質疑応答の時間を設け、参加者が内容を理解し、納得した上で改修作業に取り組めるよう配慮しました。
説明会で寄せられた質問とその回答は、ガイドラインのQ&Aセクションに反映し、内容のさらなる充実を図りました。その結果、説明会後に新たに加わったメンバーも、ガイドラインを参照するだけで適切な対応ができており、ガイドライン作成の効果を実感しています。
ナレッジ共有の仕組み化
Security Hubの対応で共通するケースが多いため、ナレッジをNotionに集約し、全プロダクト担当者が閲覧可能な共有基盤を整備しました。これにより、対応方針の属人化を防ぎ、作業効率の向上を目指しています。
ナレッジでは、「主な対応方針」や「対応時の注意事項」のほかに、「先人の知恵」と「参考資料」という項目を設けています。 「先人の知恵」には、過去に同様の対応を行ったプロジェクト担当者が、対応時のチケットリンクなどを貼り付けています。 また、「参考資料」には、調査時に使用した資料などを記録するようにしています。 これにより、次に対応する人や、過去の対応を振り返りたいときに、ノウハウが蓄積された状態を維持できるようにしています。
当初はSREチーム主導でナレッジ作成を行っていましたが、次第にプロダクト側から「新規でナレッジを書いても良いか?」という声も上がるようになり、文化として定着しつつあります。
対応方針を検討する上で、Classmethod様のAWS Security Hub ガイドは非常に参考になっています。各コントロールの解説が詳細であるだけでなく、説明の裏付けとなる情報源へのリンクも豊富に提供されており、効率的な対応が可能になっています。
無効化処理の効率化
前述の通り、Security Hubのコントロールの中には、社内ポリシーに基づき「無効化」とし、チェック対象外とする項目があります。例えば、弊社では[RDS.13] RDSのマイナーバージョンの自動アップグレードが有効であること
が該当します。
弊社は、マイナーバージョンアップであっても、検証環境での動作確認後に本番環境へ手動適用する方針としています。これは、過去に筆者が経験したように(こちら) 、検証が不十分な状態でのバージョンアップは予期せぬ問題を引き起こす可能性があるためです。
そのようなコントロールの無効化を手動でアカウントごとに管理するのは非効率なため、自動化フローを整備しました。具体的には、無効化対象のコントロールを記述したYAMLファイルをLambda関数に渡し、全AWSアカウントの該当項目を一括で無効化します。
工夫したポイント
- コントロールの無効化リストをGitHub Actions経由でS3にアップロード
mainブランチへのマージをトリガーに、コントロールの無効化リストが自動でS3にアップロードされる仕組みです。S3のバージョニングも有効にしており、誤操作時の復旧を可能にしています。当初はJSON形式でしたが、コメント記述の容易さからYAML形式に変更しました。
# コントロールの無効化リスト AWS-SecurityHub-Controls: # 2025/01/22 SREにて判断(参考:https://○○○○○) RDS.13: "マイナーバージョンアップは自動で行う方針のため無効化" # 2025/02/04 SREにて判断(参考:https://△△△△△) CloudTrail.5: "CloudWatchLogsではなくS3の保存で十分であると判断して無効化"
- S3のPUTイベントをトリガーにLambda関数を実行
CDKでリソース構築していますが、Lambda関数はデプロイ後の自動実行ではないため、トリガーにS3 PUTイベントを選択しました。この関数がAssumeRoleを用いて各メンバーアカウントのSecurity Hub設定を一括変更します。
リソースはセキュリティ統括アカウントに集約管理し、メンバーアカウントにはAssumeRole用のIAMロールのみを配置しました。セキュリティ統括アカウントへのアクセス権限を最小化し、誤操作による設定変更を防いでいます。
定期的なコントロール項目の見直し
Security Hubのコントロールは常に変化するため、「抑制」や「無効化」設定の放置はリスクになります。また、インフラ構成の変化により、過去の判断が現状に合わないこともあります。継続的な見直しが理想ですが、運用負荷を考慮し、3ヶ月ごとのレビューをルール化し、SREチームのカレンダーに定期イベントとして登録しています。
3.予防 - 同じ課題が再発しないように仕組み化する
CI/CDでのセキュリティチェックの自動化
改修体制の整備に加え、重要なのは脆弱性のあるリソースの新規作成を防ぐことです。Security Hub運用を通じて、既存リソースの改修はシステム影響が大きく、慎重な調整が必要と分かりました。
そのため、開発プロセスにおけるセキュリティリスク検知を目指し、CloudFormationテンプレート等の構成定義ファイルの作成・更新時にチェックを導入しました。具体的には、cfn-nagをCI/CDパイプラインに組み込み、mainブランチへのマージ前に自動検証を行っています。
工夫したポイント
- cfn-nagの検知除外機能
セキュリティリスクの検知結果は、社内ポリシーに基づき対応不要な場合も考えられます。そのため、--deny-list-path
オプションを利用して、チェック対象から除外できる仕組みを導入しました。
# スキャンの実行(deny-list付き) cfn_nag_scan --input-path <CloudFormationテンプレート名> --deny-list-path ./settings/cfn-nag_deny_list.yml
# cfn-nag_deny_list.ymlの例 RulesToSuppress: - id: W9 reason: "Public IP for bastion host, access controlled by security group. No operational issues." - id: W28 reason: "Full S3 access required for dedicated batch job user only. No other operations." - id: W40 reason: "Temporary SSH access for maintenance, will be restricted after completion. No operational issues."
- cfn-nagの複数ファイル解析
cfn-nagは通常、複数のCloudFormationテンプレートを解析する際、いずれかのファイルでFAIL
が検出されると、その時点で処理を中断します。
たとえば、01_NW/vpc-sg.yaml
および03_APP/apigateway.yaml
の両方に脆弱性が存在し、FAIL
が発生する設定になっていた場合でも、以下の例のように、先にFAIL
が見つかったファイルのみが対象となり、残りのファイルは解析されません。
# FAIL発生時の挙動(1ファイルのみ解析) ▶︎Run cfn-nag on changed files ------------------------------------------------------------ 01_NW/vpc-sg.yaml ------------------------------------------------------------------------------------------------------------------------ | FAIL F1000 | | Resource: ["RDSSG"] | Line Numbers: [49] | | Missing egress rule means all traffic is allowed outbound. Make this explicit if it is desired configuration ------------------------------------------------------------ Failures count: 1 Warnings count: 0 Error: Process completed with exit code 1.
この問題を解決するため、FAIL
が発生しても解析を継続し、全てのファイルの検証結果を得られるようにしました。以下のGitHub Actionsのコードでその処理を実現しています。
# FAILをカウントしながら複数ファイルを解析する処理 - name: Run cfn-nag on changed files # ... 省略 ... run: | error_count=0 for file in ${{ steps.security_check.outputs.changed_files }}; do cfn_nag_scan --input-path "$file" --deny-list-path ./settings/cfn-nag_deny_list.yml || { # FAIL発生時にカウントアップ error_count=$((error_count + 1)) } done echo "ERROR_COUNT=$error_count" >> $GITHUB_OUTPUT - name: Fail if cfn-nag errors occurred if: steps.run-cfn-nag.outputs.ERROR_COUNT > 0 run: | echo "cfn-nag validation failed for ${{ steps.run-cfn-nag.outputs.ERROR_COUNT }} file(s)." # 全ての解析後にFAILがあればワークフローを失敗させる exit 1
この変更により、複数のファイルにわたるセキュリティリスクを網羅的に検知できるようになりました。以下の例のように、複数のファイルでFAIL
が検出されます。
# 改善後の挙動(複数ファイルを解析) ▶︎Run cfn-nag on changed files ------------------------------------------------------------ 01_NW/vpc-sg.yaml ------------------------------------------------------------------------------------------------------------------------ | FAIL F1000 | | Resource: ["RDSSG01"] | Line Numbers: [49] | | Missing egress rule means all traffic is allowed outbound. Make this explicit if it is desired configuration ------------------------------------------------------------ Failures count: 1 Warnings count: 0 ------------------------------------------------------------ 03_APP/apigateway.yaml ------------------------------------------------------------ | FAIL F38 | | Resource: ["APIGatewayRole"] | Line Numbers: [146] | | IAM role should not allow * resource with PassRole action on its permissions policy ------------------------------------------------------------ Failures count: 1 Warnings count: 0 ▶︎Fail if cfn-nag errors occurred cfn-nag validation failed for 2 file(s). Error: Process completed with exit code 1.
この実装により、パイプラインは複数のCloudFormationテンプレートに潜在するセキュリティリスクを漏れなく検出し、開発者は全ての問題を把握した上で対応を検討できるようになりました。その結果、セキュリティのシフトレフトが促進されることを期待しています。
今後の展望
Security Hubの改修運用を継続的に推進し、サービス全体のセキュリティレベル向上を図ります。将来的には、新規ローンチされるすべてのプロダクトにおいて「Security Hub指摘ゼロ」を目指していきます。
また現在、手作業で行っているSecurity Hubの検知項目に対するイシュー起票プロセスについては、運用効率化を目的に、自動化の仕組みの構築を検討しています。
連載予定
投稿日 | タイトル |
---|---|
5月 | SREが“消火活動”に本気で向き合って見えた、信頼性向上へのリアルな一歩 |
6月 | SREとしてはお休み |
7月 | ポストモーテム文化の醸成 |
※内容や更新予定日は変更になる可能性があります。
連載を通じて、SREチームのチャレンジや日々の気づきを発信していきます。
「SREって何から始めればいいの?」と悩む方や、自社の運用課題に向き合っている方の参考になれば嬉しいです。
一緒に働く仲間を募集しています!
スタイル・エッジでは、SRE文化の構築に向けてともに挑戦していただける仲間を募集中です。
ご興味をお持ちいただけた方は、ぜひ採用サイトもご覧ください!
recruit.styleedge.co.jp