見出し画像

Security Hub導入とGuardDutyの改善

こんにちは。エンジニア 佐々木です。

今回は、以前のAWS Control Tower導入の記事にて触れていたAWS Security Hub導入とAmazon GuardDutyの改善についての記事になります。

それぞれのサービスについて導入と改善を行ったため詳しく紹介したいと思います。


Security Hub, GuardDutyとは

まずは改めてSecurity HubとGuardDutyに関して説明します(ご存知の方は飛ばしてください)。

Security Hubは、AWSにおけるセキュリティイベントを集約し、AWS内でのセキュリティのベストプラクティスチェックの自動化を行ってくれるサービスです。これによってAWS Organizations内にあるすべてのアカウント・リージョンのセキュリティイベントを一つのアカウントに集約しつつチェックを行うことが可能になります。

具体的なチェック項目には、ECSタスク定義のネットワークモードがawsvpcモードになっているかといったリソース単位でのチェックであったり、GuardDutyが有効になっているかやアカウントのルートユーザーに対してハードウェアMFAが有効になっているかなど、アカウント全体に関わる項目などがあります。

GuardDutyは、悪意のあるアクティビティ・不正アクセスがAWSアカウント内で発生していないかを機械学習によって検出してくれるサービスです。あくまで検出までに留まるサービスなので、検出後は利用者が内容の確認と対応を行う必要があります。

こちらも具体例を例示すると、疑わしいファイルがECSクラスター内で検出されたであったり、悪意のある既知の IP アドレスからIAMやS3のAPIがコールされたなどがあります。

以降ではそれぞれどのような進め方でどんなことを行ったかを紹介します。

Security Hubの導入

進め方

クラシコムではSecurity Hubの導入実績がなく、いくつかの資料・ドキュメントの調査を行いどのように導入するかをまずは検討しました。

つい最近、Control TowerとSecurity Hubの統合がプレビューからGAになったことが発表されました。しかし導入時はまだプレビューだったため、Control Towerを介してSecurity Hubを有効化するのは見送っています。

Security HubはOrganizationsと統合されており、Organizationsの管理アカウントからメンバーアカウントに管理の委任が可能です。また、委任していれば他のメンバーアカウントでの自動有効化も可能になります。

上記記事にも記載がありますが、Security Hub はバックグラウンドで AWS Configを利用しており、AWS Configの有効化が前提となっています。Control Towerの管理下にあるアカウントに関しては自動でAWS Configが有効になるので、この点はControl Tower導入時点でクリアできました。

なお、Security Hubは複数のAWSサービスと統合されており、いろいろなサービスのセキュリティイベントが集約されます。

上記から、進め方としては以下のように進めることとしました。

  1. 委任の実施と有効化

  2. 通知の設定

  3. 運用しながらの調整

委任の実施と有効化

委任の実施と有効化は以下のような流れで実施しました。

  1. 管理アカウントでSecurity Hub有効化

  2. メンバーアカウントに管理を委任

  3. 委任先のアカウントでメンバーアカウントの自動有効化をONにセット

実際には構成管理ツールであるTerraformを使用し、リージョン拒否設定がされていないリージョンごとに有効化、委任などの設定を行いました。

# 管理アカウント
resource "aws_organizations_organization" "example" {
  aws_service_access_principals = ["securityhub.amazonaws.com"]
  feature_set                   = "ALL"
}

resource "aws_securityhub_account" "example" {}

resource "aws_securityhub_organization_admin_account" "example" {
  depends_on = [aws_organizations_organization.example]

  admin_account_id = "123456789012"
}

# 委任されたメンバーアカウント
resource "aws_securityhub_organization_configuration" "example" {
  auto_enable = true
}

ref: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/securityhub_organization_configuration

なお、委任先であるメンバーアカウントはControl Towerが作成したAuditアカウントがOrganizations内での役割上妥当と判断しAuditアカウントに委任しています。

通知の設定

通知に関してはいくつか注意が必要でした。

まず、Security Hubはリージョンごとに必要になるので、そのままだとリージョンごとにイベントが散ってしまいます。

しかしクロスリージョンのイベントを一つのリージョンに集約する機能がSecurity Hubに備わっているので、それを有効にする必要がありました。


次に注意が必要なのは、発生したイベントをEventBridgeで捕捉してSNSやChatBotを使用して通知したとしても、イベント自体のステータスが変わることはなく、定期的に通知が送られてくる可能性があることです。

定期的に通知を送られたくない場合、通知が送信されたら「通知済み」などのステータスに更新してやる必要があります。これはStep Functions(SFn)を使うことで、通知と同時に対象イベントのステータスを更新してやることが可能になります。

これでOrganizations内のメンバーアカウントで何かしらセキュリティイベントが発生したら、セキュリティレベルHIGH以上のものをEventBridgeが捕捉し、その後SFn → SNS → ChatBotという流れでSlackに通知されるようにできました。

運用しながらの調整

発生したセキュリティイベントはAWSのベストプラクティスに則ったものだったりしますが、必ずしも運用している組織・システムにとってベストなものとは限りません。実際に使い始めてみて、通知された内容を無効化したいコントロールが出てきました。

コントロールを無効化したい場合、すべてのアカウント・リージョンで無効化の作業を行いたいということもあります。

アカウント・リージョンが多いと、それなりの運用負荷になります。自前でツールを作成して管理しているところもあるようで、下記記事は参考になりました。

クラシコムの場合は使っているリージョンが少ないこと、無効化したいものがまだ少ないことから、Terraformで管理するようにしていますが、今後増えた場合には改めて管理方法を見直したいと考えています。

GuardDutyの改善

どんな状態だったか

クラシコムでは以前より、GuardDuty自体はOrganizationsの管理アカウントで有効になっていました。

Organizatins内の各メンバーアカウントを管理アカウントが招待することで、各アカウントの有効化と管理アカウントへのイベントの集約を行うという手順が必要だった状態です。

しかし、招待するということはOrganizationsの組織構造との連携はなく、このままだとメンバーアカウントを追加するたびに招待する必要が発生し、招待漏れが発生してしまう可能性がありました。

この手間と漏れの危険性を回避するのに、Security Hub同様特定のメンバーアカウントに管理を委任する機能が有効です。

委任を行うとOrganizationsの組織構造と連携されるようになり、新規アカウントも自動でGuardDutyの有効化が可能になります。

また、委任することで、Organizationsの管理アカウントから責務を切り離すことが可能になり、GuardDutyの管理を行うアカウントにアクセスするユーザーの権限管理もしやすくなるというメリットもあります。

進め方

さて、実際の進め方ですが、以下のように進めました。

 1. 既存リソースの削除
 2. Control Towerでリージョン拒否
 3. 委任の実施
 4. 通知の設定

既存リソースの削除

GuardDutyの設定に関してはすべてのリージョンに対してTerraformのmoduleを使用して管理していました。当時参考にしていたのは以下の記事で、Slackへの通知に必要なEventBridge, SNSなどのリソースも合わせて用意している状態です。

今回他のアカウントに委任することになるので、GuardDutyの通知周りの既存のリソースはいったん削除する必要がありました。

Control Towerでリージョン拒否

次にControl Towerでのリージョン拒否について。前回の記事にてControl Towerを使用したリージョン拒否設定について軽く触れました。

ref: https://note.com/kurashicom_tech/n/n20adc0124837#31b09011-ec87-4462-ac16-b9a341cd0946

これは実際には、このGuardDutyの整備を行う流れで実施したものになります。既存リソースの削除を行ってからリージョン拒否設定を行いたかったためです。

委任の実施

委任の実施ですが、Security Hub同様、Terraformで以下のようにコードを書きapplyを実施しています。

# 管理アカウント
resource "aws_organizations_organization" "example" {
  aws_service_access_principals = ["guardduty.amazonaws.com"]
  feature_set                   = "ALL"
}

resource "aws_guardduty_detector" "example" {}

resource "aws_guardduty_organization_admin_account" "example" {
  depends_on = [aws_organizations_organization.example]

  admin_account_id = "123456789012"
}

# 委任されたメンバーアカウント
resource "aws_guardduty_organization_configuration" "example" {
  auto_enable_organization_members = "ALL"

  detector_id = aws_guardduty_detector.example.id

  datasources {
    // 略
  }
}

ref: https://registry.terraform.io/providers/hashicorp/aws/5.6.2/docs/resources/guardduty_organization_configuration
https://registry.terraform.io/providers/hashicorp/aws/5.6.2/docs/resources/guardduty_organization_admin_account

なお、委任先であるメンバーアカウントはSecurity Hub同様Control Towerが作成したAuditアカウントに委任しています。

通知の設定

最後に通知の設定ですが、Security Hubを経由してSlackに通知するよう設定しました。

クラシコムでは一部重要度レベルに応じて通知先チャンネルを分けた運用を行っているのですが、GuardDutyのイベントは内容によってはかなり深刻なものである可能性があります。そのため基本的にレベルの高い通知を流すためのチャンネルに通知するよう設定しました。

そのため、EventBridge/SFn/SNS/ChatBotなどは上記Security Hubで設定したものとは別にリソースを用意するようにしました。

まとめ

Control Towerと合わせて導入・改善を行ったSecurity Hub、GuardDutyについて紹介しました。

AWSのセキュリティ系のサービスは多くあります。そしてその中でも複数のサービスが統合され、便利になりつつもありますが、その分複雑でもあります。

自身のプロダクトの状況に合わせ、必要に応じてサービスを取り入れることで、セキュリティレベルの向上をコツコツと積み上げることが大事かと思います。

最後に

ユーザー体験をより良くし、セキュアな状態を保ち信頼を積み重ねるプロダクト開発に興味があるエンジニアの方、いらっしゃればぜひお声がけください!