[アップデート]AWS Control Towerのランディングゾーン3.2がリリース!Security Hubサービスマネージド標準のドリフトが検出できるようになりました!

2023.06.29

みなさん、こんにちは。

明るい笑顔がトレードマーク、ルイボスティーが大好きな芦沢(@ashi_ssan)です。

AWS Control Towerのランディングゾーン3.2がリリースされました! 例のごとく、AWS What’s newよりアップデートブログが公開されています。

ブログではControl TowerとSecurity Hubの統合と書かれていますが、実質的にはランディングゾーン3.2のリリースだと理解したので本ブログのタイトルにはそのように表記しました。

概要

ランディングゾーンとは?

そもそもランディングゾーンとは、AWSのベストプラクティスに基づいて構成したアカウントをスケーラブルに展開していくための仕組みの総称です。

AWS Control Towerは、このランディングゾーンの仕組みを実装する1つの方法で、ランディングゾーンに必要な機能を簡単にセットアップできます。

参考: AWS再入門2020 AWS Control Tower編 | DevelopersIO

今回のアップデートについて

今回新しくリリースされたランディングゾーン3.2でのアップデート内容は、以下の2つです。

  • Security Hubの『サービスマネージド標準: AWS Control Tower』によるドリフト検出が可能になった
  • リージョン拒否コントロールのアップデート

ここで出てくる用語が見慣れない方もいるかもしれないので少し補足します。

Security Hubの『サービスマネージド標準: AWS Control Tower』とは?

昨年のアップデートで追加された、Security Hubのセキュリティ標準「AWS 基礎セキュリティのベストプラクティス v1.0.0(AFSBP)」相当の基準をControl Towerのコントロールとして管理できるようになった機能です。

リージョン拒否コントロールとは?

Control Towerでは、Control Tower管理リージョンの設定に基づき、管理対象外のリージョンのAWSサービスにアクセスできなくなります。そのアクセス制限を実装するために生成されるコントロールです。

他のコントロールと異なり、特定のOUではなくランディングゾーン全体に適用される特別なコントロールです。

初期構築時にも有効化/無効化を選択できますが、後で変更できます。

前置きはここまでにして、以降実際にアップデートして詳しい内容を確認してみます。

やってみた

検証環境について

以下のようなControl Tower環境で検証を行いました。

Control Tower(ランディングゾーンバージョン3.1)有効化済み。OUや組織内のアカウント構成は以下。

ランディングゾーンのバージョンアップ(3.1→3.2)

Control Towerのコンソール画面、ランディングゾーン設定からアップデートをしていきます。

バージョン3.2の説明文は以下です。

Update to show drift in the console for controls that are part of the Security Hub Service-Managed Standard: AWS Control Tower. Includes a new service-linked role that permits drift to be monitored in customer accounts, based on a new managed rule created with EventBridge. Updates the Region Deny control.

コンソール上で指定できる新規の設定項目はないため、そのまま更新します。

今回は実施しませんでしたが、ランディングゾーンのバージョンアップ後には必要に応じてOU(組織単位)やアカウントの再登録等でOU、アカウント単位でのランディングゾーンバージョンの更新を行なってください。

現在のバージョンが3.2に変わっています。これで更新完了です。

Security Hubの『サービスマネージド標準: AWS Control Tower』のドリフト検出機能

今回追加されたドリフト検出機能についてはこちらのドキュメントに概要が書かれています。あわせてご覧ください。

Security Hub standard - AWS Control Tower

それでは検証に戻ります。

事前準備

まずは検証にかかる事前の準備を行います。

Control Tower管理アカウントの、Control Towerのマネジメントコンソールでサービスマネージド標準のコントロールを検索します。コントロールオーナーにSecurity Hub、サービスに検索したいサービス(今回はAmazon S3)を指定すると絞りやすいです。

今回は[SH.S3.1] S3 ブロックパブリックアクセス設定を有効にする必要がありますを選択しました。

OUを指定して、そのまま有効化しようとすると以下のようなポップアップが表示されます。主に『サービスマネージド標準: AWS Control Tower』が有効化されてしまう点に関する注意書きが書かれていますね。確認を押すと有効化されます。

有効化できました。

メンバーアカウント側から確認してみると、Security Hubのセキュリティ標準に追加されていること、リソースが1件検知していることが確認できます。

ドリフトの発生

準備ができたので、このコントロールを無効化します。コントロールの無効化によってドリフトが発生することを期待しています。

無効化後、24時間ほど時間を空けるとControl TowerのSNSトピックからこのようなメールが配信されました。こちらのドキュメントにある内容と同様の通知のようです。

Control Towerコンソールの組織タブからアカウントのステータスを確認すると、ドリフト(コントロールドリフト)と表示されています。コントロールの無効化を検知できました!

ドリフトの修復

ここではドリフトの修復を行い、ドリフトの解消および原因となるコントロールの無効化が修正されることを確認します。

ドリフトを修復するために、OUの再登録またはコントロールの無効化/再有効化(一旦非アクティブにしてもう1回アクティブ化する)が必要です。

今回はOUの再登録でドリフトを修復します。ドリフトが発生しているアカウントの組織単位でOUを再登録します。

ステータスは「準拠」と表示されていますが、コンソールに以下のように表記されている通り、この「準拠」はサービスマネージド標準の状態を表すものではないそうです。

AWS Security Hub が所有するコントロールについては、コンプライアンスステータスは不明です。これらは AWS Control Tower のアカウントと OU のコンプライアンスステータスには集計されません。

「このOUで適用されるコントロール」にドリフト検出していた原因のコントロールが含められていることが確認できます。再登録には2時間ほどかかると表示されています。再登録していきましょう。

しばらく待って(30分以内に終わっていました)、再登録完了するとドリフトが解消され、OUでの制御状態が有効になっています。

修復直後に確認すると、まだコントロールステータスは無効化のままでした。ステータスの切り替えで利用するボタンはコントロールの無効化になっていたので内部的には有効化に切り替わっていそうです。

今回対象としたS3.1のコントロールが対象とするリソースがアカウントのみで、既にこのアカウントに対して検知したFindingsは抑制済みのステータスになっていたためこのような表示になっていたと想定しています。

修復の翌日には、コントロールステータスも無効化ではなくなっていました(データなし)

自動修復が正しく行われていることが確認できました。

リージョン拒否コントロールのアップデート

リージョン拒否コントロールの内容について、Control Towerのコンソール上でも確認できますが、後述する注意点に記載するようにControl Towerのコンソールでは正しい内容が確認できない場合があります。

代わりに、コントロールを実装している実質的なリソースであるOrganizationsのSCPを確認します。

SCPで実装されるControl Towerコントロールは、aws-guardrails-ランダム文字列という規則性のある命名規則で設定されるため、名前だけでは中身が判別できません。

リージョン拒否コントロールは、SidがGRREGIONDENY、ポリシーの中身が様々なアクションをDenyしているものなので、判別できるはずです。

この章の本題はここからになります。結論から申し上げますと、バージョン3.2のリージョン拒否コントロールでは、3.1と比較して以下のような差分がありました。

  • 追加されたアクション
    • billing:*
    • cloudtrail:LookupEvents
    • consoleapp:*
    • consolidatedbilling:*
    • freetier:*
    • invoicing:*
    • iq:*
    • notifications-contacts:*
    • notifications:*
    • payments:*
    • tax:*
  • 削除されたアクション
    • s3:GetAccountPublic
    • s3:PutAccountPublic

billing、freetierなどの請求に関連していそうなポリシーが拒否対象に追加され、S3の操作に関するポリシーが対象から削除されています。S3に関するポリシーはバージョン3.0ごろで追加されたポリシーが含まれているようです。

検証で確認できたそれぞれの具体的なポリシードキュメントは、こちらに記載しておきます。

見たい方はトグルを開いてください
■バージョン3.1のリージョン拒否コントロールポリシードキュメント

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Condition": {
        "StringNotEquals": {
          "aws:RequestedRegion": [
            "ap-northeast-1",
            "us-east-1"
          ]
        },
        "ArnNotLike": {
          "aws:PrincipalARN": [
            "arn:aws:iam::*:role/AWSControlTowerExecution"
          ]
        }
      },
      "Resource": "*",
      "Effect": "Deny",
      "NotAction": [
        "a4b:*",
        "access-analyzer:*",
        "acm:*",
        "account:*",
        "activate:*",
        "artifact:*",
        "aws-marketplace-management:*",
        "aws-marketplace:*",
        "aws-portal:*",
        "billingconductor:*",
        "budgets:*",
        "ce:*",
        "chatbot:*",
        "chime:*",
        "cloudfront:*",
        "compute-optimizer:*",
        "config:*",
        "cur:*",
        "datapipeline:GetAccountLimits",
        "devicefarm:*",
        "directconnect:*",
        "discovery-marketplace:*",
        "ec2:DescribeRegions",
        "ec2:DescribeTransitGateways",
        "ec2:DescribeVpnGateways",
        "ecr-public:*",
        "fms:*",
        "globalaccelerator:*",
        "health:*",
        "iam:*",
        "importexport:*",
        "kms:*",
        "license-manager:ListReceivedLicenses",
        "lightsail:Get*",
        "mobileanalytics:*",
        "networkmanager:*",
        "organizations:*",
        "pricing:*",
        "resource-explorer-2:*",
        "route53-recovery-cluster:*",
        "route53-recovery-control-config:*",
        "route53-recovery-readiness:*",
        "route53:*",
        "route53domains:*",
        "s3:CreateMultiRegionAccessPoint",
        "s3:DeleteMultiRegionAccessPoint",
        "s3:DescribeMultiRegionAccessPointOperation",
        "s3:GetAccountPublic",
        "s3:GetAccountPublicAccessBlock",
        "s3:GetBucketLocation",
        "s3:GetBucketPolicyStatus",
        "s3:GetBucketPublicAccessBlock",
        "s3:GetMultiRegionAccessPoint",
        "s3:GetMultiRegionAccessPointPolicy",
        "s3:GetMultiRegionAccessPointPolicyStatus",
        "s3:GetStorageLensConfiguration",
        "s3:GetStorageLensDashboard",
        "s3:ListAllMyBuckets",
        "s3:ListMultiRegionAccessPoints",
        "s3:ListStorageLensConfigurations",
        "s3:PutAccountPublic",
        "s3:PutAccountPublicAccessBlock",
        "s3:PutMultiRegionAccessPointPolicy",
        "savingsplans:*",
        "shield:*",
        "sso:*",
        "sts:*",
        "support:*",
        "supportapp:*",
        "supportplans:*",
        "sustainability:*",
        "tag:GetResources",
        "trustedadvisor:*",
        "vendor-insights:ListEntitledSecurityProfiles",
        "waf-regional:*",
        "waf:*",
        "wafv2:*"
      ],
      "Sid": "GRREGIONDENY"
    }
  ]
}

■バージョン3.2のリージョン拒否コントロールポリシードキュメント

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Condition": {
        "StringNotEquals": {
          "aws:RequestedRegion": [
            "ap-northeast-1",
            "us-east-1"
          ]
        },
        "ArnNotLike": {
          "aws:PrincipalARN": [
            "arn:aws:iam::*:role/AWSControlTowerExecution"
          ]
        }
      },
      "Resource": "*",
      "Effect": "Deny",
      "NotAction": [
        "a4b:*",
        "access-analyzer:*",
        "account:*",
        "acm:*",
        "activate:*",
        "artifact:*",
        "aws-marketplace-management:*",
        "aws-marketplace:*",
        "aws-portal:*",
        "billing:*",
        "billingconductor:*",
        "budgets:*",
        "ce:*",
        "chatbot:*",
        "chime:*",
        "cloudfront:*",
        "cloudtrail:LookupEvents",
        "compute-optimizer:*",
        "config:*",
        "consoleapp:*",
        "consolidatedbilling:*",
        "cur:*",
        "datapipeline:GetAccountLimits",
        "devicefarm:*",
        "directconnect:*",
        "discovery-marketplace:*",
        "ec2:DescribeRegions",
        "ec2:DescribeTransitGateways",
        "ec2:DescribeVpnGateways",
        "ecr-public:*",
        "fms:*",
        "freetier:*",
        "globalaccelerator:*",
        "health:*",
        "iam:*",
        "importexport:*",
        "invoicing:*",
        "iq:*",
        "kms:*",
        "license-manager:ListReceivedLicenses",
        "lightsail:Get*",
        "mobileanalytics:*",
        "networkmanager:*",
        "notifications-contacts:*",
        "notifications:*",
        "organizations:*",
        "payments:*",
        "pricing:*",
        "resource-explorer-2:*",
        "route53-recovery-cluster:*",
        "route53-recovery-control-config:*",
        "route53-recovery-readiness:*",
        "route53:*",
        "route53domains:*",
        "s3:CreateMultiRegionAccessPoint",
        "s3:DeleteMultiRegionAccessPoint",
        "s3:DescribeMultiRegionAccessPointOperation",
        "s3:GetAccountPublicAccessBlock",
        "s3:GetBucketLocation",
        "s3:GetBucketPolicyStatus",
        "s3:GetBucketPublicAccessBlock",
        "s3:GetMultiRegionAccessPoint",
        "s3:GetMultiRegionAccessPointPolicy",
        "s3:GetMultiRegionAccessPointPolicyStatus",
        "s3:GetStorageLensConfiguration",
        "s3:GetStorageLensDashboard",
        "s3:ListAllMyBuckets",
        "s3:ListMultiRegionAccessPoints",
        "s3:ListStorageLensConfigurations",
        "s3:PutAccountPublicAccessBlock",
        "s3:PutMultiRegionAccessPointPolicy",
        "savingsplans:*",
        "shield:*",
        "sso:*",
        "sts:*",
        "support:*",
        "supportapp:*",
        "supportplans:*",
        "sustainability:*",
        "tag:GetResources",
        "tax:*",
        "trustedadvisor:*",
        "vendor-insights:ListEntitledSecurityProfiles",
        "waf-regional:*",
        "waf:*",
        "wafv2:*"
      ],
      "Sid": "GRREGIONDENY"
    }
  ]
}

リージョン拒否コントロールのポリシードキュメントについては、以下AWS公式ドキュメント上からも確認できます。

Controls that enhance data residency protection - AWS Control Tower

リージョン拒否コントロールの注意点について(2023/6/29現在)

前述したように、リージョン拒否コントロールはControl Towerのコンソール上からコントロールのポリシードキュメントをJSON形式で確認できます。

しかし、以前からコンソール上に表示されるポリシードキュメントが誤った内容が表示されるというバグが確認できています。ランディングゾーンのアップデートを行なっていない状態なのにもかかわらず、リージョン拒否コントロールのポリシードキュメントの内容は最新バージョンの内容が記載されている、というものです。

バージョン3.1がリリースされた際、バージョン3.0なのに3.1の内容が表示されてしまう事象を確認したのでサポートに確認したところ、これは既知の表示上の誤りで実際の設定は想定通りの内容が適用されているとのことでした。確かにSCP側では本来の設定が確認できました。

今回の3.2のリリース時の現在でも同じ事象が確認できているので、まだ解消されていないようです。リージョン拒否コントロールの内容を確認したい場合、今回の検証で行ったようにリージョン拒否コントロールを実装している元のリソースであるOrganizationsのSCPの情報を確認するようにしてください。

最後に

新たにリリースされたControl Towerランディングゾーンのバージョン3.2について、確認・検証してみました。

Security Hubのサービスマネージド標準については、個人的にはまだ活用するに至っていませんが、このようなアップデートがあるとSecurity Hubもまとめて管理していくぞというControl Towerのサービス開発側の気概が感じられますね。

既知のリージョン拒否コントロールの表示上バグが解消されていないなど、いくつか最新の状況を確認できたので個人的に検証を行なっておいてよかったです。SCP側を確認するという回避策はありますが、確認するの際はご注意ください。

以上、芦沢(@ashi_ssan)でした。