ES.2
概要
ES.2 は、Elasticsearch ドメインが VPC アクセス方式で作成されているかをチェックする Security Hub CSPM コントロールである。対応する Config ルールは elasticsearch-in-vpc-only。対象リソースタイプは AWS::Elasticsearch::Domain。
同等のコントロールに Opensearch.2 があり、こちらは AWS::OpenSearchService::Domain を対象とする。AWS は 2021 年に Amazon Elasticsearch Service を Amazon OpenSearch Service にリネームした。リネーム以前から存在するレガシードメインは AWS::Elasticsearch::Domain リソースタイプのまま残り、新規作成するドメインは AWS::OpenSearchService::Domain リソースタイプになる。そのため、Security Hub では両方のリソースタイプ別に検出コントロールが用意されている。
本記事では、レガシー Elasticsearch ドメイン(Elasticsearch 7.10)を使って ES.2 を実機検証する。
検出範囲
ES.2 は「Elasticsearch ドメインが VPC アクセス方式で作成されているか」のみをチェックする。パブリックエンドポイント方式で作成された場合に FAILED、VPC アクセス方式で作成された場合に PASSED となる。
Elasticsearch(および OpenSearch)ドメインの「アクセス方式」は作成時に選択する。作成後にパブリック方式 ↔ VPC 方式を切り替えることはできない(VPC 内でのサブネットやセキュリティグループの変更は可能)。
- パブリックエンドポイント方式: AWS 管理のパブリックエンドポイント(
https://search-<ドメイン>.us-east-1.es.amazonaws.com形式)が払い出され、インターネットから到達可能。アクセス制御はドメインアクセスポリシー(JSON)で行う。 - VPC アクセス方式: 指定した VPC のサブネットに ENI が作られ、パブリックエンドポイントは払い出されない。インターネットからは到達不可(VPC 内・VPC ピアリング・VPN・Direct Connect 経由のみ)。アクセス制御はセキュリティグループ + ドメインアクセスポリシー。
| ドメイン設定 | ES.2 |
|---|---|
| パブリックエンドポイント方式(VPC 設定なし) | FAILED |
| VPC アクセス方式(VPC 設定あり) | PASSED |
VPCOptions 属性の有無のみを評価する。VPC 内に配置されていれば PASSED となるが、ENI を配置したサブネットがパブリックサブネット(IGW へのルートを持つ)かプライベートサブネットかは評価しない。これは利用者の責任でプライベートサブネットを選ぶ必要がある。本記事のステップ 5 では、デフォルト VPC のパブリックサブネットに配置しても PASSED になることを実証し、この境界を明示する。外部アクセス制御レイヤー
Elasticsearch ドメインの外部アクセスに関わるコントロールは以下の通り。ES.2 は CSPM による検出レイヤーに位置する。
| レイヤー | コントロール | 役割 |
|---|---|---|
| デフォルト保護 | なし | ドメイン作成時に VPC 設定を選択しなければパブリックエンドポイントで作成される |
| 予防(SCP / RCP / 宣言型ポリシー) | なし | API 呼び出し自体をブロックする予防コントロールは存在しない |
| プロアクティブ(Proactive、CFn Hooks)※ | CT.OPENSEARCH.PR.2 | CloudFormation で Elasticsearch ドメインを作成する際、VPCOptions.SubnetIds が指定されていることを要求 |
| 検出(CSPM) | ES.2(本記事) | Elasticsearch ドメインが VPC アクセス方式で作成されているかチェック |
| 検出(CSPM) | Opensearch.2 | OpenSearch ドメインが VPC アクセス方式で作成されているかチェック |
※ 本サイトでは原則としてプロアクティブコントロールは検証対象外。ES.2 / Opensearch.2 では予防(SCP / RCP / 宣言型ポリシー)が存在しないため、唯一の予防的選択肢として例外的に言及する。詳細は プロアクティブコントロールを検証対象外とする理由 を参照。
本記事で確認すること
| # | 検証観点 | 状態 |
|---|---|---|
| 1 | パブリックエンドポイント方式の Elasticsearch ドメインで ES.2 が FAILED | 本記事で検証(2. パブリックドメインで ES.2 FAILED を確認) |
| 2 | VPC アクセス方式(パブリックサブネット配置)の Elasticsearch ドメインで ES.2 が PASSED | 本記事で検証(5. VPC ドメインで ES.2 PASSED を確認) |
検証観点が 2 つだけなのは、ES.2 の判定軸が「VPC 設定の有無」のみで、かつドメイン作成後にアクセス方式を切り替えられないため、2 つのドメインを別々に作成・評価する必要があるから。
結果
- パブリックエンドポイント方式:
--vpc-optionsを指定せずに Elasticsearch ドメインを作成すると、パブリックエンドポイントが払い出され、ES.2 は FAILED - VPC アクセス方式(パブリックサブネット配置):
--vpc-optionsを指定して作成すると、VPC 内に ENI が作られ、ES.2 は PASSED。ENI を配置したサブネットがパブリックサブネットであっても、ES.2 は VPC 設定の有無のみを見るため PASSED となる
検証環境
本記事のコマンドは、--profile 指定がない場合は Workload アカウントで実行する。事前に export AWS_PROFILE=Workload でデフォルトを設定しておくと便利。
共通の前提:デフォルト VPC のパブリックサブネットを使用する
本記事の検証では、ステップ 4 の VPC ドメインをデフォルト VPC のパブリックサブネット(IGW への 0.0.0.0/0 ルートを持つ)に配置する。これは「ES.2 はサブネットのルーティング設定を評価せず、VPCOptions の有無のみで判定している」ことを実証するため。
検証開始前に、使用するサブネットがパブリックサブネットであることを確認する。
aws ec2 describe-subnets \
--filters Name=default-for-az,Values=true \
--query 'Subnets[0].{SubnetId:SubnetId,VpcId:VpcId,AZ:AvailabilityZone}' \
--region ap-northeast-1{
"SubnetId": "<パブリックサブネット ID>",
"VpcId": "<デフォルト VPC ID>",
"AZ": "ap-northeast-1a"
}aws ec2 describe-route-tables \
--filters "Name=vpc-id,Values=<デフォルト VPC ID>" "Name=association.main,Values=true" \
--query 'RouteTables[].Routes[].{Destination:DestinationCidrBlock,Gateway:GatewayId}' \
--region ap-northeast-1[
{"Destination": "172.31.0.0/16", "Gateway": "local"},
{"Destination": "0.0.0.0/0", "Gateway": "<IGW ID>"}
]デフォルト VPC のメインルートテーブルは 0.0.0.0/0 → IGW のルートを持つため、デフォルトサブネットはパブリックサブネットである。
また、デフォルト SG ID を取得する(ステップ 4 で使用する)。
aws ec2 describe-security-groups \
--filters Name=vpc-id,Values=<デフォルト VPC ID> Name=group-name,Values=default \
--query 'SecurityGroups[0].GroupId' --output text \
--region ap-northeast-1<デフォルト SG ID>検証の流れ
flowchart LR
A[1. パブリックドメイン<br>作成] --> B[2. ES.2 FAILED<br>確認]
B --> C[3. パブリックドメイン<br>削除]
C --> D[4. VPC ドメイン<br>作成]
D --> E[5. ES.2 PASSED<br>確認]
E --> F[6. クリーンアップ]
1. パブリックドメインの作成
--vpc-options を指定せずに Elasticsearch ドメインを作成する。これによりパブリックエンドポイントが払い出される。
Elasticsearch 7.10 を使用する(AWS が作成を許可している最新の Elasticsearch バージョン。これより新しいバージョンは OpenSearch となる)。
aws es create-elasticsearch-domain \
--domain-name es-2-public-test \
--elasticsearch-version 7.10 \
--elasticsearch-cluster-config 'InstanceType=t3.small.elasticsearch,InstanceCount=1' \
--ebs-options 'EBSEnabled=true,VolumeType=gp3,VolumeSize=10' \
--access-policies '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::<アカウント ID>:root"},"Action":"es:*","Resource":"arn:aws:es:ap-northeast-1:<アカウント ID>:domain/es-2-public-test/*"}]}' \
--query 'DomainStatus.{DomainName:DomainName,Created:Created,Processing:Processing}' \
--region ap-northeast-1{
"DomainName": "es-2-public-test",
"Created": true,
"Processing": true
}ドメイン作成完了まで 15〜25 分程度かかる。Processing: false になるまで待つ。
aws es describe-elasticsearch-domain \
--domain-name es-2-public-test \
--query 'DomainStatus.{Processing:Processing,Endpoint:Endpoint,VPCOptions:VPCOptions}' \
--region ap-northeast-1{
"Processing": false,
"Endpoint": "search-es-2-public-test-<ハッシュ>.ap-northeast-1.es.amazonaws.com",
"VPCOptions": null
}Endpoint がパブリックエンドポイント、VPCOptions が null であることを確認する。
2. パブリックドメインで ES.2 FAILED を確認
Config リソース発見の確認
aws configservice list-discovered-resources \
--resource-type AWS::Elasticsearch::Domain \
--query 'resourceIdentifiers[?resourceName==`es-2-public-test`]' \
--region ap-northeast-1[
{
"resourceType": "AWS::Elasticsearch::Domain",
"resourceId": "<ドメイン ID>",
"resourceName": "es-2-public-test"
}
]Config に発見されるまで数分のラグがある場合は、数分待って再実行する。
Config ルール手動トリガー
aws configservice start-config-rules-evaluation \
--config-rule-names securityhub-elasticsearch-in-vpc-only-<サフィックス> \
--region ap-northeast-1
(出力なし)1〜2 分待ってから評価結果を確認する。
Config の評価結果確認
aws configservice get-compliance-details-by-config-rule \
--config-rule-name securityhub-elasticsearch-in-vpc-only-<サフィックス> \
--query 'EvaluationResults[?EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId==`<ドメイン ID>`].{ResourceId:EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId,ComplianceType:ComplianceType,ResultRecordedTime:ResultRecordedTime}' \
--region ap-northeast-1[
{
"ResourceId": "<ドメイン ID>",
"ComplianceType": "NON_COMPLIANT",
"ResultRecordedTime": "<評価時刻>"
}
]Security Hub finding 確認
Config の評価結果が Security Hub に反映されるまで 2〜3 分のラグがある。数分待ってから確認する。
aws securityhub get-findings \
--filters '{
"ComplianceSecurityControlId": [{"Comparison": "EQUALS", "Value": "ES.2"}],
"AwsAccountId": [{"Comparison": "EQUALS", "Value": "<アカウント ID>"}],
"ResourceId": [{"Comparison": "EQUALS", "Value": "arn:aws:es:ap-northeast-1:<アカウント ID>:domain/es-2-public-test"}],
"RecordState": [{"Comparison": "EQUALS", "Value": "ACTIVE"}]
}' \
--query 'Findings[].{Status:Compliance.Status,ResourceId:Resources[0].Id,UpdatedAt:UpdatedAt}' \
--region ap-northeast-1[
{
"Status": "FAILED",
"ResourceId": "arn:aws:es:ap-northeast-1:<アカウント ID>:domain/es-2-public-test",
"UpdatedAt": "<更新時刻>"
}
]3. パブリックドメインの削除
aws es delete-elasticsearch-domain \
--domain-name es-2-public-test \
--region ap-northeast-1{
"DomainStatus": {
"DomainName": "es-2-public-test",
"Deleted": true,
"Processing": true
}
}削除完了まで 10〜20 分程度かかる。次のステップ(VPC ドメイン作成)は削除完了を待たずに開始してよい。
4. VPC ドメインの作成
--vpc-options を指定して Elasticsearch ドメインを作成する。ENI を配置するサブネットは、共通の前提で確認済みの デフォルト VPC のパブリックサブネット(IGW へのルートを持つ)を使用する。これは「ES.2 はサブネットのルーティング設定を評価しない」ことを実証するため。
aws es create-elasticsearch-domain \
--domain-name es-2-vpc-test \
--elasticsearch-version 7.10 \
--elasticsearch-cluster-config 'InstanceType=t3.small.elasticsearch,InstanceCount=1' \
--ebs-options 'EBSEnabled=true,VolumeType=gp3,VolumeSize=10' \
--vpc-options "SubnetIds=<パブリックサブネット ID>,SecurityGroupIds=<デフォルト SG ID>" \
--access-policies '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::<アカウント ID>:root"},"Action":"es:*","Resource":"arn:aws:es:ap-northeast-1:<アカウント ID>:domain/es-2-vpc-test/*"}]}' \
--query 'DomainStatus.{DomainName:DomainName,Created:Created,Processing:Processing}' \
--region ap-northeast-1{
"DomainName": "es-2-vpc-test",
"Created": true,
"Processing": true
}ドメイン作成完了まで 15〜25 分程度かかる。Processing: false になるまで待つ。
aws es describe-elasticsearch-domain \
--domain-name es-2-vpc-test \
--query 'DomainStatus.{Processing:Processing,Endpoint:Endpoint,VPCOptions:VPCOptions}' \
--region ap-northeast-1{
"Processing": false,
"Endpoint": null,
"VPCOptions": {
"VPCId": "<デフォルト VPC ID>",
"SubnetIds": ["<パブリックサブネット ID>"],
"AvailabilityZones": ["ap-northeast-1a"],
"SecurityGroupIds": ["<デフォルト SG ID>"]
}
}Endpoint が null、VPCOptions が設定されていることを確認する。
5. VPC ドメインで ES.2 PASSED を確認
Config リソース発見の確認
aws configservice list-discovered-resources \
--resource-type AWS::Elasticsearch::Domain \
--query 'resourceIdentifiers[?resourceName==`es-2-vpc-test`]' \
--region ap-northeast-1[
{
"resourceType": "AWS::Elasticsearch::Domain",
"resourceId": "<ドメイン ID>",
"resourceName": "es-2-vpc-test"
}
]Config ルール手動トリガー
aws configservice start-config-rules-evaluation \
--config-rule-names securityhub-elasticsearch-in-vpc-only-<サフィックス> \
--region ap-northeast-1
(出力なし)1〜2 分待ってから評価結果を確認する。
Config の評価結果確認
aws configservice get-compliance-details-by-config-rule \
--config-rule-name securityhub-elasticsearch-in-vpc-only-<サフィックス> \
--query 'EvaluationResults[?EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId==`<ドメイン ID>`].{ResourceId:EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId,ComplianceType:ComplianceType,ResultRecordedTime:ResultRecordedTime}' \
--region ap-northeast-1[
{
"ResourceId": "<ドメイン ID>",
"ComplianceType": "COMPLIANT",
"ResultRecordedTime": "<評価時刻>"
}
]Security Hub finding 確認
aws securityhub get-findings \
--filters '{
"ComplianceSecurityControlId": [{"Comparison": "EQUALS", "Value": "ES.2"}],
"AwsAccountId": [{"Comparison": "EQUALS", "Value": "<アカウント ID>"}],
"ResourceId": [{"Comparison": "EQUALS", "Value": "arn:aws:es:ap-northeast-1:<アカウント ID>:domain/es-2-vpc-test"}],
"RecordState": [{"Comparison": "EQUALS", "Value": "ACTIVE"}]
}' \
--query 'Findings[].{Status:Compliance.Status,ResourceId:Resources[0].Id,UpdatedAt:UpdatedAt}' \
--region ap-northeast-1[
{
"Status": "PASSED",
"ResourceId": "arn:aws:es:ap-northeast-1:<アカウント ID>:domain/es-2-vpc-test",
"UpdatedAt": "<更新時刻>"
}
]パブリックサブネットに ENI を配置しても ES.2 は PASSED となることを確認する。これは ES.2 がサブネットのルーティング設定を評価せず、VPCOptions の有無のみで判定していることを示す。
6. クリーンアップ
VPC ドメイン削除
aws es delete-elasticsearch-domain \
--domain-name es-2-vpc-test \
--region ap-northeast-1削除完了まで 10〜20 分程度かかる。