話題の記事

[安全なAWSセキュリティ運用ナレッジ2022]セキュアアカウントの使い方

AWS環境をセキュアにセットアップする方法と、その運用方法を詳細に紹介します。秘伝のタレである具体的な設定も書いてます。みんな真似していいよ!
2022.02.03

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、臼田です。

みなさん、安全にAWS使えていますか?(挨拶

今日は全てのAWSユーザーが安全にAWSを活用し、セキュアに運用できるようにナレッジを大量にダンプしたいと思います。

弊社サービスに関連させて書く部分もありますが、基本的にどのようなAWS環境でも適用できると思います。

ちょっと長い背景

クラスメソッドでは長いこと様々なAWSを利用するお客様を支援しています。私は特にセキュリティ周りについて支援させていただくことが多く、最近はAWSのセキュリティサービスが充実していることから、これらの初期導入や運用設計、あるいはインシデント対応やその後の組織としてのセキュリティ体制づくりなどいろんな関わり方をしてきました。

どのようにセキュリティサービスを有効化し、どう使っていけばいいか、ということを以下のようにブログでたくさん書いてきました。

各サービスの記事一覧: Amazon GuardDuty / AWS Security Hub / IAM Access Analyzer / Amazon Detective

そして、これらの有用なAWSのセキュリティサービスをお客様個別でお金をもらって構築や運用の設計を支援させていただいてきましたが、僕たちが支援できる範囲以上にAWSを利用したい方がたくさんいらっしゃるので、無償で最初からこれらの設定がされた状態でAWSアカウントを払い出すサービスを開始しました。

これが「セキュアアカウント発行サービス」です。これに伴いAWSアカウントのセットアップ以外にも「不正利用時の復旧支援」や「障害発生時の復旧支援」などのサポート体制についても明文化しました。

クラスメソッドメンバーズ リニューアルの概要

クラウド利用におけるインシデント原因の80%を事前に回避または軽減するセキュアアカウント発行サービスを提供開始〜セキュリティ対策を標準サービス化し運用改善支援・技術サポート・コスト最適化も強化〜 | クラスメソッド

このサービスでどんな設定をしているか、セキュアに設定したあとAWSアカウントをどう運用すればいいかを詳しく紹介します。弊社のサービスを使っていただくと出来合いの物を使えますし、真似して自身で環境構築していただいても、もちろんいいでしょう。真似していいよ!

セキュアアカウントのアーキテクチャ

以下のような感じです。ばーん。

いろんな設定を行っていますが、主に各種設定の基準になっているのはAWS Security Hubの「AWS基礎セキュリティベストプラクティスv1.0.0」です。概ねこれを満たすよう設定しています。

この状態でSecurity Hubのセキュリティスコアは99%となります。(2022/02/03時点)

納品時に引き渡されるIAMユーザーのMFAを設定していただくとセキュリティスコアは100%になります。すぐに設定しましょう。

各項目毎どんなことをなんのためにしているか説明します。なお、この構成や設定は2022/02/01時点のものですので、仕様変更等により変わる可能性があることをご了承ください。

AWS上の証跡管理

AWS上ではほぼすべての操作はAPIで実行されます。この実行履歴を取得するサービスがAmazon CloudTrailです。そして、各種AWSリソースの変更履歴を取得するサービスがAWS Configです。この2つのサービスは最初に有効化すべきサービスです。

AWS上でどのような操作がされたか、どのようにリソースが変更されたかを確認する手段であり、ユーザー側で取得する責任があります。

セキュアアカウントでは以下のような設定がされます。

  • AWS CloudTrail
    • 東京リージョンで「すべてのリージョンに適用される証跡」を作成し有効化
    • 記録対象イベント
      • 管理イベント(データイベントは記録されません)
    • ログファイルのSSE-KMS暗号化
      • 有効
    •  ログファイルの検証
      • 有効
  • AWS Config
    • 全てのリージョンで有効化
    • 記録するリソースタイプ
      • サポートされているすべてのリソース
    • グローバルリソースを含める
      • 東京のみ有効
    • 配信チャンネルのSSE-KMS暗号化
      • 有効
  • S3バケット
    • AWS CloudTrailのログ配信先
    • AWS Configの配信チャネルのバケット
    • SSE-KMSによるデフォルト暗号化
    • 3年間データを保持するライフサイクルポリシー
  • AWS KMS
    • CloudTrail / Config保管バケット用CMK
      • キーのタイプ: 対称

この設定で満たせるSecurity Hubの基準は以下のとおりです。

  • [CloudTrail.1] CloudTrail を有効にし、少なくとも 1 つのマルチリージョンの証跡で設定する必要があります
  • [CloudTrail.2] CloudTrail では、保管時の暗号化が有効になっている必要があります
  • [CloudTrail.4] CloudTrail ログファイルの検証が有効になっているかどうかを確認します
  • [CloudTrail.5] CloudTrail トレイルが Amazon CloudWatch Logs と統合されていることを確認する
  • [Config.1] AWS Config を有効にする必要があります
  • [S3.2] S3 バケットではパブリック読み取りアクセスを禁止する必要があります
  • [S3.3] S3 バケットはパブリック書き込みアクセスを禁止する必要があります
  • [S3.4] S3 バケットでは、サーバー側の暗号化を有効にする必要があります
  • [S3.5] S3 バケットは、Secure Socket Layer を使用するためのリクエストが必要です
  • [S3.6] 他のユーザーに付与された Amazon S3 のアクセス許可AWSバケットポリシーのアカウントは制限する必要があります
  • [S3.8] バケットレベルで S3 ブロックパブリックアクセス設定を有効にする必要があります

AWS上の証跡管理の設定はあまり調整することは無いですが、ログの保持期間などを調整したい場合には、対象のS3バケットのライフサイクルポリシーを変更するといいでしょう。

デフォルトのS3公開防止

Amazon S3はフルマネージドなオブジェクトストレージのサービスです。デフォルトでS3のバケットは非公開ですが、うっかり公開設定にしてしまって情報流出してしまう、という事故がよく発生します。

S3のアクセス制御の仕組みは様々ありうっかり公開しがちなので、最近では2つのブロックパブリックアクセスという更に上乗せして非公開にするための設定が加わりました。1つはAWSアカウントレベルでのブロックパブリックアクセスで、もう1つはバケットレベルのブロックパブリックアクセスです。少なくともこれらが有効である限りはうっかり公開してしまうことを防げます。

セキュアアカウントではAWSアカウントレベルでのブロックパブリックアクセスを有効化しています。

この設定で満たせるSecurity Hubの基準は以下のとおりです。

  • [S3.1] S3 ブロックパブリックアクセス設定を有効にする必要があります
  • [S3.2] S3 バケットではパブリック読み取りアクセスを禁止する必要があります
  • [S3.3] S3 バケットはパブリック書き込みアクセスを禁止する必要があります
  • [S3.8] バケットレベルで S3 ブロックパブリックアクセス設定を有効にする必要があります

S3バケットに外部公開したいデータを入れる場合には、この設定を無効化して変わりにバケット毎にブロックパブリックアクセスの設定を管理してください。

ただし、HTML/CSS/JavaScriptなどのWeb用や画像/動画などの静的コンテンツはS3のブロックパブリックアクセスはそのまま、CloudFrontのOrigin Access Identity (OAI)を利用して配信しましょう。このような用途でS3バケットをそのまま公開することは不要な権限を設定することからアンチパターンです。以下の基準にも違反します。

  • [CloudFront.2] CloudFront ディストリビューションでは、オリジンアクセスアイデンティティを有効にする必要があります

EBSのデフォルト暗号化

ブロックストレージであるAmazon EBSのデフォルト暗号化設定を有効化しています。

セキュアアカウント発行時のデフォルトの暗号化キーはAWSマネージドキーを指定していますが、お客様で発行したカスタマーマスターキー(CMK)に変更することも可能です。データを保管するストレージをCMKで暗号化することで、暗号化キーの削除による暗号化消去(Cryptographic Erase)が可能です。お客様が暗号化消去を行うことで、AWS上からデータを論理的に削除したことが説明できます。安全なデータ破棄の考え方は クラウドにおける安全なデータの廃棄 も参照してください。

さらにデータの破棄サイクルが異なるようなEBSの管理を行う場合(例えばマルチテナントのサービスで顧客毎にEBSを分けて保存するような使い方)、それぞれCMKを分けておくとライフサイクルに合わせて暗号化消去を実施することが可能です。事前にデータのライフサイクル設計を行ってから暗号化の設計を行いましょう。

この設定で満たせるSecurity Hubの基準は以下のとおりです。

  • [EC2.3] アタッチされた EBS ボリュームは保管時に暗号化する必要があります
  • [EC2.7] EBS のデフォルト暗号化を有効にする必要があります

パスワードポリシー強化

IAMユーザーのパスワードポリシーを以下の設定にしています。

  • パスワードの最小長
    • 8文字
  • 少なくとも1つの大文字が必要
    • ON
  • 少なくとも1つの小文字が必要
    • ON
  • 少なくとも1つの数字が必要
    • ON
  • 少なくとも1つの英数字以外の文字が必要
    • ON
  • ユーザーにパスワードの変更を許可
    • ON

この設定で満たせるSecurity Hubの基準は以下のとおりです。

  • [IAM.7] IAM ユーザーのパスワードポリシーには強力な設定が必要です

もちろんこのポリシーをさらに強化することも可能です。

AWS上のID管理のTipsとしては、多数のAWSアカウントを利用するようになるとIAMユーザーの管理が煩雑になってしまうため、1つのAWSアカウントにIAMユーザーを集約して、そこから各AWSアカウントにスイッチロールするJumpアカウント方式や、AWS SSOやサードパーティのIDaaSなどを利用したSSOを検討しましょう。IAMユーザーは極力作らないことがベストプラクティスです。

デフォルトVPCの削除

各リージョンに1つずつ用意されているデフォルトVPCを削除します。

デフォルトVPCはAWSアカウント作成時に一緒に生成されるVPCです。合わせてサブネットやセキュリティグループなども作成されていて、これらを意図せず設定し、必要以上の公開範囲でリソースを晒してしまう可能性があるためVPCごと削除します。明示的な意図に合わせてVPCリソースを作成し、利用しましょう。

また、VPC作成時に同時に作成されるデフォルトのセキュリティグループは全てのルールを削除し、使用しないようにします。デフォルトのセキュリティグループは各種設定でパラメータを省略した際に意図せずアタッチされるなど不用意な公開を招く性質がありつつ、削除することもできないからです。

この設定で満たせるSecurity Hubの基準は以下のとおりです。

  • [EC2.2] VPC のデフォルトのセキュリティグループでは、インバウンドトラフィックとアウトバウンドトラフィックが禁止されます

セキュリティサービス有効化 + チューニング

各種AWSのフルマネージドなセキュリティサービスを有効化します。多いので順に説明します。

Amazon GuardDuty

AWS上でマネージドに脅威検知が出来るサービスです。簡単に言うとAWSアカウントへの不正なログイン、EC2へのマルウェア感染・コインマイニングの検知、意図せぬS3のデータ漏洩などを検知してくれます。すぐれもの!

全リージョンで有効化し、追加のS3やKubernetesのチェックも有効化します。それぞれ使っていなければお金がかからないので、とりあえず全部有効化で問題ありません。

AWS上ではサービスや設定も多くすべてを人が見渡すことは困難ですから、異常が起きたことにすぐ気付ける仕組みとしてGuardDutyは非常に優秀です。仕組みとしてはCloudTrail / VPCフローログ / DNSログ / S3データイベントログ / Kubernetes監査ログをバックグラウンドで自動的に収集し、異常を検知してくれます。これらのログを自分たちで収集・処理してアラートを出すよりも数段簡単にコスパよく利用できます。

この設定で満たせるSecurity Hubの基準は以下のとおりです。

  • [GuardDuty.1] GuardDuty を有効にする必要があります

GuardDuty運用のコツは検知後の対応と、そのための事前準備です。具体的な運用方法は他のセキュリティサービスと合わせて後述します。

AWS Security Hub

AWS上のセキュリティイベントの集約と、危ない設定がないかセキュリティチェックする、という2つの機能を持つサービスです。特にセキュリティチェックは有用で、ここまでで様々なチェック基準を書いてきましたがこれらを自動でチェックしてくれます。

全リージョンで有効化し、セキュリティチェックとして「AWS基礎セキュリティのベストプラクティスv1.0.0」を有効化します。セキュリティチェックもいくつかは管理が煩雑になるため無効化してもいいです。セキュアアカウントでは以下を無効化しています。理由も添えておきます。

  • 無効化項目
    • [IAM.6] ルートユーザーに対してハードウェア MFA を有効にする必要があります
      • クラスメソッドでは代わりにソフトウェアMFAで管理していて、適切な職掌分離を行っています
    • [EC2.8] EC2 インスタンスは IMDSv2 を使用する必要があります
      • IMDSv2を利用することでSSRF攻撃に対して耐性が得られますが、動作環境を整備する難易度の高さから外しています。十分に検証しIMDSv2を利用できる環境であれば、有効化してもいいでしょう
    • [CloudTrail.5] CloudTrail トレイルが Amazon CloudWatch Logs と統合されていることを確認する
      • CloudTrailのログはS3に保存されていれば通常問題ありません。CloudWatch Logsに出力することで迅速なアラートを出すことが可能なので、こういった用途で利用する場合は有効化してもいいでしょう。通常はこの役割はGuardDutyに任せることが多いです。
    • [Config.1] AWS Config を有効にする必要があります(東京リージョン以外無効)
      • グローバルリソースを記録していることが条件に含まれており、これが東京リージョンにのみ設定しているため、東京リージョン以外を無効化します。グローバルリソースの記録を全リージョンで実施するとログが重複するのでメインのリージョンでのみ設定します

最近リージョンをまたいで1つのリージョンにセキュリティイベントを集約することが出来るようになったので、東京リージョンに集約しておきます。

Security Hubの運用のコツはセキュリティチェックをいかに楽に回すかです。これも詳細は後述します。

Amazon Detective

セキュリティインシデントが発生した際に調査をするためのサービスです。ログを集約して相関分析と可視化を提供します。

全リージョンで有効化しておきます。

DetectiveはGuardDutyと同じようなログ収集の仕組みで、CloudTrail/ VPCフローログ / GuardDutyの結果を自動で収集し、IAMユーザー・IAMロール・一時クレデンシャル・EC2・IPアドレスなどのエンティティとその関連性を内部のグラフDBで相関させ、きれいに可視化してくれます。ユーザーがログをクエリしたり、エクセルに落とし込んで目で関連性を調査しなくても自動的にくっつけてくれます。頼もしい!

Detectiveの運用方法はGuardDutyと密接に関係しています。これも詳細は後述します。

IAM Access Analyzer

IAMを始めS3やLambdaなど外部のリソースからアクセスできる設定になっているものを検知してくれるサービスです。無料です。活用しない手はありません。

IAMと名前がついていますがリージョナルサービスです。全リージョンで有効化します。

セキュアアカウントではクラスメソッドが設定するIAMについてはアーカイブルールを登録し検知しないようにしています。

運用としては、各種リソースで外部(別のAWSアカウントや未認証のユーザー)からアクセスが可能に設定された場合に、そのリソースとポリシーの内容が通知されます。意図した設定であればアーカイブし、意図していなければ直ちに修正します。具体的な通知内容などは後述します。

セキュリティアラート整形 + 通知設定

各種セキュリティサービスから出力されるアラートを集約・整形してメールやSlack、あるいは必要であればその他の仕組みに通知します。対象となるセキュリティサービスはAmazon GuardDuty / AWS Security Hub / AWS IAM Access Analyzerです。

上記図はざっくりしていますが、詳細なアーキテクチャは以下のとおりです。どーん。

図だけでもよくわからないと思うので詳細に説明します。細かく知らなくてもセキュリティアラートの通知は受け取れますので、どうでもいいよって方は飛ばしてください。

まずこういったアーキテクチャにしている理由ですが、セキュリティアラートって出力されるままだとjson形式だし英語むき出しなので見るのが大変なんですね、なので実運用で使えるように整形して・なるべく日本語で説明を補って、かつどの通知先にも飛ばせるように共通化しています。通知するだけなら直接AWS SNSやAWS Chatbotを使ってもいいでしょう。

上記の整形の結果メールやSlackでは以下のような通知を受け取ることが可能です。

以下の観点を中心に整形しています。

  • タイトルに緊急度を入れる
  • 最初に日本語で何をすべきか説明する
  • 各項目を日本語で見出しをつける
  • 次に開くべきリンクを埋め込む

これによりセキュリティアラートの判断を的確に行えるようになり、次の調査が必要な場合でもリンクを開いてスムーズに調査を開始できます。

昔はこういった整形をほとんどAWS Lambdaで実施をしていましたが、最近はAWS StepFunctionsがすごく良くなったので、Lambdaレスで実装することができています。Lambdaを利用した仕組みは自由度が高い反面、採用する言語ライブラリの保守が必要となるため、作って渡す仕組みには向いていないこともあり、セキュアアカウントではLambdaレスにしています。

アーキテクチャ図の左から流れを説明します。

まずいちばん左は東京以外のリージョンです。Security Hubはリージョンをまたいだ集約が可能なのでその機能で東京リージョンに転送し、GuardDutyとAccess Analyzerはこの機能がないためEventBridgeのルールでこれを東京リージョンのEventBridgeデフォルトバスに転送します。

東京リージョンのEventBridgeでは3つのサービスのイベントを検知するルールを作成し、それぞれStepFunctionsに転送します。

StepFunctionsによる整形は以下のようなフローになっています。

ステートマシンの定義は以下のような感じになっています。長いです。

{
  "Comment": "A description of my state machine",
  "StartAt": "Choice Service",
  "States": {
    "Choice Service": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.source",
          "StringEquals": "aws.guardduty",
          "Next": "GuardDuty Sharping"
        },
        {
          "Variable": "$.source",
          "StringEquals": "aws.securityhub",
          "Next": "Choice Severity"
        },
        {
          "Variable": "$.source",
          "StringEquals": "aws.access-analyzer",
          "Next": "AccessAnalyzer Sharping"
        }
      ],
      "Default": "Fail"
    },
    "Choice Severity": {
      "Type": "Choice",
      "Choices": [
        {
          "Or": [
            {
              "Variable": "$.detail.findings[0].Severity.Label",
              "StringEquals": "LOW"
            },
            {
              "Variable": "$.detail.findings[0].Severity.Label",
              "StringEquals": "INFORMATIONAL"
            }
          ],
          "Next": "Severity Low"
        },
        {
          "Variable": "$.detail.findings[0].Severity.Label",
          "StringEquals": "MEDIUM",
          "Next": "Severity Middle"
        },
        {
          "Or": [
            {
              "Variable": "$.detail.findings[0].Severity.Label",
              "StringEquals": "HIGH"
            },
            {
              "Variable": "$.detail.findings[0].Severity.Label",
              "StringEquals": "CRITICAL"
            }
          ],
          "Next": "Severity High"
        }
      ],
      "Default": "Severity None"
    },
    "Severity None": {
      "Type": "Pass",
      "Next": "Security Hub Sharping",
      "Result": "不明",
      "ResultPath": "$.SeverityName"
    },
    "Severity Low": {
      "Type": "Pass",
      "Next": "Security Hub Sharping",
      "Result": "低",
      "ResultPath": "$.SeverityName"
    },
    "GuardDuty Sharping": {
      "Type": "Pass",
      "Next": "EventBridge PutEvents",
      "Parameters": {
        "Subject.$": "States.Format('緊急度: {} GuardDutyセキュリティアラート Account: {}', $.detail.severity, $.detail.accountId)",
        "Message.$": "States.Format('以下の脅威を検知しました。\n意図したものであるか確認してください。\n検知タイプ: {}\n詳細: {}\nリージョン: {}', $.detail.type, $.detail.description, $.region)"
      }
    },
    "EventBridge PutEvents": {
      "Type": "Task",
      "Resource": "arn:aws:states:::events:putEvents",
      "Parameters": {
        "Entries": [
          {
            "Detail": {
              "Subject.$": "$.Subject",
              "Message.$": "$.Message"
            },
            "DetailType": "Sharped GuardDuty Findings",
            "EventBusName": "cm-security-alert-aggregator-bus",
            "Source": "custom.securityalert.stepfunctions"
          }
        ]
      },
      "End": true
    },
    "Fail": {
      "Type": "Fail"
    },
    "Security Hub Sharping": {
      "Type": "Pass",
      "Parameters": {
        "Subject.$": "States.Format('緊急度: {} Security Hubセキュリティアラート Account: {}', $.SeverityName, $.account)",
        "Message.$": "States.Format('Security Hubでセキュリティ上好ましくない設定を検知しました。\n意図したものであるか確認してください。\n検知内容: {}\nリソース種類: {}\nリソースID: {}\n詳細: {}\nリージョン: {}', $.detail.findings[0].Title, $.detail.findings[0].Resources[0].Type, $.detail.findings[0].Resources[0].Id, $.detail.findings[0].Description, $.detail.findings[0].Region)"
      },
      "Next": "EventBridge PutEvents"
    },
    "Severity Middle": {
      "Type": "Pass",
      "Next": "Security Hub Sharping",
      "Result": "中",
      "ResultPath": "$.SeverityName"
    },
    "Severity High": {
      "Type": "Pass",
      "Next": "Security Hub Sharping",
      "Result": "高",
      "ResultPath": "$.SeverityName"
    },
    "AccessAnalyzer Sharping": {
      "Type": "Pass",
      "Parameters": {
        "Subject.$": "States.Format('IAM Access Analyzerセキュリティアラート Account: {} リソース種類: {}', $.detail.accountId, $.detail.resourceType)",
        "Message.$": "States.Format('以下リソースが外部共有されています。\n意図した設定か確認してください。\nリソース種類: {}\nリソース名: {}\nリージョン: {}\nプリンシパル: {}', $.detail.resourceType, $.detail.resource, $.detail.region, $.detail.principal)"
      },
      "Next": "EventBridge PutEvents"
    }
  }
}

もっとやろうと思えば出来ると思うのでお好きにどうぞ。

そして、整形後カスタムイベントバスに集約されたイベントは、メールやSlackへ通知します。ここから先の通知設定はセキュアアカウントではデフォルトで設定されていません。通知先毎に設定が必要だからです。通知先の登録にはCloudFormationのテンプレートが用意してあります。詳細な手順は後述します。

初めにやること

セキュアアカウントを受け取ったみなさま、最初にやることが以下の2つあります。まずはこれを実施してください。

  • IAMユーザーのMFA設定(あるいはアクセス管理の初期設定)
  • セキュリティアラートの通知設定

IAMユーザーのMFA設定(あるいはアクセス管理の初期設定)

セキュアアカウントが発行されると、IAMユーザーが1つ発行されます。このIAMユーザーはデフォルトではユーザー名とパスワード(とAWSアカウントID)でログインが可能です。

しかしこれは、AWS上ではあまりセキュアではありません。なぜならAWSにログインするための画面はインターネットに公開されていて単一要素の認証ではAWSアカウントを保護するために不十分だからです。

すぐにMFA(多要素認証, Multi-Factor Authentication)の設定をIAMユーザーに対して行ってください。MFAデバイスにはいくつか種類がありますが、利用しやすいのは仮想MFAデバイスです。設定は以下を参考にしてください。

セキュリティアラートの通知設定

セキュアアカウントでは各種セキュリティサービスが有効化されています。何かあった時には通知が発生しますが、初期の状態ではその通知先は登録されていません。必ず受け取れるように設定してください。

クラスメソッドでは現在メールとSlackへの通知は簡単に設定できるようにCloudFormationテンプレートを提供しています。以下を確認しながらテンプレートを展開し通知の設定を行ってください。おすすめはSlackへの通知です。メールでの運用は非常に煩雑になるためです。

セキュリティアラート通知設定 — メンバーズポータル ユーザーガイド

メールやSlack以外への通知をしたい場合には、上述しているカスタムイベントバスからルールを作成し、任意の通知先を設定してください。

Slack Appの設定は以下も参考にしてください。

セキュリティ運用でやること

AWSの各種セキュリティサービスは有効化したら終わりではありません。そこからがスタートです。

しかし「セキュリティよくわからん」という方も多いと思います。でも安心してください。AWSのセキュリティサービスはとても良くできているので、以下で説明する運用のコツを押さえていただければAWS上でセキュアな環境を維持しやすくなります。

念の為の免責ですが、もちろんこれをやれば絶対安全というわけでもありませんし、AWS上に構築するアプリケーションなどの様々な仕組みにもセキュリティ対策やその運用が必要になりますので、ここで全てのレイヤーをカバーしているわけでもありません。ひとつひとつやっていきましょう。

AWS上のセキュリティ運用は大きく2つです。

1つは予防的統制、もう1つは発見的統制です。難しい言葉ですが、上記の図をみるとわかりやすいと思います。予防的統制は事故が起きないように未然にチェックすること、発見的統制は事故が起きたことを素早く検知し対応することです。そしてそれぞれに対応するサービスとして、予防的統制はAWS Security HubとIAM Access Analyzer、発見的統制はAmazon GuardDutyとAmazon Detectiveがあり、これらはセキュアアカウントではデフォルトで有効化され適切な設定にチューニングされています。

これらの目的と使い方を理解すればバッチリです。順に見ていきましょう。

AWS Security Hub運用のコツ

Security HubはAWS環境上の様々なサービスの設定を確認し、危ない設定がないかチェックしてくれます。そしてそのチェックに違反があるとセキュリティアラートが飛んできます。飛んできたアラートを見て、この危ない設定を是正したり、例外として許可したりするのが基本的な運用です。

チェックしている内容の一覧はAWS の基本的なセキュリティのベストプラクティスコントロール - AWS Security Hubに書かれていて、事前にこれら全ての項目を深く理解しておく必要性はありません。アラートが来た段階で、該当するセキュリティチェックの項目について確認すれば大丈夫です。このドキュメントには各項目毎以下の内容が含まれています。

  • 重要度
  • チェック内容
  • なぜ危ないのか
  • どのように修復したらいいか

1つチェック内容を取り上げてみます。例えば「[S3.8] バケットレベルで S3 ブロックパブリックアクセス設定を有効にする必要があります」のアラートが上がったとします。

このドキュメントには「このコントロールは S3 バケットにバケットレベルのパブリックアクセスブロックが適用されているかどうかを確認します」とあり、該当するS3バケットでバケットレベルのパブリックアクセスブロックが適用されていないためアラートが上がってきたことがわかります。

次に「S3 バケットレベルでパブリックアクセスをブロックすると、オブジェクトがパブリックアクセスを決して持たないようにコントロールが提供されます。パブリックアクセスは、アクセスコントロールリスト (ACL)、バケットポリシー、またはその両方からバケットおよびオブジェクトに付与されます。」とこの設定のメリットが書かれていて、逆に設定しないと誤って公開してしまう可能性があることがわかります。

そして実際の修復方法であるAmazon S3 ストレージへのパブリックアクセスのブロック - Amazon Simple Storage Serviceのリンクが紹介されています。もし対象がパブリックアクセスブロックが適用されているべきS3バケットであれば、これを活用して修復しましょう。

無事修復できたら、しばらくするとSecurity Hub上でセキュリティチェックが正常に戻っていることが確認できます。

一方で、該当バケットが公開する必要がある場合もあります。その場合は例外リソースとして登録します。Security Hubのリソース詳細画面でステータスを「抑制済み」とすることで例外登録が完了します。また、もしセキュリティチェック自体を外したい場合は、これを無効化することも可能です。詳細は以下をご確認ください。

通知については、すべてを通知しなくていい場合もあります。例えば、全体のセキュリティ管理者に対する通知は、特に重要度の高いものだけに絞るケースがあります。通知レベルを調整したい場合は、以下のブログのようにEventBridgeで重要度に応じたフィルタリング設定で対応が可能です。

また、発展的な使い方として検知した内容を自動的に修復するソリューションを活用する方法があります。よく検証する必要がありますが、適用できると運用がぐっと楽になります。詳細は以下のブログを確認してください。

IAM Access Analyzer運用のコツ

IAM Access AnalyzerはIAMを始めS3やLambdaなど外部のリソースからアクセスできる設定になっているものを検知してくれます。

AWSでは様々なリソースが別のAWSアカウントや外部に向けてアクセスを許可できる様になっているため、これらが本当にアクセスさせていいのかを確認する必要があります。

IAM Access Analyzerのセキュリティアラートでは「どのリソースが」「どこから」「どんなアクセスが許可されているか」が確認できます。IAM Access Analyzerの画面にアクセスして確認すると以下のようになっています。

この設定が想定されたものなら左下のアーカイブを押して完了です。想定されていない、危ない設定であれば該当リソースにアクセスして修正しましょう。これだけです!

シンプルな機能ですが、大事なアクセス制御の管理に非常に役立ちます。もちろん修正した場合は、なぜそのような設定をしてしまったか原因究明し、再発防止も検討しましょう。大体は知らずに設定してしまっているので、継続的な啓蒙が必要でしょう。

Amazon GuardDuty運用のコツ

GuardDutyはAWS上で発生する様々な脅威を検知してくれます。検知するカテゴリは大きく3タイプで、IAM / EC2 / S3です。それぞれ以下のような内容を検知します。(ほんの一部)

  • IAMタイプ
    • 不正ログイン
    • 漏洩したクレデンシャル利用
    • CloudTrail無効化
  • EC2タイプ
    • コインマイニング
    • C&Cサーバー接続
    • SSHブルートフォース(受信 or 送信)
  • S3タイプ
    • バケット公開
    • Torアクセス

これを見て非常に強力であることが理解できると思います。反面、対応が難しそうな印象を持たれるかもしれません。でも大丈夫です。対応も3タイプごと理解しておけば概ねOKです!ざっくり以下のようになります。

  • IAMタイプ
    • 認証情報を無効化する
  • EC2タイプ
    • EC2を隔離、保全、調査する
    • 調査は得意な会社に依頼できる準備でもいい
  • S3タイプ
    • アクセス権限を絞る

それぞれ検知内容の詳細・どのような観点でチェックすればいいか・対応の方法については検索タイプ - Amazon GuardDutyに検知タイプ毎詳細に書かれています。

詳細な初動対応については以下ブログの「5. [中級]インシデントに対応する -> 脅威検知時の初動対応」もご確認ください。

上記内容が理解できれば、あとはいざというときのために準備しましょう。初動対応で実施すべきことをまとめ、運用担当者がすぐにそれを見つけ、実行できるようにします。いざというときは焦りますので、使いやすい状態になっているか何度も訓練しましょう。

GuardDuty運用の全般は以下も参考になります。

また、最近Amazon EKSクラスターに対する脅威も検知できるようになりました。こちらも検知タイプのドキュメントを確認しながら対応可能です。詳細は以下もご確認ください。

Amazon Detective運用のコツ

DetectiveはGuardDutyで検知したインシデントの詳細を調査し、影響範囲を特定することができます。このサービス登場以前は、GuardDutyの検知内容を一通り確認して、それでも足りなければログを直接確認する必要がありました。今ではGuardDutyとDetectiveを確認すればほとんどのインシデントの調査が完了します。

Detectiveはその性質上、GuardDutyの画面からアクセスすることがほとんどです。GuardDutyの画面でインシデントを確認し、より詳細の確認が必要と判断したら「Detectiveで調査する」ボタンから移動します。

対象のリソースに関する情報が出てきて、それぞれのエンティティがリンクされていてドリルダウンしていけます。

各リソースに関連するAPI実行履歴を集計した状態で確認でき、フィルターもかけられます。これにより、攻撃者がどのようなAPIを実行したか、影響範囲がどれくらいあるかが確認できます。

検知から対応までのフローは以下も参考にしてください。

その他セキュリティ運用のコツ

ここまで各種セキュリティサービスについてどのように運用するかまとめました。これ以外にもAWS上ではセキュリティの考慮が必要な場面は実際にはたくさんあります。まず大原則として、AWSの責任共有モデルからAWS利用者が実施すべきセキュリティの責任を理解しましょう。

そして、セキュリティのベストプラクティスWell-Architected Frameworkのセキュリティの柱について理解しましょう。学べることは多いはずです。

特に、この記事ではセキュリティサービスの活用を主軸にしたセキュリティ運用について言及しましたが、その手前にはIAMの管理・アクセス制御があることを忘れないでください。ベストプラクティスやセキュリティの柱にもある通り、セキュリティには最小権限の原則があります。アクセス制御は気を抜かず常に気をつけてください。ただ、これを補う仕組みとしてSecurity HubやIAM Access Analyzerがいることも意識してください。過敏になりすぎる必要はありません。

AWS上に構築するアプリケーションのセキュリティを向上するためのサービスもたくさんあります。AWS WAFはWebアプリケーションを攻撃から守り、Systems Manager / Secrets Managerは機密情報を安全に管理でき、CloudFormationはミスを防止し素早く環境を展開できます。

AWSの便利な仕組みを最大限活用しましょう。

何度も引用していますが以下も合わせて確認してください。

よくある質問

Slack通知を導入したらSecurity Hubで「[SecretsManager.1] Secrets Manager のシークレットは、自動ローテーションを有効にする必要があります」が検知されました。どうすればいいですか?

これはSlackに通知するためのトークンをEventBridgeで登録した際に、EventBridgeが自動的に認証情報をSecrets Managerを登録したことにより検知されています。認証情報をSecrets Managerに格納すること自体はベストプラクティスになります。

認証情報は対象によっては定期的なローテーションを実施することが推奨されていて、このSecurity Hubの項目はそれを検知するためのものです。今回対象としているSlackのトークンについて、これを実施したほうがいいかを環境に合わせて検討していただく必要があります。選択肢は対応するのか、個別に例外として許容し、Security Hubで該当項目を「抑制済み」ステータスにするかの2択です。

弊社セットアップどおりにSlack Appを構築されている場合には、権限としてchat:writeのみアタッチされているため、投稿はできても読み込みはできません。これがどの程度のリスクなのか、と考えていただくといいでしょう。

私は一般的な環境であればリスクは限定的なので、この検知結果を抑制してもいいと判断します。

ちなみにToken rotation | Slackにてローテーションの手法について説明がありましたので、これを使って独自のLambdaを準備すればSecurity Hubの要件を満たすことも可能だと思います。

複数のAWSアカウントをまとめてセキュリティを管理していくにはどうしたらいいですか?

今回紹介した仕組みはAWSアカウント単体で成り立つものですが、逆に言うと重複して行っている部分が出てきます。例えばCloudTrail/Configやセキュリティサービスなどの有効化や集約、通知の設定などです。

多数のAWSアカウント全体を管理していく場合にはAWSマルチアカウント管理に適したソリューションを活用するとより効率よく管理できます。

AWSマルチアカウント管理を実現するために、全体を管理するAWS Organizationsや、これを利用し全体の構築と集約管理、ガバナンスの適用を簡単にするAWS Control Towerを活用するといいです。詳細は以下をご確認ください。

まとめ

AWSアカウントをセキュアにセットアップする方法と、その運用方法について詳細に紹介しました。

セキュアアカウントを使っていただくとより簡単にこれが利用できますし、これを参考にみなさんの環境に合わせた設計や運用にしていただくとより捗ると思います。

色々書きましたが、セキュリティは全ての仕組みに組み込まれるべき当然の機能であり・実装であり運用でもあります。ひとつひとつ着実にやっていきましょう。