EMR.2
概要
EMR.2 は、アカウントの Amazon EMR Block Public Access(BPA) 設定が有効になっているかをチェックする Security Hub CSPM コントロールである。対応する Config ルールは emr-block-public-access。対象リソースタイプは AWS::::Account(アカウント単位のコントロール)。
Amazon EMR(Elastic MapReduce)は Apache Hadoop、Apache Spark、Presto などの分散処理フレームワークを EC2 クラスター上で動かすマネージドサービスである。EMR クラスターは 顧客が作成した VPC 内(顧客管理のパブリックサブネットまたはプライベートサブネット)に EC2 インスタンス群として起動され、通信はセキュリティグループで制御される。このセキュリティグループも顧客管理で、クラスター作成時に顧客が指定または作成する。
EMR BPA は、この顧客管理のセキュリティグループのインバウンドルールを EMR サービス自身が検査する機構である(AWS 公式ドキュメント 参照)。BPA が有効な状態で顧客管理の VPC のパブリックサブネットに EMR クラスターを作成しようとした際、0.0.0.0/0 や ::/0 から PermittedPublicSecurityGroupRuleRanges に設定された例外ポート以外を許可するインバウンドルールがセキュリティグループに含まれる場合、EMR はクラスターの起動を拒否する。また、既存クラスターのセキュリティグループにそのようなルールが追加された場合、EMR はそのルールを取り消すか(EMR サービスロールに ec2:RevokeSecurityGroupIngress 権限がある場合)、AWS Health ダッシュボードに違反イベントを生成する。プライベートサブネット内のクラスターには BPA は適用されない(IGW への経路がなくパブリック到達性がないため)。
つまり BPA は「セキュリティグループを動的にフィルタする仕組み」ではなく、「EMR サービスがクラスター起動時/セキュリティグループ変更時にルールを検査し、違反していれば起動拒否またはルール取り消しを行う制御機構」である。本記事では、EMR クラスターを一切起動せず、アカウントレベルの BPA 設定値(BlockPublicSecurityGroupRules と PermittedPublicSecurityGroupRuleRanges)を変更したときに Config ルール emr-block-public-access と Security Hub の EMR.2 がどう評価するかのみを検証する(課金リソースは発生しない)。Config ルールはアカウント設定のみを評価するため、サブネット設定(IGW の有無など)やセキュリティグループのルールは EMR.2 の評価結果に影響しない。したがって、BPA 有効時に実際にクラスター起動が拒否される動作や SG ルールが取り消される動作は、本記事のスコープ外である。
検出範囲
EMR.2 は「アカウントの EMR BPA 設定が、顧客管理のセキュリティグループの公開ルールを検査する状態になっているか」をチェックする。
Config ルール emr-block-public-access の公式仕様 は以下のように定義されている:
The rule is NON_COMPLIANT if BlockPublicSecurityGroupRules is false, or if true, ports other than Port 22 are listed in PermittedPublicSecurityGroupRuleRanges.
つまり FAILED になる条件は 2 つ:
BlockPublicSecurityGroupRules: false(BPA 無効)BlockPublicSecurityGroupRules: trueだが、port 22 以外の例外ポートがPermittedPublicSecurityGroupRuleRangesに含まれる
| BPA 設定 | 例外ポート | EMR.2 |
|---|---|---|
BlockPublicSecurityGroupRules: true | port 22 のみ(デフォルト) | PASSED |
BlockPublicSecurityGroupRules: true | port 22 + 他のポート(例: 8080) | FAILED |
BlockPublicSecurityGroupRules: false | (問わない) | FAILED |
port 22 が例外として許可されているのは、SSH 接続による EMR クラスター管理のため。それ以外の公開ポートを例外として許可すると EMR.2 は FAILED となる。
ResourceId 形式(SSM.7 と同じパターン): Config(AWS::::Account リソース)の ResourceId はアカウント ID そのまま(例: 250544872868)、Security Hub finding の ResourceId は AWS::::Account:<アカウント ID> 形式(例: AWS::::Account:250544872868)。put-block-public-access-configuration の変更は設定変更イベントとして Config に直接通知されるわけではない。手動トリガー(start-config-rules-evaluation)で即座に評価を促すことができる。外部アクセス制御レイヤー
EMR クラスターの外部アクセスに関わるコントロールは以下の通り。EMR.2 は CSPM によるアカウント単位の検出レイヤーに位置する。
| レイヤー | コントロール | 役割 |
|---|---|---|
| デフォルト保護 | EMR BPA のデフォルト有効(BlockPublicSecurityGroupRules: true、例外 port 22) | 新規 AWS アカウントで EMR BPA が初期状態で有効になっている(動作の詳細は後述の「EMR のサービス機能」行を参照) |
| 予防(SCP / RCP / 宣言型ポリシー) | なし | Control Tower の標準予防コントロールに EMR BPA 設定を強制するものは存在しない。カスタム SCP で emr:PutBlockPublicAccessConfiguration を Deny する運用は可能(ただし全 Deny すると有効化への変更もできなくなるため、条件付き Deny が必要) |
| EMR のサービス機能(BPA) | put-block-public-access-configuration で設定 | BPA 有効時、0.0.0.0/0(::/0)から例外ポート以外を許可するセキュリティグループを持つ EMR クラスターの起動を EMR サービスが拒否。既存クラスターの SG 変更時は違反ルールを取り消すか Health ダッシュボードに通知 |
| 検出(CSPM、アカウント単位) | EMR.2(本記事) | アカウントの BPA 設定が有効かつ port 22 以外の例外がないかチェック |
デフォルト値について: AWS 公式ドキュメント には「Block public access is enabled by default for all clusters in every AWS Region for your AWS account」と明記されており、EMR BPA はデフォルトで 有効 である。本手順書作成にあたり、事前確認として 3 アカウント(組織管理アカウント、組織配下の Workload アカウント、組織外アカウント)で get-block-public-access-configuration を実行したところ、すべてで BlockPublicSecurityGroupRules: true、PermittedPublicSecurityGroupRuleRanges: [port 22]、BlockPublicAccessConfigurationMetadata.CreationDateTime が Unix エポック近辺の値、CreatedByArn: ""(ユーザー変更なし)だった。公式ドキュメントの記述通り、新規アカウントで EMR.2 は初期状態で PASSED。
なお、AWS 公式ドキュメント によれば「2019 年 11 月 25 日以前にそのリージョンで EMR クラスターを作成したアカウントでは、該当リージョンで BPA はデフォルト無効」という例外がある。古いアカウントを検証する場合はこの点に注意すること。
本記事で確認すること
| # | 検証観点 | 状態 |
|---|---|---|
| 1 | デフォルト状態(BPA 有効 + port 22 例外のみ)で EMR.2 が PASSED | 本記事で検証(1. 現状確認 & 2. デフォルト状態の PASSED 確認) |
| 2 | BPA を無効化(BlockPublicSecurityGroupRules: false)すると EMR.2 が FAILED | 本記事で検証(3. BPA 無効化 & 4. BPA 無効化後の FAILED 確認) |
| 3 | BPA を有効化し戻す(port 22 例外のみ)と EMR.2 が PASSED に復帰 | 本記事で検証(5. BPA 有効化し戻す & 6. BPA 有効化後の PASSED 確認) |
| 4 | BPA 有効のまま、例外に port 22 以外(例: 8080)を追加すると EMR.2 が FAILED | 本記事で検証(7. 例外に port 8080 を追加 & 8. 例外追加後の FAILED 確認) |
| 5 | 例外を port 22 のみに戻すと EMR.2 が PASSED に復帰 | 本記事で検証(9. 例外を元に戻す & 10. 例外を戻した後の PASSED 確認) |
結果
- デフォルト(BPA 有効 + 例外 port 22): EMR.2 は PASSED
- BPA 無効化(
BlockPublicSecurityGroupRules: false): EMR.2 は FAILED - BPA 有効化し戻す(例外 port 22 のみ): EMR.2 は PASSED に復帰
- BPA 有効のまま、例外に port 22 以外(port 8080)を追加: EMR.2 は FAILED(EMR.2 特有の 2 つ目の FAILED 条件を実機で確認)
- 例外を port 22 のみに戻す: EMR.2 は PASSED に復帰
- 反映時間(実測): Config 手動トリガー(
start-config-rules-evaluation)から評価結果記録(ResultRecordedTime)まで約 3〜10 秒、Security Hub finding 反映(UpdatedAt)までさらに約 10〜15 秒。手順書では安全マージンとしてsleep 90(Config 評価待ち)とsleep 120(Security Hub 反映待ち)を入れているが、実測では合計 30 秒程度で遷移が完了する - 副次的な発見:
put-block-public-access-configurationを一度でも実行すると、BlockPublicAccessConfigurationMetadata.CreatedByArnとCreationDateTimeに実行痕跡が残る(検証前の AWS デフォルト値""と Unix エポック近辺の時刻には戻らないが、BlockPublicAccessConfigurationの内容が同じであれば実運用上は問題なし)
検証環境
本記事のコマンドは、--profile 指定がない場合は Workload アカウントで実行する。事前に export AWS_PROFILE=Workload でデフォルトを設定しておくと便利。
検証の流れ
flowchart LR
A[1. 現状確認] --> B[2. PASSED 確認]
B --> C[3. BPA 無効化]
C --> D[4. FAILED 確認]
D --> E[5. BPA 有効化し戻す]
E --> F[6. PASSED 確認]
F --> G[7. 例外に port 8080 追加]
G --> H[8. FAILED 確認]
H --> I[9. 例外を元に戻す]
I --> J[10. PASSED 確認]
BlockPublicSecurityGroupRules: true + 例外 port 22 のみ(デフォルト)の前提で進め、最後にその状態に戻す。検証前に意図的に BPA を無効化していたり例外ポートを追加していた環境であれば、検証終了後に元の状態に戻す必要がある。検証開始前の設定を記録しておくこと。1. 現状確認(デフォルト)
EMR BPA の現状を確認する。
aws emr get-block-public-access-configuration \
--region ap-northeast-1{
"BlockPublicAccessConfiguration": {
"BlockPublicSecurityGroupRules": true,
"PermittedPublicSecurityGroupRuleRanges": [
{
"MinRange": 22,
"MaxRange": 22
}
]
},
"BlockPublicAccessConfigurationMetadata": {
"CreationDateTime": "<日時>",
"CreatedByArn": ""
}
}BlockPublicSecurityGroupRules: true かつ PermittedPublicSecurityGroupRuleRanges が port 22 のみの状態であることを確認する。CreatedByArn: "" は AWS 側が初期化したデフォルト値である証拠(ユーザー変更なし)。
BlockPublicSecurityGroupRules: false や port 22 以外の例外が含まれる場合: 意図的にカスタマイズされている可能性がある。検証前の状態を記録しておき、検証後に元に戻すこと。2. デフォルト状態の PASSED 確認
Config ルールを手動トリガーして即座に評価させる。
aws configservice start-config-rules-evaluation \
--config-rule-names securityhub-emr-block-public-access-<サフィックス> \
--region ap-northeast-1(出力なし)1〜2 分待ってから評価結果を確認する。
sleep 90
aws configservice get-compliance-details-by-config-rule \
--config-rule-name securityhub-emr-block-public-access-<サフィックス> \
--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 を確認する。
sleep 120
aws securityhub get-findings \
--filters '{
"ComplianceSecurityControlId": [{"Comparison": "EQUALS", "Value": "EMR.2"}],
"AwsAccountId": [{"Comparison": "EQUALS", "Value": "<アカウント ID>"}],
"ResourceId": [{"Comparison": "EQUALS", "Value": "AWS::::Account:<アカウント ID>"}],
"RecordState": [{"Comparison": "EQUALS", "Value": "ACTIVE"}]
}' \
--query 'Findings[].{Status:Compliance.Status,ResourceId:Resources[0].Id,UpdatedAt:UpdatedAt}' \
--region ap-northeast-1[
{
"Status": "PASSED",
"ResourceId": "AWS::::Account:<アカウント ID>",
"UpdatedAt": "<更新時刻>"
}
]3. BPA 無効化
put-block-public-access-configuration で BlockPublicSecurityGroupRules: false に設定する。
aws emr put-block-public-access-configuration \
--block-public-access-configuration '{"BlockPublicSecurityGroupRules": false}' \
--region ap-northeast-1(出力なし)反映を確認する。
aws emr get-block-public-access-configuration \
--region ap-northeast-1{
"BlockPublicAccessConfiguration": {
"BlockPublicSecurityGroupRules": false,
"PermittedPublicSecurityGroupRuleRanges": []
},
"BlockPublicAccessConfigurationMetadata": {
"CreationDateTime": "<日時>",
"CreatedByArn": "<変更者 ARN>"
}
}BlockPublicSecurityGroupRules が false に変わり、CreatedByArn にユーザーまたはロールの ARN が記録されている。
4. BPA 無効化後の FAILED 確認
Config ルールを再度トリガーする。
aws configservice start-config-rules-evaluation \
--config-rule-names securityhub-emr-block-public-access-<サフィックス> \
--region ap-northeast-1(出力なし)評価結果を確認する。
sleep 90
aws configservice get-compliance-details-by-config-rule \
--config-rule-name securityhub-emr-block-public-access-<サフィックス> \
--query "EvaluationResults[?EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId=='<アカウント ID>'].{ResourceId:EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId,ComplianceType:ComplianceType,ResultRecordedTime:ResultRecordedTime}" \
--region ap-northeast-1[
{
"ResourceId": "<アカウント ID>",
"ComplianceType": "NON_COMPLIANT",
"ResultRecordedTime": "<評価時刻>"
}
]ResultRecordedTime がステップ 3 の put-block-public-access-configuration 実行時刻より後であることを確認する。
COMPLIANT のままの結果が返る場合がある(設定変更の反映ラグにより、直前の評価結果がそのまま返ることがある)。その場合は数分待ってから再度 start-config-rules-evaluation で再トリガーする。Security Hub への反映を待ってから、finding を確認する。
sleep 120
aws securityhub get-findings \
--filters '{
"ComplianceSecurityControlId": [{"Comparison": "EQUALS", "Value": "EMR.2"}],
"AwsAccountId": [{"Comparison": "EQUALS", "Value": "<アカウント ID>"}],
"ResourceId": [{"Comparison": "EQUALS", "Value": "AWS::::Account:<アカウント ID>"}],
"RecordState": [{"Comparison": "EQUALS", "Value": "ACTIVE"}]
}' \
--query 'Findings[].{Status:Compliance.Status,ResourceId:Resources[0].Id,UpdatedAt:UpdatedAt}' \
--region ap-northeast-1[
{
"Status": "FAILED",
"ResourceId": "AWS::::Account:<アカウント ID>",
"UpdatedAt": "<更新時刻>"
}
]5. BPA 有効化し戻す
BlockPublicSecurityGroupRules: true に戻し、例外ポートを port 22 のみに戻す(デフォルト状態に復帰)。
aws emr put-block-public-access-configuration \
--block-public-access-configuration '{
"BlockPublicSecurityGroupRules": true,
"PermittedPublicSecurityGroupRuleRanges": [
{"MinRange": 22, "MaxRange": 22}
]
}' \
--region ap-northeast-1(出力なし)反映を確認する。
aws emr get-block-public-access-configuration \
--region ap-northeast-1{
"BlockPublicAccessConfiguration": {
"BlockPublicSecurityGroupRules": true,
"PermittedPublicSecurityGroupRuleRanges": [
{
"MinRange": 22,
"MaxRange": 22
}
]
},
"BlockPublicAccessConfigurationMetadata": {
"CreationDateTime": "<日時>",
"CreatedByArn": "<変更者 ARN>"
}
}6. BPA 有効化後の PASSED 確認
Config ルールを再度トリガーする。
aws configservice start-config-rules-evaluation \
--config-rule-names securityhub-emr-block-public-access-<サフィックス> \
--region ap-northeast-1(出力なし)sleep 90
aws configservice get-compliance-details-by-config-rule \
--config-rule-name securityhub-emr-block-public-access-<サフィックス> \
--query "EvaluationResults[?EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId=='<アカウント ID>'].{ResourceId:EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId,ComplianceType:ComplianceType,ResultRecordedTime:ResultRecordedTime}" \
--region ap-northeast-1[
{
"ResourceId": "<アカウント ID>",
"ComplianceType": "COMPLIANT",
"ResultRecordedTime": "<評価時刻>"
}
]ResultRecordedTime がステップ 5 の put-block-public-access-configuration 実行時刻より後であることを確認する。
sleep 120
aws securityhub get-findings \
--filters '{
"ComplianceSecurityControlId": [{"Comparison": "EQUALS", "Value": "EMR.2"}],
"AwsAccountId": [{"Comparison": "EQUALS", "Value": "<アカウント ID>"}],
"ResourceId": [{"Comparison": "EQUALS", "Value": "AWS::::Account:<アカウント ID>"}],
"RecordState": [{"Comparison": "EQUALS", "Value": "ACTIVE"}]
}' \
--query 'Findings[].{Status:Compliance.Status,ResourceId:Resources[0].Id,UpdatedAt:UpdatedAt}' \
--region ap-northeast-1[
{
"Status": "PASSED",
"ResourceId": "AWS::::Account:<アカウント ID>",
"UpdatedAt": "<更新時刻>"
}
]7. 例外に port 8080 を追加
BPA を有効にしたまま、例外ポートに port 8080 を追加する。これは EMR.2 の 2 つ目の FAILED 条件(BlockPublicSecurityGroupRules: true だが port 22 以外の例外あり)を満たす状態を作る。
aws emr put-block-public-access-configuration \
--block-public-access-configuration '{
"BlockPublicSecurityGroupRules": true,
"PermittedPublicSecurityGroupRuleRanges": [
{"MinRange": 22, "MaxRange": 22},
{"MinRange": 8080, "MaxRange": 8080}
]
}' \
--region ap-northeast-1(出力なし)反映を確認する。
aws emr get-block-public-access-configuration \
--region ap-northeast-1{
"BlockPublicAccessConfiguration": {
"BlockPublicSecurityGroupRules": true,
"PermittedPublicSecurityGroupRuleRanges": [
{
"MinRange": 22,
"MaxRange": 22
},
{
"MinRange": 8080,
"MaxRange": 8080
}
]
},
"BlockPublicAccessConfigurationMetadata": {
"CreationDateTime": "<日時>",
"CreatedByArn": "<変更者 ARN>"
}
}8. 例外追加後の FAILED 確認
aws configservice start-config-rules-evaluation \
--config-rule-names securityhub-emr-block-public-access-<サフィックス> \
--region ap-northeast-1(出力なし)sleep 90
aws configservice get-compliance-details-by-config-rule \
--config-rule-name securityhub-emr-block-public-access-<サフィックス> \
--query "EvaluationResults[?EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId=='<アカウント ID>'].{ResourceId:EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId,ComplianceType:ComplianceType,ResultRecordedTime:ResultRecordedTime}" \
--region ap-northeast-1[
{
"ResourceId": "<アカウント ID>",
"ComplianceType": "NON_COMPLIANT",
"ResultRecordedTime": "<評価時刻>"
}
]ResultRecordedTime がステップ 7 の put-block-public-access-configuration 実行時刻より後であることを確認する。BlockPublicSecurityGroupRules: true のままでも、例外に port 22 以外が含まれることで EMR.2 は FAILED になる。
COMPLIANT のままの結果が返る場合がある(設定変更の反映ラグにより、直前の評価結果がそのまま返ることがある)。その場合は数分待ってから再度 start-config-rules-evaluation で再トリガーする。sleep 120
aws securityhub get-findings \
--filters '{
"ComplianceSecurityControlId": [{"Comparison": "EQUALS", "Value": "EMR.2"}],
"AwsAccountId": [{"Comparison": "EQUALS", "Value": "<アカウント ID>"}],
"ResourceId": [{"Comparison": "EQUALS", "Value": "AWS::::Account:<アカウント ID>"}],
"RecordState": [{"Comparison": "EQUALS", "Value": "ACTIVE"}]
}' \
--query 'Findings[].{Status:Compliance.Status,ResourceId:Resources[0].Id,UpdatedAt:UpdatedAt}' \
--region ap-northeast-1[
{
"Status": "FAILED",
"ResourceId": "AWS::::Account:<アカウント ID>",
"UpdatedAt": "<更新時刻>"
}
]9. 例外を元に戻す
例外ポートを port 22 のみに戻す(デフォルト状態に復帰)。
aws emr put-block-public-access-configuration \
--block-public-access-configuration '{
"BlockPublicSecurityGroupRules": true,
"PermittedPublicSecurityGroupRuleRanges": [
{"MinRange": 22, "MaxRange": 22}
]
}' \
--region ap-northeast-1(出力なし)aws emr get-block-public-access-configuration \
--region ap-northeast-1{
"BlockPublicAccessConfiguration": {
"BlockPublicSecurityGroupRules": true,
"PermittedPublicSecurityGroupRuleRanges": [
{
"MinRange": 22,
"MaxRange": 22
}
]
},
"BlockPublicAccessConfigurationMetadata": {
"CreationDateTime": "<日時>",
"CreatedByArn": "<変更者 ARN>"
}
}CreatedByArn は空には戻らない: 一度 put-block-public-access-configuration を実行すると CreatedByArn にユーザー/ロールの ARN が記録される。検証前の AWS デフォルト状態(CreatedByArn: "")には戻らないが、BlockPublicAccessConfiguration の内容が同じであれば実運用上は問題なし。10. 例外を戻した後の PASSED 確認
aws configservice start-config-rules-evaluation \
--config-rule-names securityhub-emr-block-public-access-<サフィックス> \
--region ap-northeast-1(出力なし)sleep 90
aws configservice get-compliance-details-by-config-rule \
--config-rule-name securityhub-emr-block-public-access-<サフィックス> \
--query "EvaluationResults[?EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId=='<アカウント ID>'].{ResourceId:EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId,ComplianceType:ComplianceType,ResultRecordedTime:ResultRecordedTime}" \
--region ap-northeast-1[
{
"ResourceId": "<アカウント ID>",
"ComplianceType": "COMPLIANT",
"ResultRecordedTime": "<評価時刻>"
}
]ResultRecordedTime がステップ 9 の put-block-public-access-configuration 実行時刻より後であることを確認する。
sleep 120
aws securityhub get-findings \
--filters '{
"ComplianceSecurityControlId": [{"Comparison": "EQUALS", "Value": "EMR.2"}],
"AwsAccountId": [{"Comparison": "EQUALS", "Value": "<アカウント ID>"}],
"ResourceId": [{"Comparison": "EQUALS", "Value": "AWS::::Account:<アカウント ID>"}],
"RecordState": [{"Comparison": "EQUALS", "Value": "ACTIVE"}]
}' \
--query 'Findings[].{Status:Compliance.Status,ResourceId:Resources[0].Id,UpdatedAt:UpdatedAt}' \
--region ap-northeast-1[
{
"Status": "PASSED",
"ResourceId": "AWS::::Account:<アカウント ID>",
"UpdatedAt": "<更新時刻>"
}
]推奨設定
本検証で確認する通り、EMR BPA は新規アカウントでデフォルト有効(BlockPublicSecurityGroupRules: true + 例外 port 22 のみ)であり、EMR.2 は初期状態で PASSED となる。
以下の運用を推奨する:
- BPA 設定(
BlockPublicSecurityGroupRules)はtrueを維持する - 例外ポート(
PermittedPublicSecurityGroupRuleRanges)は SSH の port 22 のみに限定し、それ以外のポートは追加しない - port 22 以外の公開ポートが必要な場合は、プライベートサブネットでクラスターを起動する(BPA はプライベートサブネット内クラスターには適用されない)か、特定 IP アドレスからのみのアクセスを許可するセキュリティグループを設定する
例外ポートを追加しないことで EMR.2 の PASSED 状態を維持できる。