DMS.1
コントロールの説明
DMS レプリケーションインスタンスの PubliclyAccessible 設定が false になっているかをチェックする。PubliclyAccessible が true の場合に FAILED となる。
DMS(Database Migration Service)はデータベースの移行やレプリケーションを行うサービスであり、レプリケーションインスタンスはソース DB とターゲット DB の間でデータを転送する中継サーバーである。レプリケーションインスタンスは VPC 内に配置され、RDS と同様に PubliclyAccessible フラグでパブリック IP の付与とパブリック DNS 名の解決先を制御する。
通常、ソース DB とターゲット DB は同一 VPC 内またはピアリング / Transit Gateway 経由で接続するため、レプリケーションインスタンスをパブリックにする必要はない。オンプレミスの DB をインターネット経由で移行する場合にパブリックアクセスが必要になるケースがあるが、VPN や Direct Connect を使用する方が安全である。
対応する Config ルール: DMS_REPLICATION_NOT_PUBLIC(評価頻度: Periodic)
検証環境
--profile 指定がない場合は Workload アカウントで実行する。export AWS_PROFILE=Workload でデフォルトを設定しておくと便利。
結果
- DMS レプリケーションインスタンスが存在しない場合は PASSED
- PubliclyAccessible=true で起動すると FAILED。パブリック IP アドレスが付与される
- インスタンスを削除すると PASSED に復帰
- デフォルトでは保護されていない(PubliclyAccessible のデフォルトは true)
- DMS の ARN はインスタンス識別子ではなく内部 ID が使われる(delete-replication-instance 時に注意)
検証の流れ
flowchart LR
A[1. デフォルト状態の確認<br>PASSED] --> B[2. PubliclyAccessible=true で<br>レプリケーションインスタンス起動]
B --> C[3. FAILED 確認]
C --> D[4. インスタンス削除]
D --> E[5. PASSED 復帰確認]
1. デフォルト状態の確認
Security Hub finding の確認
aws securityhub get-findings \
--filters '{
"ComplianceSecurityControlId": [{"Comparison": "EQUALS", "Value": "DMS.1"}],
"AwsAccountId": [{"Comparison": "EQUALS", "Value": "<アカウント ID>"}],
"WorkflowStatus": [{"Comparison": "NOT_EQUALS", "Value": "SUPPRESSED"}],
"RecordState": [{"Comparison": "EQUALS", "Value": "ACTIVE"}]
}' \
--query 'Findings[].{Status:Compliance.Status,ResourceId:Resources[0].Id}' \
--region ap-northeast-1[
{
"Status": "PASSED",
"ResourceId": "AWS::::Account:<アカウント ID>"
},
{
"Status": "PASSED",
"ResourceId": "AWS::::Account:<アカウント ID>"
}
]DMS レプリケーションインスタンスが存在しないため PASSED。2 件返るのは、東京リージョン(ap-northeast-1)と集約リージョン(ap-southeast-1)の 2 リージョンで Security Hub が有効化されているためである。
2. PubliclyAccessible=true でレプリケーションインスタンス起動
DMS VPC ロールの作成
DMS がサブネットグループの VPC にアクセスするために dms-vpc-role という名前の IAM ロールが必要である。
cat > /tmp/dms-vpc-trust.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "dms.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOFaws iam create-role \
--role-name dms-vpc-role \
--assume-role-policy-document file:///tmp/dms-vpc-trust.json \
--query 'Role.{RoleName:RoleName,Arn:Arn}'{
"RoleName": "dms-vpc-role",
"Arn": "arn:aws:iam::<アカウント ID>:role/dms-vpc-role"
}aws iam attach-role-policy \
--role-name dms-vpc-role \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonDMSVPCManagementRole
(出力なし)レプリケーションサブネットグループの作成
DMS レプリケーションインスタンスにはレプリケーションサブネットグループが必要である。デフォルト VPC のサブネットを使用する。
aws dms create-replication-subnet-group \
--replication-subnet-group-identifier dms1-test-subnet-group \
--replication-subnet-group-description "DMS.1 test" \
--subnet-ids <サブネット ID 1> <サブネット ID 2> <サブネット ID 3> \
--query 'ReplicationSubnetGroup.{Id:ReplicationSubnetGroupIdentifier,VpcId:VpcId}' \
--region ap-northeast-1{
"Id": "dms1-test-subnet-group",
"VpcId": "<デフォルト VPC ID>"
}レプリケーションインスタンスの起動
aws dms create-replication-instance \
--replication-instance-identifier dms1-test \
--replication-instance-class dms.t3.small \
--allocated-storage 5 \
--publicly-accessible \
--replication-subnet-group-identifier dms1-test-subnet-group \
--no-multi-az \
--query 'ReplicationInstance.{Id:ReplicationInstanceIdentifier,Status:ReplicationInstanceStatus,PubliclyAccessible:PubliclyAccessible}' \
--region ap-northeast-1{
"Id": "dms1-test",
"Status": "creating",
"PubliclyAccessible": true
}available 確認
レプリケーションインスタンスの起動には数分かかる。
aws dms describe-replication-instances \
--filters Name=replication-instance-id,Values=dms1-test \
--query 'ReplicationInstances[].{Id:ReplicationInstanceIdentifier,Status:ReplicationInstanceStatus,PubliclyAccessible:PubliclyAccessible,PublicIpAddress:ReplicationInstancePublicIpAddress,PrivateIpAddress:ReplicationInstancePrivateIpAddress}' \
--region ap-northeast-1[
{
"Id": "dms1-test",
"Status": "available",
"PubliclyAccessible": true,
"PublicIpAddress": "<パブリック IP アドレス>",
"PrivateIpAddress": "<プライベート IP アドレス>"
}
]PubliclyAccessible=true の場合、パブリック IP アドレスが付与される。
3. FAILED 確認
Config ルールの手動トリガー
aws configservice start-config-rules-evaluation \
--config-rule-names securityhub-dms-replication-not-public-<サフィックス> \
--region ap-northeast-1
(出力なし)Config 評価結果の確認
aws configservice get-compliance-details-by-config-rule \
--config-rule-name securityhub-dms-replication-not-public-<サフィックス> \
--query 'EvaluationResults[].{ResourceId:EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId,ComplianceType:ComplianceType}' \
--region ap-northeast-1[
{
"ResourceId": "<Config リソース ID>",
"ComplianceType": "NON_COMPLIANT"
}
]Security Hub finding の FAILED 確認
aws securityhub get-findings \
--filters '{
"ComplianceSecurityControlId": [{"Comparison": "EQUALS", "Value": "DMS.1"}],
"AwsAccountId": [{"Comparison": "EQUALS", "Value": "<アカウント ID>"}],
"WorkflowStatus": [{"Comparison": "NOT_EQUALS", "Value": "SUPPRESSED"}],
"RecordState": [{"Comparison": "EQUALS", "Value": "ACTIVE"}]
}' \
--query 'Findings[].{Status:Compliance.Status,ResourceId:Resources[0].Id}' \
--region ap-northeast-1[
{
"Status": "FAILED",
"ResourceId": "arn:aws:dms:ap-northeast-1:<アカウント ID>:rep:dms1-test"
},
{
"Status": "PASSED",
"ResourceId": "AWS::::Account:<アカウント ID>"
}
]4. インスタンス削除
DMS レプリケーションインスタンスの ARN はインスタンス識別子ではなく内部 ID が使われる。describe-replication-instances で確認できる。
aws dms describe-replication-instances \
--filters Name=replication-instance-id,Values=dms1-test \
--query 'ReplicationInstances[].ReplicationInstanceArn' \
--region ap-northeast-1[
"arn:aws:dms:ap-northeast-1:<アカウント ID>:rep:<内部 ID>"
]aws dms delete-replication-instance \
--replication-instance-arn arn:aws:dms:ap-northeast-1:<アカウント ID>:rep:<内部 ID> \
--query 'ReplicationInstance.{Id:ReplicationInstanceIdentifier,Status:ReplicationInstanceStatus}' \
--region ap-northeast-1{
"Id": "dms1-test",
"Status": "deleting"
}削除完了確認
aws dms describe-replication-instances \
--filters Name=replication-instance-id,Values=dms1-test \
--query 'ReplicationInstances[].{Status:ReplicationInstanceStatus}' \
--region ap-northeast-1An error occurred (ResourceNotFoundFault) when calling the DescribeReplicationInstances operation: No instances found matching provided filtersレプリケーションサブネットグループの削除
aws dms delete-replication-subnet-group \
--replication-subnet-group-identifier dms1-test-subnet-group \
--region ap-northeast-1
(出力なし)DMS VPC ロールの削除
aws iam detach-role-policy \
--role-name dms-vpc-role \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonDMSVPCManagementRole
(出力なし)aws iam delete-role \
--role-name dms-vpc-role
(出力なし)5. PASSED 復帰確認
Config ルールの手動トリガー
aws configservice start-config-rules-evaluation \
--config-rule-names securityhub-dms-replication-not-public-<サフィックス> \
--region ap-northeast-1
(出力なし)Security Hub finding の PASSED 確認
aws securityhub get-findings \
--filters '{
"ComplianceSecurityControlId": [{"Comparison": "EQUALS", "Value": "DMS.1"}],
"AwsAccountId": [{"Comparison": "EQUALS", "Value": "<アカウント ID>"}],
"WorkflowStatus": [{"Comparison": "NOT_EQUALS", "Value": "SUPPRESSED"}],
"RecordState": [{"Comparison": "EQUALS", "Value": "ACTIVE"}]
}' \
--query 'Findings[].{Status:Compliance.Status,ResourceId:Resources[0].Id}' \
--region ap-northeast-1[
{
"Status": "PASSED",
"ResourceId": "AWS::::Account:<アカウント ID>"
}
]補足:Config ルール名の確認方法
aws configservice describe-config-rules \
--query 'ConfigRules[?contains(Source.SourceIdentifier,`DMS_REPLICATION_NOT_PUBLIC`)].ConfigRuleName' \
--region ap-northeast-1