Contrôles Amazon Relational Database Service (Amazon RDS) - AWS Control Tower

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Contrôles Amazon Relational Database Service (Amazon RDS)

Rubriques

[CT.RDS.PR.1] Exiger qu'une instance de base de données Amazon RDS soit configurée avec plusieurs zones de disponibilité

Ce contrôle vérifie si la haute disponibilité est configurée pour vos instances de base de données Amazon Relational Database Service (RDS).

  • Objectif de contrôle : améliorer la disponibilité

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBInstance

  • AWS CloudFormationrègle de garde : CT.RDS.PR.1spécification des règles

Détails et exemples

Explication

Les instances de base de données (DB) Amazon RDS doivent être configurées pour plusieurs zones de disponibilité (AZ). Cette configuration augmente la disponibilité des données stockées. Le déploiement dans plusieurs zones de disponibilité permet un basculement automatique, en cas de panne d'une zone de disponibilité et lors de la maintenance régulière du RDS.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux types de moteurs de base de données Amazon RDS mariadb mysql oracle-eeoracle-ee-cdb,oracle-se2,oracle-se2-cdb,postgres,, sqlserver-eesqlserver-se, sqlserver-ex etsqlserver-web.

  • Ce contrôle s'applique uniquement lorsque la Engine propriété est fournie. Cela ne s'applique pas lors de la restauration à partir d'un instantané de base de données ou d'un instantané de cluster pour lequel un n'Enginea pas été défini explicitement.

Corrections en cas de défaillance des règles

Définissez MultiAZ sur true.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Instance de base de données Amazon RDS : exemple

Instance de base de données Amazon RDS configurée avec plusieurs zones de disponibilité. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBInstance": { "Type": "AWS::RDS::DBInstance", "Properties": { "Engine": "postgres", "EngineVersion": 14.2, "DBInstanceClass": "db.m5.large", "StorageType": "gp2", "AllocatedStorage": 5, "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::password}}" }, "MultiAZ": true }, "DeletionPolicy": "Delete" } }

Exemple YAML

DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' MultiAZ: true DeletionPolicy: Delete

CT.RDS.PR.1spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_instance_multi_az_support_check # # Description: # This control checks whether high availability is configured for your Amazon Relational Database Service (RDS) database instances. # # Reports on: # AWS::RDS::DBInstance # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any RDS DB instance resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is not one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'MultiAZ' has not been specified # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'MultiAZ' has been specified # And: 'MultiAZ' has been set to bool(false) # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'MultiAZ' has been specified # And: 'MultiAZ' has been set to bool(true) # Then: PASS # # Constants # let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance" let INPUT_DOCUMENT = this let SUPPORTED_RDS_INSTANCE_ENGINES = [ "mariadb", "mysql", "oracle-ee", "oracle-ee-cdb", "oracle-se2", "oracle-se2-cdb", "postgres", "sqlserver-ee", "sqlserver-se", "sqlserver-ex", "sqlserver-web" ] # # Assignments # let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ] # # Primary Rules # rule rds_instance_multi_az_support_check when is_cfn_template(%INPUT_DOCUMENT) %rds_db_instances not empty { check(%rds_db_instances.Properties) << [CT.RDS.PR.1]: Require that an Amazon RDS database instance is configured with multiple Availability Zones [FIX]: Set 'MultiAZ' to 'true'. >> } rule rds_instance_multi_az_support_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties) << [CT.RDS.PR.1]: Require that an Amazon RDS database instance is configured with multiple Availability Zones [FIX]: Set 'MultiAZ' to 'true'. >> } # # Parameterized Rules # rule check(rds_db_instance) { %rds_db_instance [filter_engine(this)] { # Scenario 3 MultiAZ exists # Scenario 4 and 5 MultiAZ == true } } rule filter_engine(db_properties) { %db_properties { # Scenario 2 Engine exists Engine is_string Engine in %SUPPORTED_RDS_INSTANCE_ENGINES } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

CT.RDS.PR.1exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS instance secret GenerateSecretString: SecretStringTemplate: '{"username": "testUser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' MultiAZ: true DeletionPolicy: Delete

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS instance secret GenerateSecretString: SecretStringTemplate: '{"username": "testUser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' MultiAZ: false DeletionPolicy: Delete

[CT.RDS.PR.2] Exiger la configuration d'une instance ou d'un cluster de base de données Amazon RDS

Ce contrôle vérifie si la surveillance améliorée est activée pour les instances Amazon Relational Database Service (RDS).

  • Objectif de contrôle : établir une journalisation et une surveillance

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBInstance

  • AWS CloudFormationrègle de garde : CT.RDS.PR.2spécification des règles

Détails et exemples

Explication

Dans Amazon RDS, la surveillance améliorée permet de réagir plus rapidement aux changements de performances de l'infrastructure sous-jacente. Ces modifications des performances peuvent entraîner un manque de disponibilité des données. La surveillance améliorée fournit des mesures en temps réel du système d'exploitation sur lequel votre instance de base de données RDS s'exécute. Un agent, installé sur l'instance, peut obtenir des métriques de manière plus précise qu'il n'est possible de le faire à partir de la couche hyperviseur.

Les métriques de surveillance améliorées sont utiles lorsque vous souhaitez voir comment les différents processus ou threads d'une instance de base de données (DB) utilisent le processeur.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux types de moteurs de base de données Amazon RDS aurora aurora-mysql aurora-postgresql mariadbmysql,oracle-ee,oracle-ee-cdb,oracle-se2,oracle-se2-cdb,postgres, sqlserver-eesqlserver-se, et sqlserver-ex sqlserver-web

  • Ce contrôle s'applique uniquement lorsque la Engine propriété est fournie. Cela ne s'applique pas lors de la restauration à partir d'un instantané de base de données ou d'un instantané de cluster pour lequel un n'Enginea pas été défini explicitement.

Corrections en cas de défaillance des règles

MonitoringIntervalDéfini sur une valeur prise en charge (1, 5, 10, 15, 30, 60) et défini MonitoringRoleArn sur l'ARN d'un rôle AWS IAM.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Instance de base de données Amazon RDS : exemple

Instance de base de données Amazon RDS configurée avec une surveillance améliorée. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBInstance": { "Type": "AWS::RDS::DBInstance", "Properties": { "Engine": "postgres", "EngineVersion": 14.2, "DBInstanceClass": "db.m5.large", "StorageType": "gp2", "AllocatedStorage": 5, "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::password}}" }, "MonitoringInterval": 30, "MonitoringRoleArn": { "Fn::GetAtt": [ "MonitoringIAMRole", "Arn" ] } }, "DeletionPolicy": "Delete" } }

Exemple YAML

DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' MonitoringInterval: 30 MonitoringRoleArn: !GetAtt 'MonitoringIAMRole.Arn' DeletionPolicy: Delete

CT.RDS.PR.2spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_instance_enhanced_monitoring_enabled_check # # Description: # This control checks whether enhanced monitoring is activated for Amazon Relational Database Service (RDS) instances. # # Reports on: # AWS::RDS::DBInstance # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any RDS DB instance resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is not one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mariadb', 'mysql', # 'oracle-ee', 'oracle-se2', 'oracle-se1', 'oracle-se', 'postgres', 'sqlserver-ee', # 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mariadb', 'mysql', # 'oracle-ee', 'oracle-se2', 'oracle-se1', 'oracle-se', 'postgres', 'sqlserver-ee', # 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'MonitoringInterval' has not been specified # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mariadb', 'mysql', # 'oracle-ee', 'oracle-se2', 'oracle-se1', 'oracle-se', 'postgres', 'sqlserver-ee', # 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'MonitoringInterval' has been specified # And: 'MonitoringInterval' has been set to '0' # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mariadb', 'mysql', # 'oracle-ee', 'oracle-se2', 'oracle-se1', 'oracle-se', 'postgres', 'sqlserver-ee', # 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'MonitoringInterval' has been specified # And: 'MonitoringInterval' has not been set to a value from the list 1, 5, 10, 15, 30, 60 # Then: FAIL # Scenario: 6 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mariadb', 'mysql', # 'oracle-ee', 'oracle-se2', 'oracle-se1', 'oracle-se', 'postgres', 'sqlserver-ee', # 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'MonitoringInterval' has been specified # And: 'MonitoringInterval' has been set to a value from the list 1, 5, 10, 15, 30, 60 # And: 'MonitoringRoleArn' has not been specified or specified as an empty string # Then: FAIL # Scenario: 7 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mariadb', 'mysql', # 'oracle-ee', 'oracle-se2', 'oracle-se1', 'oracle-se', 'postgres', 'sqlserver-ee', # 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'MonitoringInterval' has been specified # And: 'MonitoringInterval' has been set to a value from the list 1, 5, 10, 15, 30, 60 # And: 'MonitoringRoleArn' has been specified with a non-empty string or valid local reference # Then: PASS # # Constants # let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance" let INPUT_DOCUMENT = this let SUPPORTED_RDS_INSTANCE_ENGINES = [ "aurora", "aurora-mysql", "aurora-postgresql", "mariadb", "mysql", "oracle-ee", "oracle-ee-cdb", "oracle-se2", "oracle-se2-cdb", "postgres", "sqlserver-ee", "sqlserver-se", "sqlserver-ex", "sqlserver-web" ] let ALLOWED_EM_VALUES = [1, 5, 10, 15, 30, 60] # # Assignments # let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ] # # Primary Rules # rule rds_instance_enhanced_monitoring_enabled_check when is_cfn_template(%INPUT_DOCUMENT) %rds_db_instances not empty { check(%rds_db_instances.Properties) << [CT.RDS.PR.2]: Require an Amazon RDS database instance or cluster to have enhanced monitoring configured [FIX]: Set 'MonitoringInterval' to a supported value (1, 5, 10, 15, 30, 60), and set 'MonitoringRoleArn' to the ARN of an AWS IAM role. >> } rule rds_instance_enhanced_monitoring_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties) << [CT.RDS.PR.2]: Require an Amazon RDS database instance or cluster to have enhanced monitoring configured [FIX]: Set 'MonitoringInterval' to a supported value (1, 5, 10, 15, 30, 60), and set 'MonitoringRoleArn' to the ARN of an AWS IAM role. >> } # # Parameterized Rules # rule check(rds_db_instance) { %rds_db_instance [filter_engine(this)] { # Scenario: 3, 4, 5, 6 and 7 MonitoringInterval exists MonitoringInterval in %ALLOWED_EM_VALUES # Scenario: 6 and 7 MonitoringRoleArn exists check_for_valid_monitor_role_arn(MonitoringRoleArn) } } rule filter_engine(db_properties) { %db_properties { # Scenario: 2 Engine exists Engine is_string Engine in %SUPPORTED_RDS_INSTANCE_ENGINES } } rule check_for_valid_monitor_role_arn(iam_role_arn) { %iam_role_arn { check_is_string_and_not_empty(this) or check_local_references(%INPUT_DOCUMENT, this, "AWS::IAM::Role") } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists } rule check_is_string_and_not_empty(value) { %value { this is_string this != /\A\s*\z/ } } rule check_local_references(doc, reference_properties, referenced_resource_type) { %reference_properties { 'Fn::GetAtt' { query_for_resource(%doc, this[0], %referenced_resource_type) <<Local Stack reference was invalid>> } or Ref { query_for_resource(%doc, this, %referenced_resource_type) <<Local Stack reference was invalid>> } } } rule query_for_resource(doc, resource_key, referenced_resource_type) { let referenced_resource = %doc.Resources[ keys == %resource_key ] %referenced_resource not empty %referenced_resource { Type == %referenced_resource_type } }

CT.RDS.PR.2exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: MonitoringIAMRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Service: - "monitoring.rds.amazonaws.com" Action: - "sts:AssumeRole" Path: "/" ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB instance secret GenerateSecretString: SecretStringTemplate: '{"username": "testUser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' MonitoringInterval: 30 MonitoringRoleArn: Fn::GetAtt: ["MonitoringIAMRole", "Arn"] DeletionPolicy: Delete

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB instance secret GenerateSecretString: SecretStringTemplate: '{"username": "testUser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' MonitoringInterval: 0 DeletionPolicy: Delete

[CT.RDS.PR.3] Exiger que la protection contre les suppressions soit configurée sur un cluster Amazon RDS

Ce contrôle vérifie si la protection contre les suppressions est activée sur votre cluster Amazon Relational Database Service (Amazon RDS).

  • Objectif de contrôle : améliorer la disponibilité

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBCluster

  • AWS CloudFormationrègle de garde : CT.RDS.PR.3spécification des règles

Détails et exemples

Explication

L'activation de la protection contre la suppression de clusters constitue un niveau de protection supplémentaire contre la suppression accidentelle de la base de données ou la suppression par une entité non autorisée.

Lorsque la protection contre la suppression est activée, un cluster Amazon RDS ne peut pas être supprimé. Pour qu'une demande de suppression puisse aboutir, la protection contre la suppression doit être désactivée.

Corrections en cas de défaillance des règles

Définissez la valeur du DeletionProtection paramètre sur true.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Cluster de bases de données Amazon RDS : exemple

Cluster de base de données Amazon RDS avec protection contre la suppression activée. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "RDSDBCluster": { "Type": "AWS::RDS::DBCluster", "Properties": { "Engine": "aurora", "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${RDSClusterSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${RDSClusterSecret}::password}}" }, "DBSubnetGroupName": { "Ref": "TestDBSubnetGroup" }, "DeletionProtection": true } } }

Exemple YAML

RDSDBCluster: Type: AWS::RDS::DBCluster Properties: Engine: aurora MasterUsername: !Sub '{{resolve:secretsmanager:${RDSClusterSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${RDSClusterSecret}::password}}' DBSubnetGroupName: !Ref 'TestDBSubnetGroup' DeletionProtection: true

CT.RDS.PR.3spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_cluster_deletion_protection_enabled_check # # Description: # Checks if an Amazon Relational Database Service (Amazon RDS) cluster has deletion protection enabled. # # Reports on: # AWS::RDS::DBCluster # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document does not contain any RDS DB cluster resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'DeletionProtection' has not been specified # Then: FAIL # Scenario: 3 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'DeletionProtection' has been specified # And: 'DeletionProtection' has been set to bool(false) # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'DeletionProtection' has been specified # And: 'DeletionProtection' has been set to bool(true) # Then: PASS # # Constants # let RDS_DB_CLUSTER_TYPE = "AWS::RDS::DBCluster" let INPUT_DOCUMENT = this # # Assignments # let db_clusters = Resources.*[ Type == %RDS_DB_CLUSTER_TYPE ] # # Primary Rules # rule rds_cluster_deletion_protection_enabled_check when is_cfn_template(%INPUT_DOCUMENT) %db_clusters not empty { check(%db_clusters.Properties) << [CT.RDS.PR.3]: Require an Amazon RDS cluster to have deletion protection configured [FIX]: Set the value of the 'DeletionProtection' parameter to true. >> } rule rds_cluster_deletion_protection_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_CLUSTER_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_CLUSTER_TYPE.resourceProperties) << [CT.RDS.PR.3]: Require an Amazon RDS cluster to have deletion protection configured [FIX]: Set the value of the 'DeletionProtection' parameter to true. >> } rule check(properties) { %properties { # Scenario 2 DeletionProtection exists # Scenario 3 and 4 DeletionProtection == true } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

CT.RDS.PR.3exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true SubnetOne: Type: AWS::EC2::Subnet Properties: VpcId: Ref: VPC CidrBlock: 10.0.0.0/25 AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: '' SubnetTwo: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.0.0.128/25 AvailabilityZone: Fn::Select: - 1 - Fn::GetAZs: '' VpcId: Ref: VPC DBSubnetGroup: Type: AWS::RDS::DBSubnetGroup Properties: DBSubnetGroupDescription: Example DB subnet group SubnetIds: - Ref: SubnetOne - Ref: SubnetTwo RDSClusterSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS cluster secret GenerateSecretString: SecretStringTemplate: '{"username": "exampleuser"}' GenerateStringKey: password PasswordLength: 32 ExcludeCharacters: "/@\"" RDSCluster: Type: AWS::RDS::DBCluster Properties: Engine: aurora-mysql MasterUsername: Fn::Sub: "{{resolve:secretsmanager:${RDSClusterSecret}::username}}" MasterUserPassword: Fn::Sub: "{{resolve:secretsmanager:${RDSClusterSecret}::password}}" DBSubnetGroupName: Ref: DBSubnetGroup DeletionProtection: true

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true SubnetOne: Type: AWS::EC2::Subnet Properties: VpcId: Ref: VPC CidrBlock: 10.0.0.0/25 AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: '' SubnetTwo: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.0.0.128/25 AvailabilityZone: Fn::Select: - 1 - Fn::GetAZs: '' VpcId: Ref: VPC DBSubnetGroup: Type: AWS::RDS::DBSubnetGroup Properties: DBSubnetGroupDescription: Example DB subnet group SubnetIds: - Ref: SubnetOne - Ref: SubnetTwo RDSClusterSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS cluster secret GenerateSecretString: SecretStringTemplate: '{"username": "exampleuser"}' GenerateStringKey: password PasswordLength: 32 ExcludeCharacters: "/@\"" RDSCluster: Type: AWS::RDS::DBCluster Properties: Engine: aurora-mysql MasterUsername: Fn::Sub: "{{resolve:secretsmanager:${RDSClusterSecret}::username}}" MasterUserPassword: Fn::Sub: "{{resolve:secretsmanager:${RDSClusterSecret}::password}}" DBSubnetGroupName: Ref: DBSubnetGroup DeletionProtection: false

[CT.RDS.PR.4] Exiger qu'un cluster de base de données Amazon RDS soit configuré pour configurer l'authentification de base de données AWS IAM

Ce contrôle vérifie si l'authentification de base de données IAM est activée dans un cluster AWS de base de données (DB) Amazon Relational Database Service (RDS).

  • Objectif de contrôle : utiliser une authentification forte

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBCluster

  • AWS CloudFormationrègle de garde : CT.RDS.PR.4spécification des règles

Détails et exemples

Explication

L'authentification de base de données IAM permet une authentification sans mot de passe pour les instances de base de données. L'authentification utilise un jeton d'authentification. Le trafic réseau à destination et en provenance de la base de données est crypté à l'aide du protocole SSL.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux types de moteurs de cluster de base de données Amazon RDSaurora, aurora-mysql etaurora-postgresql.

Corrections en cas de défaillance des règles

Définissez EnableIAMDatabaseAuthentication sur true.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Cluster de bases de données Amazon RDS : exemple

Cluster de base de données Amazon RDS configuré avec l'authentification de base de données AWS IAM. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBCluster": { "Type": "AWS::RDS::DBCluster", "Properties": { "Engine": "aurora-mysql", "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBClusterSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBClusterSecret}::password}}" }, "DBSubnetGroupName": { "Ref": "DBSubnetGroup" }, "EnableIAMDatabaseAuthentication": true } } }

Exemple YAML

DBCluster: Type: AWS::RDS::DBCluster Properties: Engine: aurora-mysql MasterUsername: !Sub '{{resolve:secretsmanager:${DBClusterSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBClusterSecret}::password}}' DBSubnetGroupName: !Ref 'DBSubnetGroup' EnableIAMDatabaseAuthentication: true

CT.RDS.PR.4spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_cluster_iam_authentication_enabled_check # # Description: # This control checks whether an Amazon Relational Database Service (RDS) database (DB) cluster has AWS IAM database authentication activated. # # Reports on: # AWS::RDS::DBCluster # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation document or AWS CloudFormation hook document # And: The input document does not contain any RDS DB cluster resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation document or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'Engine' provided is not one of 'aurora' or 'aurora-mysql' or 'aurora-postgresql' # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation document or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'Engine' provided is one of 'aurora' or 'aurora-mysql' or 'aurora-postgresql' # And: 'EnableIAMDatabaseAuthentication' has not been provided # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation document or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'Engine' provided is one of 'aurora' or 'aurora-mysql' or 'aurora-postgresql' # And: 'EnableIAMDatabaseAuthentication' has been provided # And: 'EnableIAMDatabaseAuthentication' has been set to a value other than bool(true) # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation document or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'Engine' provided is one of 'aurora' or 'aurora-mysql' or 'aurora-postgresql' # And: 'EnableIAMDatabaseAuthentication' has been provided # And: 'EnableIAMDatabaseAuthentication' has been set to bool(true) # Then: PASS # # Constants # let RDS_DB_CLUSTER_TYPE = "AWS::RDS::DBCluster" let SUPPORTED_DB_CLUSTER_ENGINES = ["aurora", "aurora-mysql","aurora-postgresql"] let INPUT_DOCUMENT = this # # Assignments # let db_clusters = Resources.*[ Type == %RDS_DB_CLUSTER_TYPE ] # # Primary Rules # rule rds_cluster_iam_authentication_enabled_check when is_cfn_template(%INPUT_DOCUMENT) %db_clusters not empty { check(%db_clusters.Properties) << [CT.RDS.PR.4]: Require an Amazon RDS database cluster to have AWS IAM database authentication configured [FIX]: Set 'EnableIAMDatabaseAuthentication' to 'true'. >> } rule rds_cluster_iam_authentication_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_CLUSTER_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_CLUSTER_TYPE.resourceProperties) << [CT.RDS.PR.4]: Require an Amazon RDS database cluster to have AWS IAM database authentication configured [FIX]: Set 'EnableIAMDatabaseAuthentication' to 'true'. >> } rule check(db_cluster) { %db_cluster [ # Scenario 2 filter_engine(this) ] { # Scenario 3 EnableIAMDatabaseAuthentication exists # Scenario 4 and 5 EnableIAMDatabaseAuthentication == true } } rule filter_engine(cluster_properties) { %cluster_properties { Engine exists Engine in %SUPPORTED_DB_CLUSTER_ENGINES } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

CT.RDS.PR.4exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true SubnetOne: Type: AWS::EC2::Subnet Properties: VpcId: Ref: VPC CidrBlock: 10.0.0.0/25 AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: '' SubnetTwo: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.0.0.128/25 AvailabilityZone: Fn::Select: - 1 - Fn::GetAZs: '' VpcId: Ref: VPC DBSubnetGroup: Type: AWS::RDS::DBSubnetGroup Properties: DBSubnetGroupDescription: DB subnet group for DBCluster SubnetIds: - Ref: SubnetOne - Ref: SubnetTwo DBClusterSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB cluster secret GenerateSecretString: SecretStringTemplate: '{"username": "examplemasteruser"}' GenerateStringKey: password PasswordLength: 32 ExcludeCharacters: "/@\"'\\" DBCluster: Type: AWS::RDS::DBCluster Properties: Engine: aurora-mysql MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBClusterSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBClusterSecret}::password}}' DBSubnetGroupName: Ref: DBSubnetGroup EnableIAMDatabaseAuthentication: true

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true SubnetOne: Type: AWS::EC2::Subnet Properties: VpcId: Ref: VPC CidrBlock: 10.0.0.0/25 AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: '' SubnetTwo: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.0.0.128/25 AvailabilityZone: Fn::Select: - 1 - Fn::GetAZs: '' VpcId: Ref: VPC DBSubnetGroup: Type: AWS::RDS::DBSubnetGroup Properties: DBSubnetGroupDescription: DB subnet group for DBCluster SubnetIds: - Ref: SubnetOne - Ref: SubnetTwo DBClusterSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB cluster secret GenerateSecretString: SecretStringTemplate: '{"username": "examplemasteruser"}' GenerateStringKey: password PasswordLength: 32 ExcludeCharacters: "/@\"'\\" DBCluster: Type: AWS::RDS::DBCluster Properties: Engine: aurora-mysql MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBClusterSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBClusterSecret}::password}}' DBSubnetGroupName: Ref: DBSubnetGroup

[CT.RDS.PR.5] Exiger une instance de base de données Amazon RDS pour configurer les mises à niveau des versions mineures

Ce contrôle vérifie si les mises à niveau automatiques des versions mineures sont activées pour une instance de base de données Amazon Relational Database Service (RDS).

  • Objectif de contrôle : gérer les vulnérabilités

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBInstance

  • AWS CloudFormationrègle de garde : CT.RDS.PR.5spécification des règles

Détails et exemples

Explication

En activant les mises à niveau automatiques des versions mineures, vous pouvez vous assurer que les dernières mises à jour des versions mineures du système de gestion de base de données relationnelle (SGBDR) sont installées. Ces mises à niveau peuvent inclure des correctifs de sécurité et des corrections de bogues. La mise à jour de l'installation des correctifs est une étape importante de la sécurisation des systèmes.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux types de moteurs de base de données Amazon RDS aurora aurora-mysql aurora-postgresql mariadbmysql,oracle-ee,oracle-ee-cdb,,oracle-se2,oracle-se2-cdb,postgres, sqlserver-eesqlserver-se, sqlserver-ex etsqlserver-web.

  • Ce contrôle s'applique uniquement lorsque la Engine propriété est fournie. Cela ne s'applique pas lors de la restauration à partir d'un instantané de base de données ou d'un instantané de cluster pour lequel un n'Enginea pas été défini explicitement.

Corrections en cas de défaillance des règles

Omettez la AutoMinorVersionUpgrade propriété ou définissez-la sur. true

Les exemples suivants montrent comment mettre en œuvre cette correction.

Instance de base de données Amazon RDS - Exemple 1

Instance de base de données Amazon RDS configurée avec des mises à niveau automatiques des versions mineures, activées par AWS CloudFormation défaut. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBInstance": { "Type": "AWS::RDS::DBInstance", "Properties": { "Engine": "postgres", "EngineVersion": 14.2, "DBInstanceClass": "db.m5.large", "StorageType": "gp2", "AllocatedStorage": 5, "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::password}}" } }, "DeletionPolicy": "Delete" } }

Exemple YAML

DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' DeletionPolicy: Delete

Les exemples suivants montrent comment mettre en œuvre cette correction.

Instance de base de données Amazon RDS : deuxième exemple

Instance de base de données Amazon RDS configurée avec des mises à niveau automatiques des versions mineures, activées au moyen de la AutoMinorVersionUpgrade propriété. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBInstance": { "Type": "AWS::RDS::DBInstance", "Properties": { "Engine": "postgres", "EngineVersion": 14.2, "DBInstanceClass": "db.m5.large", "StorageType": "gp2", "AllocatedStorage": 5, "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::password}}" }, "AutoMinorVersionUpgrade": true }, "DeletionPolicy": "Delete" } }

Exemple YAML

DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' AutoMinorVersionUpgrade: true DeletionPolicy: Delete

CT.RDS.PR.5spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_instance_automatic_minor_version_upgrade_enabled_check # # Description: # This control checks whether automatic minor version upgrades are enabled for an Amazon Relational Database Service (RDS) database instance. # # Reports on: # AWS::RDS::DBInstance # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any RDS DB instance resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is not one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mariadb', 'mysql', # 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', 'oracle-se2-cdb', # 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web', # 'postgres' # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mariadb', 'mysql', # 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', 'oracle-se2-cdb', # 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web', # 'postgres' # And: 'AutoMinorVersionUpgrade' has been specified # And: 'AutoMinorVersionUpgrade' has been set to bool(false) # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mariadb', 'mysql', # 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', 'oracle-se2-cdb', # 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web', # 'postgres' # And: 'AutoMinorVersionUpgrade' has not been specified # Then: PASS # Scenario: 5 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mariadb', 'mysql', # 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', 'oracle-se2-cdb', # 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web', # 'postgres' # And: 'AutoMinorVersionUpgrade' has been specified # And: 'AutoMinorVersionUpgrade' has been set to bool(true) # Then: PASS # # Constants # let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance" let INPUT_DOCUMENT = this let SUPPORTED_RDS_INSTANCE_ENGINES = [ "aurora", "aurora-mysql", "aurora-postgresql", "mariadb", "mysql", "oracle-ee", "oracle-ee-cdb", "oracle-se2", "oracle-se2-cdb", "postgres", "sqlserver-ee", "sqlserver-se", "sqlserver-ex", "sqlserver-web" ] # # Assignments # let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ] # # Primary Rules # rule rds_instance_automatic_minor_version_upgrade_enabled_check when is_cfn_template(%INPUT_DOCUMENT) %rds_db_instances not empty { check(%rds_db_instances.Properties) << [CT.RDS.PR.5]: Require an Amazon RDS database instance to have minor version upgrades configured [FIX]: Omit the 'AutoMinorVersionUpgrade' property or set it to 'true'. >> } rule rds_instance_automatic_minor_version_upgrade_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties) << [CT.RDS.PR.5]: Require an Amazon RDS database instance to have minor version upgrades configured [FIX]: Omit the 'AutoMinorVersionUpgrade' property or set it to 'true'. >> } # # Parameterized Rules # rule check(rds_db_instance) { %rds_db_instance [ filter_engine(this) ] { # Scenario: 4 AutoMinorVersionUpgrade not exists or # Scenario: 3 and 5 AutoMinorVersionUpgrade == true } } rule filter_engine(db_properties) { %db_properties { # Scenario: 2 Engine exists Engine is_string Engine in %SUPPORTED_RDS_INSTANCE_ENGINES } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

CT.RDS.PR.5exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: Test RDS DB Instance secret GenerateSecretString: SecretStringTemplate: '{"username": "testUser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' DeletionPolicy: Delete

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: Test RDS DB Instance secret GenerateSecretString: SecretStringTemplate: '{"username": "testUser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' AutoMinorVersionUpgrade: false DeletionPolicy: Delete

[CT.RDS.PR.6] Exiger la configuration du retour en arrière sur un cluster de bases de données Amazon RDS

Ce contrôle vérifie si le retour en arrière est activé sur un cluster de base de données (DB) Amazon Relational Database Service (RDS).

  • Objectif de contrôle : améliorer la résilience

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBCluster

  • AWS CloudFormationrègle de garde : Spécification de la règle CT.RDS.PR.6

Détails et exemples

Explication

Les sauvegardes vous aident à récupérer plus rapidement après un incident de sécurité. Les sauvegardes renforcent également la résilience de vos systèmes. Le retour en arrière d'Aurora réduit le temps nécessaire pour restaurer une base de données à un moment précis, et la restauration ne nécessite pas de restauration de base de données.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux types de moteurs de cluster de base de données Amazon RDS aurora et aurora-mysql aux modes provisioned de moteur de cluster de base de données et parallelquery

  • Ce contrôle ne s'applique pas aux clusters de base de données Amazon RDS qui prennent en charge les instances de base de données Aurora Serverless V2 (par exemple, les clusters de base de données RDS configurés avec a et compatibles avec ServerlessV2ScalingConfiguration Aurora Serverless V2). EngineVersion

Corrections en cas de défaillance des règles

BacktrackWindowRéglé sur un nombre compris entre 1 et259200.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Cluster de bases de données Amazon RDS : exemple

Cluster de base de données Amazon RDS configuré avec une fenêtre de retour en arrière de 720 secondes (12 minutes). L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBCluster": { "Type": "AWS::RDS::DBCluster", "Properties": { "Engine": "aurora-mysql", "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBClusterSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBClusterSecret}::password}}" }, "DBSubnetGroupName": { "Ref": "DBSubnetGroup" }, "BacktrackWindow": 720 } } }

Exemple YAML

DBCluster: Type: AWS::RDS::DBCluster Properties: Engine: aurora-mysql MasterUsername: !Sub '{{resolve:secretsmanager:${DBClusterSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBClusterSecret}::password}}' DBSubnetGroupName: !Ref 'DBSubnetGroup' BacktrackWindow: 720

Spécification de la règle CT.RDS.PR.6

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # aurora_cluster_backtracking_enabled_check # # Description: # This control checks whether an Amazon Relational Database Service (RDS) database (DB) cluster has backtracking enabled. # # Reports on: # AWS::RDS::DBCluster # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any RDS DB cluster resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'Engine' provided is not one of 'aurora' or 'aurora-mysql' # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'Engine' provided is one of 'aurora' or 'aurora-mysql' # And: 'EngineMode' provided is not one of 'provisioned' or 'parallelquery' # Then: SKIP # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'ServerlessV2ScalingConfiguration' is provided # And: 'Engine' provided is 'aurora-mysql' # And: 'EngineVersion' provided is '8.0.mysql_aurora.3.02.0' or higher # Then: SKIP # Scenario: 5 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'Engine' provided is one of 'aurora' or 'aurora-mysql' # And: 'EngineMode' is not provided or 'EngineMode' provided is one of 'provisioned' or 'parallelquery' # And: 'BacktrackWindow' has not been provided # Then: FAIL # Scenario: 6 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'Engine' provided is one of 'aurora' or 'aurora-mysql' # And: 'EngineMode' is not provided or 'EngineMode' provided is one of 'provisioned' or 'parallelquery' # And: 'BacktrackWindow' has been provided and is set to 0 # Then: FAIL # Scenario: 7 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'Engine' provided is one of 'aurora' or 'aurora-mysql' # And: 'EngineMode' is not provided or 'EngineMode' provided is one of 'provisioned' or 'parallelquery' # And: 'BacktrackWindow' has been provided and is set to a value > 0 # Then: PASS # # Constants # let RDS_DB_CLUSTER_TYPE = "AWS::RDS::DBCluster" let SUPPORTED_DB_CLUSTER_ENGINES = ["aurora", "aurora-mysql"] let SUPPORTED_DB_CLUSTER_ENGINE_MODES = ["provisioned", "parallelquery"] let AURORA_SERVERLESS_V2_SUPPORTED_ENGINE = ["aurora-mysql"] let AURORA_V3_SERVERLESS_V2_NOT_SUPPORTED_PATTERN = /^8\.0\.mysql_aurora\.3\.01\./ let AURORA_V3_SERVERLESS_V2_SUPPORTED_PATTERN = /^8\.0\.mysql_aurora\.3/ let INPUT_DOCUMENT = this # # Assignments # let db_clusters = Resources.*[ Type == %RDS_DB_CLUSTER_TYPE ] # # Primary Rules # rule aurora_cluster_backtracking_enabled_check when is_cfn_template(%INPUT_DOCUMENT) %db_clusters not empty { check(%db_clusters.Properties) << [CT.RDS.PR.6]: Require an Amazon RDS database cluster to have backtracking configured [FIX]: Set 'BacktrackWindow' to a number between '1' and '259200'. >> } rule aurora_cluster_backtracking_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_CLUSTER_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_CLUSTER_TYPE.resourceProperties) << [CT.RDS.PR.6]: Require an Amazon RDS database cluster to have backtracking configured [FIX]: Set 'BacktrackWindow' to a number between '1' and '259200'. >> } rule check(db_cluster) { %db_cluster [ filter_engine_enginemode_and_serverless_v2(this) ] { # Scenario 5 BacktrackWindow exists # Scenario 6 and 7 BacktrackWindow > 0 } } rule filter_engine_enginemode_and_serverless_v2(db_cluster) { # Scenario 2 and 3 %db_cluster { Engine exists Engine in %SUPPORTED_DB_CLUSTER_ENGINES EngineMode not exists or EngineMode in %SUPPORTED_DB_CLUSTER_ENGINE_MODES } #Scenario 4 %db_cluster [ ServerlessV2ScalingConfiguration exists Engine in %AURORA_SERVERLESS_V2_SUPPORTED_ENGINE ] { EngineVersion in %AURORA_V3_SERVERLESS_V2_NOT_SUPPORTED_PATTERN or EngineVersion not in %AURORA_V3_SERVERLESS_V2_SUPPORTED_PATTERN } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

CT.RDS.PR.6exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true SubnetOne: Type: AWS::EC2::Subnet Properties: VpcId: Ref: VPC CidrBlock: 10.0.0.0/25 AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: '' SubnetTwo: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.0.0.128/25 AvailabilityZone: Fn::Select: - 1 - Fn::GetAZs: '' VpcId: Ref: VPC DBSubnetGroup: Type: AWS::RDS::DBSubnetGroup Properties: DBSubnetGroupDescription: Example DB subnet group SubnetIds: - Ref: SubnetOne - Ref: SubnetTwo DBClusterSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB cluster secret GenerateSecretString: SecretStringTemplate: '{"username": "examplemasteruser"}' GenerateStringKey: password PasswordLength: 32 ExcludeCharacters: "/@\"'\\" DBCluster: Type: AWS::RDS::DBCluster Properties: Engine: aurora-mysql MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBClusterSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBClusterSecret}::password}}' DBSubnetGroupName: Ref: DBSubnetGroup BacktrackWindow: 720

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true SubnetOne: Type: AWS::EC2::Subnet Properties: VpcId: Ref: VPC CidrBlock: 10.0.0.0/25 AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: '' SubnetTwo: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.0.0.128/25 AvailabilityZone: Fn::Select: - 1 - Fn::GetAZs: '' VpcId: Ref: VPC DBSubnetGroup: Type: AWS::RDS::DBSubnetGroup Properties: DBSubnetGroupDescription: Example DB subnet group SubnetIds: - Ref: SubnetOne - Ref: SubnetTwo DBClusterSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB cluster secret GenerateSecretString: SecretStringTemplate: '{"username": "examplemasteruser"}' GenerateStringKey: password PasswordLength: 32 ExcludeCharacters: "/@\"'\\" DBCluster: Type: AWS::RDS::DBCluster Properties: Engine: aurora-mysql EngineMode: provisioned MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBClusterSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBClusterSecret}::password}}' DBSubnetGroupName: Ref: DBSubnetGroup

[CT.RDS.PR.7] Exiger que l'authentification IAM soit configurée sur les instances de base de données Amazon RDS

Ce contrôle vérifie si l'authentification de base de données (IAM) est activée sur une instance de base de données AWS Identity and Access Management (DB) Amazon RDS.

  • Objectif de contrôle : utiliser une authentification forte

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBInstance

  • AWS CloudFormationrègle de garde : CT.RDS.PR.7spécification des règles

Détails et exemples

Explication

L'authentification de base de données IAM permet d'authentifier les instances de base de données à l'aide d'un jeton d'authentification au lieu d'un mot de passe. Le trafic réseau à destination et en provenance de la base de données est crypté avec le protocole SSL.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux types de moteurs de base de données Amazon RDSmariadb, mysql etpostgres.

  • Ce contrôle s'applique uniquement lorsque la Engine propriété est fournie. Cela ne s'applique pas lors de la restauration à partir d'un instantané de base de données ou d'un instantané de cluster pour lequel un n'Enginea pas été défini explicitement.

Corrections en cas de défaillance des règles

Définissez EnableIAMDatabaseAuthentication sur true.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Instance de base de données Amazon RDS : exemple

Instance de base de données Amazon RDS configurée avec l'authentification de base de données IAM. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBInstance": { "Type": "AWS::RDS::DBInstance", "Properties": { "Engine": "postgres", "EngineVersion": 14.2, "DBInstanceClass": "db.m5.large", "StorageType": "gp2", "AllocatedStorage": 5, "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::password}}" }, "EnableIAMDatabaseAuthentication": true }, "DeletionPolicy": "Delete" } }

Exemple YAML

DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' EnableIAMDatabaseAuthentication: true DeletionPolicy: Delete

CT.RDS.PR.7spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_instance_iam_authentication_enabled_check # # Description: # This control checks whether an Amazon RDS database (DB) instance has AWS Identity and Access Management (IAM) database authentication activated. # # Reports on: # AWS::RDS::DBInstance # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any RDS DB instance resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is not in-scope database engines - 'mariadb', 'mysql', 'postgres' # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is in-scope database engines - 'mariadb', 'mysql', 'postgres' # And: 'EnableIAMDatabaseAuthentication' has not been specified # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is in-scope database engines - 'mariadb', 'mysql', 'postgres' # And: 'EnableIAMDatabaseAuthentication' has been specified # And: 'EnableIAMDatabaseAuthentication' has been set to bool(false) # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is in-scope database engines - 'mariadb', 'mysql', 'postgres' # And: 'EnableIAMDatabaseAuthentication' has been specified # And: 'EnableIAMDatabaseAuthentication' has been set to bool(true) # Then: PASS # # Constants # let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance" let INPUT_DOCUMENT = this let SUPPORTED_RDS_INSTANCE_ENGINES = ["mariadb", "mysql", "postgres"] # # Assignments # let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ] # # Primary Rules # rule rds_instance_iam_authentication_enabled_check when is_cfn_template(%INPUT_DOCUMENT) %rds_db_instances not empty { check(%rds_db_instances.Properties) << [CT.RDS.PR.7]: Require Amazon RDS database instances to have AWS IAM authentication configured [FIX]: Set 'EnableIAMDatabaseAuthentication' to 'true'. >> } rule rds_instance_iam_authentication_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties) << [CT.RDS.PR.7]: Require Amazon RDS database instances to have AWS IAM authentication configured [FIX]: Set 'EnableIAMDatabaseAuthentication' to 'true'. >> } # # Parameterized Rules # rule check(rds_db_instance) { %rds_db_instance [filter_engine(this)] { #Scenario: 3 EnableIAMDatabaseAuthentication exists #Scenario: 4 and 5 EnableIAMDatabaseAuthentication == true } } rule filter_engine(db_properties) { %db_properties { #Scenario: 2 Engine exists Engine is_string Engine in %SUPPORTED_RDS_INSTANCE_ENGINES } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

CT.RDS.PR.7exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: Test RDS DB Instance secret GenerateSecretString: SecretStringTemplate: '{"username": "testUser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' EnableIAMDatabaseAuthentication: true DeletionPolicy: Delete

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: Test RDS DB Instance secret GenerateSecretString: SecretStringTemplate: '{"username": "testUser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' EnableIAMDatabaseAuthentication: false DeletionPolicy: Delete

[CT.RDS.PR.8] Exiger la configuration des sauvegardes automatiques sur une instance de base de données Amazon RDS

Ce contrôle vérifie si les instances de base de données (DB) Amazon RDS ont activé les sauvegardes automatisées et vérifie que la période de conservation des sauvegardes est supérieure ou égale à sept (7) jours.

  • Objectif de contrôle : améliorer la résilience

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBInstance

  • AWS CloudFormationrègle de garde : CT.RDS.PR.8spécification des règles

Détails et exemples

Explication

Les sauvegardes vous aident à vous remettre plus rapidement en cas d'incident de sécurité et renforcent la résilience de vos systèmes. Amazon RDS fournit un moyen simple de configurer des instantanés quotidiens de volumes complets d'instance.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux types de moteurs de base de données Amazon RDS mariadb mysql oracle-eeoracle-ee-cdb,oracle-se2,oracle-se2-cdb,postgres,, sqlserver-eesqlserver-se, sqlserver-ex etsqlserver-web.

  • Ce contrôle s'applique uniquement lorsque la Engine propriété est fournie. Cela ne s'applique pas lors de la restauration à partir d'un instantané de base de données ou d'un instantané de cluster pour lequel un n'Enginea pas été défini explicitement.

Corrections en cas de défaillance des règles

BackupRetentionPeriodDéfini sur une valeur entière comprise entre 7 et 35 jours (inclus).

Les exemples suivants montrent comment mettre en œuvre cette correction.

Instance de base de données Amazon RDS : exemple

Instance de base de données Amazon RDS configurée avec des sauvegardes automatisées configurées et une période de conservation des sauvegardes de 14 jours. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBInstance": { "Type": "AWS::RDS::DBInstance", "Properties": { "Engine": "postgres", "EngineVersion": 14.2, "DBInstanceClass": "db.m5.large", "StorageType": "gp2", "AllocatedStorage": 5, "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::password}}" }, "BackupRetentionPeriod": 14 }, "DeletionPolicy": "Delete" } }

Exemple YAML

DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' BackupRetentionPeriod: 14 DeletionPolicy: Delete

CT.RDS.PR.8spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_instance_backup_enabled_check # # Description: # This control checks whether Amazon RDS database (DB) instances have automated backups enabled, and verifies that the backup retention period is greater than or equal to seven (7) days. # # Reports on: # AWS::RDS::DBInstance # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any RDS DB instance resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is not one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'BackupRetentionPeriod' has been specified # And: 'BackupRetentionPeriod' has been set to 0 (backup disabled) # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'BackupRetentionPeriod' has not been specified # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'BackupRetentionPeriod' has been specified # And: 'BackupRetentionPeriod' has been set to < 7 # Then: FAIL # Scenario: 6 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'BackupRetentionPeriod' has been specified # And: 'BackupRetentionPeriod' has been set to an integer >= 7 # Then: PASS # # Constants # let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance" let INPUT_DOCUMENT = this let SUPPORTED_RDS_INSTANCE_ENGINES = [ "mariadb", "mysql", "oracle-ee", "oracle-ee-cdb", "oracle-se2", "oracle-se2-cdb", "postgres", "sqlserver-ee", "sqlserver-se", "sqlserver-ex", "sqlserver-web" ] # # Assignments # let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ] # # Primary Rules # rule rds_instance_backup_enabled_check when is_cfn_template(%INPUT_DOCUMENT) %rds_db_instances not empty { check(%rds_db_instances.Properties) << [CT.RDS.PR.8]: Require an Amazon RDS database instance to have automatic backups configured [FIX]: Set 'BackupRetentionPeriod' to an integer value between 7 and 35 days (inclusive). >> } rule rds_instance_backup_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties) << [CT.RDS.PR.8]: Require an Amazon RDS database instance to have automatic backups configured [FIX]: Set 'BackupRetentionPeriod' to an integer value between 7 and 35 days (inclusive). >> } # # Parameterized Rules # rule check(rds_db_instance) { %rds_db_instance [ filter_db_identifier_and_engine(this) ] { # Scenario: 3, 4, 5 and 6 BackupRetentionPeriod exists BackupRetentionPeriod >= 7 } } rule filter_db_identifier_and_engine(db_properties) { %db_properties { # Scenario: 2 Engine exists Engine is_string Engine in %SUPPORTED_RDS_INSTANCE_ENGINES } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

CT.RDS.PR.8exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: Test RDS DB Instance secret GenerateSecretString: SecretStringTemplate: '{"username": "testUser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' BackupRetentionPeriod: 14 DeletionPolicy: Delete

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: Test RDS DB Instance secret GenerateSecretString: SecretStringTemplate: '{"username": "testUser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' BackupRetentionPeriod: 4 DeletionPolicy: Delete

[CT.RDS.PR.9] Exiger un cluster de base de données Amazon RDS pour copier des balises dans des instantanés

Ce contrôle vérifie si un cluster de base de données (DB) Amazon RDS est configuré pour copier toutes les balises dans les instantanés créés.

  • Objectif de contrôle : protéger les configurations

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBCluster

  • AWS CloudFormationrègle de garde : CT.RDS.PR.9spécification des règles

Détails et exemples

Explication

L'identification et l'inventaire de vos actifs d'infrastructure constituent un aspect crucial de la gouvernance et de la sécurité. Grâce à la visibilité de tous vos clusters de bases de données Amazon RDS, vous pouvez évaluer leur niveau de sécurité et prendre des mesures pour remédier aux points faibles potentiels. Nous vous recommandons de baliser les instantanés de la même manière que leurs clusters de base de données RDS parents. L'activation de ce paramètre garantit que les instantanés héritent des balises de leurs clusters de base de données parents.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux types de moteurs de cluster de base de données Amazon RDS auroraaurora-mysql, etaurora-postgresql.

Corrections en cas de défaillance des règles

Définissez CopyTagsToSnapshot sur true.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Cluster de bases de données Amazon RDS : exemple

Cluster de base de données Amazon RDS configuré pour copier des balises dans des instantanés. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBCluster": { "Type": "AWS::RDS::DBCluster", "Properties": { "Engine": "aurora-mysql", "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBClusterSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBClusterSecret}::password}}" }, "DBSubnetGroupName": { "Ref": "DBSubnetGroup" }, "CopyTagsToSnapshot": true } } }

Exemple YAML

DBCluster: Type: AWS::RDS::DBCluster Properties: Engine: aurora-mysql MasterUsername: !Sub '{{resolve:secretsmanager:${DBClusterSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBClusterSecret}::password}}' DBSubnetGroupName: !Ref 'DBSubnetGroup' CopyTagsToSnapshot: true

CT.RDS.PR.9spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_cluster_copy_tags_to_snapshots_enabled_check # # Description: # This control checks whether an Amazon RDS DB cluster is configured to copy all tags to snapshots created. # # Reports on: # AWS::RDS::DBCluster # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any RDS DB cluster resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'Engine' provided is not one of 'aurora' or 'aurora-mysql' or 'aurora-postgresql' # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'Engine' provided is one of 'aurora' or 'aurora-mysql' or 'aurora-postgresql' # And: 'CopyTagsToSnapshot' has not been provided # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'Engine' provided is one of 'aurora' or 'aurora-mysql' or 'aurora-postgresql' # And: 'CopyTagsToSnapshot' has been provided # And: 'CopyTagsToSnapshot' has been set to a value other than bool(true) # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'Engine' provided is one of 'aurora' or 'aurora-mysql' or 'aurora-postgresql' # And: 'CopyTagsToSnapshot' has been provided # And: 'CopyTagsToSnapshot' has been set to bool(true) # Then: PASS # # Constants # let RDS_DB_CLUSTER_TYPE = "AWS::RDS::DBCluster" let SUPPORTED_DB_CLUSTER_ENGINES = ["aurora", "aurora-mysql","aurora-postgresql"] let INPUT_DOCUMENT = this # # Assignments # let db_clusters = Resources.*[ Type == %RDS_DB_CLUSTER_TYPE ] # # Primary Rules # rule rds_cluster_copy_tags_to_snapshots_enabled_check when is_cfn_template(%INPUT_DOCUMENT) %db_clusters not empty { check(%db_clusters.Properties) << [CT.RDS.PR.9]: Require an Amazon RDS database cluster to copy tags to snapshots [FIX]: Set 'CopyTagsToSnapshot' to 'true'. >> } rule rds_cluster_copy_tags_to_snapshots_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_CLUSTER_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_CLUSTER_TYPE.resourceProperties) << [CT.RDS.PR.9]: Require an Amazon RDS database cluster to copy tags to snapshots [FIX]: Set 'CopyTagsToSnapshot' to 'true'. >> } rule check(db_cluster) { %db_cluster [ # Scenario 2 filter_engine(this) ] { # Scenario 3 CopyTagsToSnapshot exists # Scenario 4 and 5 CopyTagsToSnapshot == true } } rule filter_engine(cluster_properties) { %cluster_properties { Engine exists Engine in %SUPPORTED_DB_CLUSTER_ENGINES } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

CT.RDS.PR.9exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true SubnetOne: Type: AWS::EC2::Subnet Properties: VpcId: Ref: VPC CidrBlock: 10.0.0.0/25 AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: '' SubnetTwo: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.0.0.128/25 AvailabilityZone: Fn::Select: - 1 - Fn::GetAZs: '' VpcId: Ref: VPC DBSubnetGroup: Type: AWS::RDS::DBSubnetGroup Properties: DBSubnetGroupDescription: DB subnet group for DBCluster SubnetIds: - Ref: SubnetOne - Ref: SubnetTwo DBClusterSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB cluster secret GenerateSecretString: SecretStringTemplate: '{"username": "examplemasteruser"}' GenerateStringKey: password PasswordLength: 32 ExcludeCharacters: "/@\"'\\" DBCluster: Type: AWS::RDS::DBCluster Properties: Engine: aurora-mysql MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBClusterSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBClusterSecret}::password}}' DBSubnetGroupName: Ref: DBSubnetGroup CopyTagsToSnapshot: true

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true SubnetOne: Type: AWS::EC2::Subnet Properties: VpcId: Ref: VPC CidrBlock: 10.0.0.0/25 AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: '' SubnetTwo: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.0.0.128/25 AvailabilityZone: Fn::Select: - 1 - Fn::GetAZs: '' VpcId: Ref: VPC DBSubnetGroup: Type: AWS::RDS::DBSubnetGroup Properties: DBSubnetGroupDescription: DB subnet group for DBCluster SubnetIds: - Ref: SubnetOne - Ref: SubnetTwo DBClusterSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB cluster secret GenerateSecretString: SecretStringTemplate: '{"username": "examplemasteruser"}' GenerateStringKey: password PasswordLength: 32 ExcludeCharacters: "/@\"'\\" DBCluster: Type: AWS::RDS::DBCluster Properties: Engine: aurora-mysql MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBClusterSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBClusterSecret}::password}}' DBSubnetGroupName: Ref: DBSubnetGroup

[CT.RDS.PR.10] Exiger une instance de base de données Amazon RDS pour copier des balises dans des instantanés

Ce contrôle vérifie si les instances de base de données (DB) Amazon RDS sont configurées pour copier toutes les balises dans les instantanés créés.

  • Objectif de contrôle : protéger les configurations

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBInstance

  • AWS CloudFormationrègle de garde : CT.RDS.PR.10spécification des règles

Détails et exemples

Explication

L'identification et l'inventaire de vos actifs informatiques constituent un aspect crucial de la gouvernance et de la sécurité. Grâce à la visibilité de toutes vos instances de base de données RDS, vous pouvez évaluer leur niveau de sécurité et prendre des mesures pour remédier aux points faibles potentiels. Les instantanés doivent être balisés pour correspondre à leurs instances de base de données RDS parentes. L'activation de ce paramètre garantit que les instantanés héritent des balises de leurs instances de base de données parentes.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux types de moteurs de base de données Amazon RDS mariadb mysql oracle-eeoracle-ee-cdb,oracle-se2,oracle-se2-cdb,postgres,, sqlserver-eesqlserver-se, sqlserver-ex etsqlserver-web.

  • Ce contrôle s'applique uniquement lorsque la Engine propriété est fournie. Cela ne s'applique pas lors de la restauration à partir d'un instantané de base de données ou d'un instantané de cluster pour lequel un n'Enginea pas été défini explicitement.

Corrections en cas de défaillance des règles

Définissez CopyTagsToSnapshot sur true.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Instance de base de données Amazon RDS : exemple

Instance de base de données Amazon RDS configurée pour copier toutes les balises dans les instantanés créés. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBInstance": { "Type": "AWS::RDS::DBInstance", "Properties": { "Engine": "postgres", "EngineVersion": 14.2, "DBInstanceClass": "db.m5.large", "StorageType": "gp2", "AllocatedStorage": 5, "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::password}}" }, "CopyTagsToSnapshot": true }, "DeletionPolicy": "Delete" } }

Exemple YAML

DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' CopyTagsToSnapshot: true DeletionPolicy: Delete

CT.RDS.PR.10spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_instance_copy_tags_to_snapshots_enabled_check # # Description: # This control checks whether Amazon RDS database (DB) instances are configured to copy all tags to snapshots created. # # Reports on: # AWS::RDS::DBInstance # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any RDS DB instance resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is not one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'CopyTagsToSnapshot' has not been specified # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'CopyTagsToSnapshot' has been specified # And: 'CopyTagsToSnapshot' has been set to bool(false) # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'CopyTagsToSnapshot' has been specified # And: 'CopyTagsToSnapshot' has been set to bool(true) # Then: PASS # # Constants # let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance" let INPUT_DOCUMENT = this let SUPPORTED_RDS_INSTANCE_ENGINES = [ "mariadb", "mysql", "oracle-ee", "oracle-ee-cdb", "oracle-se2", "oracle-se2-cdb", "postgres", "sqlserver-ee", "sqlserver-se", "sqlserver-ex", "sqlserver-web" ] # # Assignments # let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ] # # Primary Rules # rule rds_instance_copy_tags_to_snapshots_enabled_check when is_cfn_template(%INPUT_DOCUMENT) %rds_db_instances not empty { check(%rds_db_instances.Properties) << [CT.RDS.PR.10]: Require an Amazon RDS database instance to copy tags to snapshots [FIX]: Set 'CopyTagsToSnapshot' to 'true'. >> } rule rds_instance_copy_tags_to_snapshots_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties) << [CT.RDS.PR.10]: Require an Amazon RDS database instance to copy tags to snapshots [FIX]: Set 'CopyTagsToSnapshot' to 'true'. >> } # # Parameterized Rules # rule check(rds_db_instance) { %rds_db_instance [filter_engine(this)] { # Scenario: 3 CopyTagsToSnapshot exists # Scenario: 4 and 5 CopyTagsToSnapshot == true } } rule filter_engine(db_properties) { %db_properties { # Scenario: 2 Engine exists Engine is_string Engine in %SUPPORTED_RDS_INSTANCE_ENGINES } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

CT.RDS.PR.10exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: Test RDS DB Instance secret GenerateSecretString: SecretStringTemplate: '{"username": "testUser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' CopyTagsToSnapshot: true DeletionPolicy: Delete

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: Test RDS DB Instance secret GenerateSecretString: SecretStringTemplate: '{"username": "testUser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' CopyTagsToSnapshot: false DeletionPolicy: Delete

[CT.RDS.PR.11] Exiger qu'une instance de base de données Amazon RDS ait une configuration VPC

Ce contrôle vérifie si une instance de base de données (DB) Amazon RDS est déployée dans un VPC (c'est-à-dire avec une instance EC2-VPC).

  • Objectif de contrôle : limiter l'accès au réseau

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBInstance

  • AWS CloudFormationrègle de garde : CT.RDS.PR.11spécification des règles

Détails et exemples

Explication

Amazon Virtual Private Cloud (Amazon VPC) fournit un certain nombre de contrôles réseau pour créer un accès sécurisé aux ressources RDS. Ces contrôles incluent les points de terminaison VPC, les ACL réseau et les groupes de sécurité. Pour tirer parti de ces contrôles, créez vos instances Amazon RDS en tant qu'instances VPC EC2.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux types de moteurs de base de données Amazon RDS mariadb mysql oracle-eeoracle-ee-cdb,oracle-se2,oracle-se2-cdb,postgres,, sqlserver-eesqlserver-se, sqlserver-ex etsqlserver-web.

  • Ce contrôle s'applique uniquement lorsque la Engine propriété est fournie. Cela ne s'applique pas lors de la restauration à partir d'un instantané de base de données ou d'un instantané de cluster pour lequel un n'Enginea pas été défini explicitement.

Corrections en cas de défaillance des règles

Définissez unDBSubnetGroupName.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Instance de base de données Amazon RDS : exemple

Instance de base de données Amazon RDS configurée pour être déployée dans un Amazon VPC avec un groupe de sous-réseaux de base de données RDS. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBInstance": { "Type": "AWS::RDS::DBInstance", "Properties": { "Engine": "postgres", "EngineVersion": 14.2, "DBInstanceClass": "db.m5.large", "StorageType": "gp2", "AllocatedStorage": 5, "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::password}}" }, "DBSubnetGroupName": { "Ref": "DBSubnetGroup" } }, "DeletionPolicy": "Delete" } }

Exemple YAML

DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' DBSubnetGroupName: !Ref 'DBSubnetGroup' DeletionPolicy: Delete

CT.RDS.PR.11spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_instance_deployed_in_vpc_check # # Description: # This control checks whether an Amazon RDS database (DB) instance is deployed in a VPC (that is, an EC2 VPC instance). # # Reports on: # AWS::RDS::DBInstance # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any RDS DB instance resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is not one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'DBSubnetGroupName' has not been specified # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'DBSubnetGroupName' has been specified but is an empty string # or invalid local reference to a DB Subnet Group # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'DBSubnetGroupName' has been specified but is a non-empty string # or valid local reference to a DB Subnet Group # Then: PASS # # Constants # let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance" let SUPPORTED_RDS_INSTANCE_ENGINES = [ "mariadb", "mysql", "oracle-ee", "oracle-ee-cdb", "oracle-se2", "oracle-se2-cdb", "postgres", "sqlserver-ee", "sqlserver-se", "sqlserver-ex", "sqlserver-web" ] let INPUT_DOCUMENT = this # # Assignments # let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ] # # Primary Rules # rule rds_instance_deployed_in_vpc_check when is_cfn_template(%INPUT_DOCUMENT) %rds_db_instances not empty { check(%rds_db_instances.Properties) << [CT.RDS.PR.11]: Require an Amazon RDS database instance to have a VPC configuration [FIX]: Set a 'DBSubnetGroupName'. >> } rule rds_instance_deployed_in_vpc_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties) << [CT.RDS.PR.11]: Require an Amazon RDS database instance to have a VPC configuration [FIX]: Set a 'DBSubnetGroupName'. >> } # # Parameterized Rules # rule check(rds_db_instance) { %rds_db_instance [filter_engine(this)] { # Scenario: 3 DBSubnetGroupName exists # Scenario: 4 and 5 check_db_subnet_group(DBSubnetGroupName) } } rule filter_engine(db_properties) { %db_properties { # Scenario: 2 Engine exists Engine is_string Engine in %SUPPORTED_RDS_INSTANCE_ENGINES } } rule check_db_subnet_group(db_subnet_group) { %db_subnet_group { check_is_string_and_not_empty(this) or check_local_references(%INPUT_DOCUMENT, this, "AWS::RDS::DBSubnetGroup") } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists } rule check_is_string_and_not_empty(value) { %value { this is_string this != /\A\s*\z/ } } rule check_local_references(doc, reference_properties, referenced_resource_type) { %reference_properties { 'Fn::GetAtt' { query_for_resource(%doc, this[0], %referenced_resource_type) <<Local Stack reference was invalid>> } or Ref { query_for_resource(%doc, this, %referenced_resource_type) <<Local Stack reference was invalid>> } } } rule query_for_resource(doc, resource_key, referenced_resource_type) { let referenced_resource = %doc.Resources[ keys == %resource_key ] %referenced_resource not empty %referenced_resource { Type == %referenced_resource_type } }

CT.RDS.PR.11exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true SubnetOne: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.0.96.0/19 AvailabilityZone: Fn::Select: - '0' - Fn::GetAZs: {Ref: 'AWS::Region'} VpcId: Ref: VPC SubnetTwo: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.0.128.0/19 AvailabilityZone: Fn::Select: - '1' - Fn::GetAZs: {Ref: 'AWS::Region'} VpcId: Ref: VPC DBSubnetGroup: Type: AWS::RDS::DBSubnetGroup Properties: DBSubnetGroupDescription: Test DB subnet group SubnetIds: - Ref: SubnetOne - Ref: SubnetTwo DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: Test RDS DB Instance secret GenerateSecretString: SecretStringTemplate: '{"username": "testUser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' DBSubnetGroupName: Ref: DBSubnetGroup DeletionPolicy: Delete

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: Test RDS DB Instance secret GenerateSecretString: SecretStringTemplate: '{"username": "testUser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' DeletionPolicy: Delete

[CT.RDS.PR.12] Nécessite un abonnement aux événements Amazon RDS pour configurer les événements critiques du cluster

Ce contrôle vérifie si vos abonnements aux événements Amazon RDS pour les clusters RDS sont configurés pour fournir des notifications sur les catégories d'événements de et maintenance failure.

  • Objectif de contrôle : protéger les configurations

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::EventSubscription

  • AWS CloudFormationrègle de garde : CT.RDS.PR.12spécification des règles

Détails et exemples

Explication

Les notifications d'événements Amazon RDS utilisent Amazon SNS pour vous informer des modifications apportées à la disponibilité ou à la configuration de vos ressources RDS. Ces notifications permettent une réponse rapide.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux abonnements aux événements Amazon RDS pour les clusters RDS (SourceTypededb-cluster).

Corrections en cas de défaillance des règles

Lorsqu'il SourceType est défini surdb-cluster, définissez sur Enabled true et assurez-vous qu'il EventCategories contient à la fois les failure valeurs maintenance et.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Abonnement aux événements Amazon RDS : premier exemple

Abonnement aux événements Amazon RDS pour les clusters RDS configurés pour envoyer des notifications sur toutes les catégories d'événements. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "RDSEventSubscription": { "Type": "AWS::RDS::EventSubscription", "Properties": { "SnsTopicArn": { "Ref": "SnsTopic" }, "SourceType": "db-cluster", "Enabled": true } } }

Exemple YAML

RDSEventSubscription: Type: AWS::RDS::EventSubscription Properties: SnsTopicArn: !Ref 'SnsTopic' SourceType: db-cluster Enabled: true

Les exemples suivants montrent comment mettre en œuvre cette correction.

Abonnement aux événements Amazon RDS : deuxième exemple

Abonnement aux événements Amazon RDS pour les clusters RDS configurés pour envoyer des notifications sur des catégories d'failureévénements maintenance et des catégories d'événements. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "RDSEventSubscription": { "Type": "AWS::RDS::EventSubscription", "Properties": { "SnsTopicArn": { "Ref": "SnsTopic" }, "EventCategories": [ "maintenance", "failure" ], "SourceType": "db-cluster", "Enabled": true } } }

Exemple YAML

RDSEventSubscription: Type: AWS::RDS::EventSubscription Properties: SnsTopicArn: !Ref 'SnsTopic' EventCategories: - maintenance - failure SourceType: db-cluster Enabled: true

CT.RDS.PR.12spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_cluster_event_notifications_configured_check # # Description: # Checks whether an Amazon RDS event subscriptions for RDS clusters is configured to notify on event categories of "maintenance" and "failure". # # Reports on: # AWS::RDS::EventSubscription # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document does not contain any Amazon RDS event subscription resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an Amazon RDS event subscription resource # And: 'SourceType' is provided and is not 'db-cluster' # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an Amazon RDS event subscription resource # And: 'SourceType' is 'db-cluster' # And: 'Enabled' is not provided or set to bool(false) # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an Amazon RDS event subscription resource # And: 'SourceType' is provided and is 'db-cluster' # And: 'Enabled' is provided and set to bool(true) # And: 'EventCategories' does not contain both 'maintenance' and 'failure' # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an Amazon RDS event subscription resource # And: 'SourceType' is provided and is 'db-cluster' # And: 'Enabled' is provided and set to bool(true) # And: 'EventCategories' does not exist or is an empty list # Then: PASS # Scenario: 6 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an Amazon RDS event subscription resource # And: 'SourceType' is provided and is 'db-cluster' # And: 'Enabled' is provided and set to bool(true) # And: 'EventCategories' contains both 'maintenance' and 'failure' # Then: PASS # # Constants # let RDS_EVENTSUBSCRIPTION_TYPE = "AWS::RDS::EventSubscription" let INPUT_DOCUMENT = this let EVENT_CATEGORIES = ["maintenance","failure"] let EVENT_SOURCE_TYPE = "db-cluster" # # Assignments # let rds_event_subscriptions = Resources.*[ Type == %RDS_EVENTSUBSCRIPTION_TYPE ] # # Primary Rules # rule rds_cluster_event_notifications_configured_check when is_cfn_template(%INPUT_DOCUMENT) %rds_event_subscriptions not empty { check(%rds_event_subscriptions.Properties) << [CT.RDS.PR.12]: Require an Amazon RDS event subscription to have critical cluster events configured [FIX]: When 'SourceType' is set to 'db-cluster', set 'Enabled' to true and ensure that 'EventCategories' contains both 'maintenance' and 'failure' values. >> } rule rds_cluster_event_notifications_configured_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_EVENTSUBSCRIPTION_TYPE) { check(%INPUT_DOCUMENT.%RDS_EVENTSUBSCRIPTION_TYPE.resourceProperties) << [CT.RDS.PR.12]: Require an Amazon RDS event subscription to have critical cluster events configured [FIX]: When 'SourceType' is set to 'db-cluster', set 'Enabled' to true and ensure that 'EventCategories' contains both 'maintenance' and 'failure' values. >> } # # Parameterized Rules # rule check(resource) { %resource [ SourceType == %EVENT_SOURCE_TYPE ] { Enabled exists # Scenario 4 Enabled == true # Scenario 5 EventCategories not exists or # Scenario 6 check_event_categories_for_required_events(EventCategories) } } rule check_event_categories_for_required_events(event_categories) { %event_categories { this exists this is_list this empty or %EVENT_CATEGORIES.* in this } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

CT.RDS.PR.12exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: SNSTopic: Type: AWS::SNS::Topic Properties: {} RDSEventSubscription: Type: AWS::RDS::EventSubscription Properties: SnsTopicArn: Ref: SNSTopic SourceType: db-cluster Enabled: true

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: SNSTopic: Type: AWS::SNS::Topic Properties: {} RDSEventSubscription: Type: AWS::RDS::EventSubscription Properties: SnsTopicArn: Ref: SNSTopic EventCategories: - maintenance - deletion SourceType: db-cluster Enabled: true

[CT.RDS.PR.13] Exiger que la protection contre les suppressions soit configurée sur n'importe quelle instance Amazon RDS

Ce contrôle vérifie si la protection contre la suppression est activée sur une instance Amazon Relational Database Service (Amazon RDS).

  • Objectif de contrôle : améliorer la disponibilité

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBInstance

  • AWS CloudFormationrègle de garde : CT.RDS.PR.13spécification des règles

Détails et exemples

Explication

Lorsqu'elle est active, la protection contre la suppression d'instance fournit un niveau de protection supplémentaire contre la suppression accidentelle de la base de données ou la suppression par une entité non autorisée.

Lorsque la protection contre la suppression est active, une instance de base de données RDS ne peut pas être supprimée. Pour qu'une demande de suppression puisse aboutir, la protection contre la suppression doit être désactivée.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux types de moteurs de base de données Amazon RDS mariadb mysql oracle-eeoracle-ee-cdb,oracle-se2,oracle-se2-cdb,postgres,, sqlserver-eesqlserver-se, sqlserver-ex etsqlserver-web.

  • Ce contrôle s'applique uniquement lorsque la Engine propriété est fournie. Cela ne s'applique pas lors de la restauration à partir d'un instantané de base de données ou d'un instantané de cluster pour lequel un n'Enginea pas été défini explicitement.

Corrections en cas de défaillance des règles

Définissez DeletionProtection sur true.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Instance de base de données Amazon RDS - Exemple

Instance de base de données Amazon RDS configurée avec la protection contre la suppression active. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBInstance": { "Type": "AWS::RDS::DBInstance", "Properties": { "Engine": "postgres", "EngineVersion": 5.7, "DBInstanceClass": "db.m5.large", "StorageType": "gp2", "AllocatedStorage": 5, "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::password}}" }, "StorageEncrypted": true, "DeletionProtection": true }, "DeletionPolicy": "Delete" } }

Exemple YAML

DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 5.7 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' StorageEncrypted: true DeletionProtection: true DeletionPolicy: Delete

CT.RDS.PR.13spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_instance_deletion_protection_enabled_check # # Description: # This control checks whether an Amazon Relational Database Service (Amazon RDS) instance has deletion protection activated. # # Reports on: # AWS::RDS::DBInstance # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any RDS DB instance resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is not one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'DeletionProtection' has not been specified # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'DeletionProtection' has been specified # And: 'DeletionProtection' has been set to bool(false) # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'DeletionProtection' has been specified # And: 'DeletionProtection' has been set to bool(true) # Then: PASS # # Constants # let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance" let INPUT_DOCUMENT = this let SUPPORTED_RDS_INSTANCE_ENGINES = [ "mariadb", "mysql", "oracle-ee", "oracle-ee-cdb", "oracle-se2", "oracle-se2-cdb", "postgres", "sqlserver-ee", "sqlserver-se", "sqlserver-ex", "sqlserver-web" ] # # Assignments # let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ] # # Primary Rules # rule rds_instance_deletion_protection_enabled_check when is_cfn_template(%INPUT_DOCUMENT) %rds_db_instances not empty { check(%rds_db_instances.Properties) << [CT.RDS.PR.13]: Require any Amazon RDS instance to have deletion protection configured [FIX]: Set 'DeletionProtection' to 'true'. >> } rule rds_instance_deletion_protection_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties) << [CT.RDS.PR.13]: Require any Amazon RDS instance to have deletion protection configured [FIX]: Set 'DeletionProtection' to 'true'. >> } # # Parameterized Rules # rule check(rds_db_instance) { %rds_db_instance [filter_engine(this)] { #Scenario: 3 DeletionProtection exists #Scenario: 4 and 5 DeletionProtection == true } } rule filter_engine(db_properties) { %db_properties { #Scenario: 2 Engine exists Engine is_string Engine in %SUPPORTED_RDS_INSTANCE_ENGINES } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

CT.RDS.PR.13exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB Instance secret GenerateSecretString: SecretStringTemplate: '{"username": "testUser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' DeletionProtection: true DeletionPolicy: Delete

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB Instance secret GenerateSecretString: SecretStringTemplate: '{"username": "testUser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' DeletionProtection: false DeletionPolicy: Delete

[CT.RDS.PR.14] Exiger une instance de base de données Amazon RDS pour exporter les journaux vers Amazon CloudWatch Logs au moyen de la propriété EnableCloudwatchLogsExports

Cette règle vérifie si tous les types de journaux disponibles des instances Amazon Relational Database Service (RDS) sont configurés pour être exportés vers Amazon Logs. CloudWatch

  • Objectif de contrôle : établir une journalisation et une surveillance

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBInstance

  • AWS CloudFormationrègle de garde : CT.RDS.PR.14spécification des règles

Détails et exemples

Explication

AWS Control Tower vous recommande d'activer l'exportation des journaux pertinents pour toutes les bases de données Amazon RDS vers Amazon CloudWatch Logs. La journalisation de la base de données fournit des enregistrements détaillés des demandes adressées à RDS. Les journaux de base de données peuvent faciliter les audits de sécurité et d'accès, et ils peuvent vous aider à diagnostiquer les problèmes de disponibilité.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux types de moteurs de base de données Amazon RDS mariadb mysql postgressqlserver-ee,sqlserver-se,sqlserver-ex,sqlserver-web,,oracle-ee, oracle-se2oracle-se1, etoracle-se.

  • Ce contrôle s'applique uniquement lorsque la Engine propriété est fournie. Cela ne s'applique pas lors de la restauration à partir d'un instantané de base de données ou d'un instantané de cluster pour lequel un n'Enginea pas été défini explicitement.

  • Des conditions supplémentaires peuvent être requises pour activer la journalisation en fonction du type de moteur de base de données sélectionné. Reportez-vous à la section Surveillance des fichiers journaux Amazon RDS dans le guide de l'utilisateur Amazon RDS pour plus d'informations.

Corrections en cas de défaillance des règles

Spécifiez EnableCloudwatchLogsExports avec une liste de tous les types de journaux pris en charge pour le moteur d'instance de base de données Amazon RDS.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Instance de base de données Amazon RDS - Exemple 1

Instance de base de données Amazon RDS configurée avec un type de moteur mysql et tous les types de journaux pris en charge, pour le type de mysql moteur. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBInstance": { "Type": "AWS::RDS::DBInstance", "Properties": { "Engine": "mysql", "EngineVersion": 5.7, "DBInstanceClass": "db.m5.large", "StorageType": "gp2", "AllocatedStorage": 5, "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::password}}" }, "StorageEncrypted": true, "EnableCloudwatchLogsExports": [ "error", "general", "slowquery", "audit" ] }, "DeletionPolicy": "Delete" } }

Exemple YAML

DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: mysql EngineVersion: 5.7 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' StorageEncrypted: true EnableCloudwatchLogsExports: - error - general - slowquery - audit DeletionPolicy: Delete

Les exemples suivants montrent comment mettre en œuvre cette correction.

Instance de base de données Amazon RDS : deuxième exemple

Instance de base de données Amazon RDS configurée avec un type de moteur postgres et tous les types de journaux pris en charge, pour le type de postgres moteur. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBInstance": { "Type": "AWS::RDS::DBInstance", "Properties": { "Engine": "postgres", "EngineVersion": 14.2, "DBInstanceClass": "db.m5.large", "StorageType": "gp2", "AllocatedStorage": 5, "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::password}}" }, "EnableCloudwatchLogsExports": [ "postgresql", "upgrade" ] }, "DeletionPolicy": "Delete" } }

Exemple YAML

DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' EnableCloudwatchLogsExports: - postgresql - upgrade DeletionPolicy: Delete

CT.RDS.PR.14spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_instance_logging_enabled_check # # Description: # This rules checks whether Amazon Relational Database Service (RDS) instances have all available log types configured for export to Amazon CloudWatch Logs. # # Reports on: # AWS::RDS::DBInstance # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any RDS DB instance resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is not one of 'mariadb', 'mysql', # 'oracle-ee', 'oracle-se2', 'oracle-ee-cdb', 'oracle-se2-cdb', # 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', # 'oracle-ee', 'oracle-se2', 'oracle-ee-cdb', 'oracle-se2-cdb', # 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'EnableCloudwatchLogsExports' has not been specified or has been specified # and is an empty list # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', # 'oracle-ee', 'oracle-se2', 'oracle-ee-cdb', 'oracle-se2-cdb', # 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'EnableCloudwatchLogsExports' has been specified and is a non-empty list # And: One or more log types in 'EnableCloudwatchLogsExports' are not supported by the specified 'Engine' # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', # 'oracle-ee', 'oracle-se2', 'oracle-ee-cdb', 'oracle-se2-cdb', # 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'EnableCloudwatchLogsExports' has been specified and is a non-empty list # And: 'EnableCloudwatchLogsExports' does not contain all log types supported by the specified 'Engine' # Then: FAIL # Scenario: 6 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql' # And: 'EnableCloudwatchLogsExports' has been specified # And: 'EnableCloudwatchLogsExports' value is a non-empty and all supported log types # are enabled - 'audit', 'error', 'general', 'slowquery' # Then: PASS # Scenario: 7 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is 'postgres' # And: 'EnableCloudwatchLogsExports' has been specified # And: 'EnableCloudwatchLogsExports' value is a non-empty and all supported log types # are enabled - 'postgresql', 'upgrade' # Then: PASS # Scenario: 8 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', # 'sqlserver-web' # And: 'EnableCloudwatchLogsExports' has been specified # And: 'EnableCloudwatchLogsExports' value is a non-empty and all supported log types # are enabled - 'agent', 'error' # Then: PASS # Scenario: 9 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'oracle-ee', 'oracle-se2', 'oracle-ee-cdb', 'oracle-se2-cdb', # And: 'EnableCloudwatchLogsExports' has been specified # And: 'EnableCloudwatchLogsExports' value is a non-empty and all supported log types # are enabled - 'alert', 'audit', 'listener', 'oemagent', 'trace' # Then: PASS # # Constants # let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance" let INPUT_DOCUMENT = this let SUPPORTED_RDS_INSTANCE_ENGINES = [ "mariadb", "mysql", "oracle-ee", "oracle-ee-cdb", "oracle-se2", "oracle-se2-cdb", "postgres", "sqlserver-ee", "sqlserver-se", "sqlserver-ex", "sqlserver-web" ] let MYSQL_OR_MARIA_ENGINES_SUBTYPES = [ "mariadb", "mysql" ] let POSTGRES_ENGINES_SUBTYPES = [ "postgres" ] let SQLSERVER_ENGINES_SUBTYPES = [ "sqlserver-ee", "sqlserver-se", "sqlserver-ex", "sqlserver-web" ] let ORACLE_ENGINES_SUBTYPES = [ "oracle-ee", "oracle-se2", "oracle-se1", "oracle-se" ] let MYSQL_OR_MARIA_SUPPORTED_LOG_TYPES = [ "audit", "error", "general", "slowquery" ] let POSTGRES_SUPPORTED_LOG_TYPES = [ "postgresql", "upgrade" ] let SQLSERVER_SUPPORTED_LOG_TYPES = [ "agent", "error" ] let ORACLE_SUPPORTED_LOG_TYPES = [ "alert", "audit", "listener", "oemagent", "trace" ] # # Assignments # let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ] # # Primary Rules # rule rds_instance_logging_enabled_check when is_cfn_template(%INPUT_DOCUMENT) %rds_db_instances not empty { check(%rds_db_instances.Properties) << [CT.RDS.PR.14]: Require an Amazon RDS database instance to have logging configured [FIX]: Specify 'EnableCloudwatchLogsExports' with a list of all supported log types for the Amazon RDS database instance engine. >> } rule rds_instance_logging_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties) << [CT.RDS.PR.14]: Require an Amazon RDS database instance to have logging configured [FIX]: Specify 'EnableCloudwatchLogsExports' with a list of all supported log types for the Amazon RDS database instance engine. >> } # # Parameterized Rules # rule check(rds_db_instance) { %rds_db_instance [filter_engine(this)] { # Scenario: 3 EnableCloudwatchLogsExports exists check_is_list_and_not_empty(EnableCloudwatchLogsExports) # Scenario: 4 and 5 when Engine IN %MYSQL_OR_MARIA_ENGINES_SUBTYPES { %MYSQL_OR_MARIA_SUPPORTED_LOG_TYPES.* IN EnableCloudwatchLogsExports[*] EnableCloudwatchLogsExports.* IN %MYSQL_OR_MARIA_SUPPORTED_LOG_TYPES[*] } # Scenario: 4 and 6 when Engine IN %POSTGRES_ENGINES_SUBTYPES { %POSTGRES_SUPPORTED_LOG_TYPES.* IN EnableCloudwatchLogsExports[*] EnableCloudwatchLogsExports.* IN %POSTGRES_SUPPORTED_LOG_TYPES[*] } # Scenario: 4 and 7 when Engine IN %SQLSERVER_ENGINES_SUBTYPES { %SQLSERVER_SUPPORTED_LOG_TYPES.* in EnableCloudwatchLogsExports[*] EnableCloudwatchLogsExports.* IN %SQLSERVER_SUPPORTED_LOG_TYPES[*] } # Scenario: 4 and 8 when Engine IN %ORACLE_ENGINES_SUBTYPES { %ORACLE_SUPPORTED_LOG_TYPES.* in EnableCloudwatchLogsExports[*] EnableCloudwatchLogsExports.* IN %ORACLE_SUPPORTED_LOG_TYPES[*] } } } rule filter_engine(db_properties) { %db_properties { # Scenario: 2 Engine exists Engine in %SUPPORTED_RDS_INSTANCE_ENGINES } } # # Utility Rules # rule check_is_list_and_not_empty(value) { %value { this is_list this not empty } } rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

CT.RDS.PR.14exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB instance secret GenerateSecretString: SecretStringTemplate: '{"username": "examplemasteruser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: mysql EngineVersion: 5.7 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' StorageEncrypted: true EnableCloudwatchLogsExports: - error - general - slowquery - audit DeletionPolicy: Delete

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB instance secret GenerateSecretString: SecretStringTemplate: '{"username": "examplemasteruser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: mysql EngineVersion: 5.7 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' StorageEncrypted: true EnableCloudwatchLogsExports: - error - general - slowquery DeletionPolicy: Delete

[CT.RDS.PR.15] Exiger qu'une instance Amazon RDS ne crée pas de groupes de sécurité de base de données

Ce contrôle vérifie si des groupes de sécurité de base de données (DB) Amazon Relational Database Service (RDS) sont créés par ou associés à une instance de base de données RDS, car les groupes de sécurité de base de données sont destinés à la plate-forme EC2-Classic uniquement.

  • Objectif de contrôle : limiter l'accès au réseau

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources :AWS::RDS::DBInstance, AWS::RDS::DBSecurityGroup

  • AWS CloudFormationrègle de garde : Spécification de la règle CT.RDS.PR.15

Détails et exemples

Explication

Nous recommandons que toutes les bases de données Amazon Relational Database Service (RDS) utilisent les groupes de sécurité Amazon VPC pour sécuriser leur accès. Les groupes de sécurité Amazon DB sont réservés à la plateforme EC2-Classic et leur utilisation n'est pas recommandée.

Corrections en cas de défaillance des règles

Omettez la DBSecurityGroups propriété. Configurez plutôt les groupes de sécurité Amazon VPC au moyen de la VPCSecurityGroups propriété.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Instance de base de données Amazon RDS : exemple

Instance de base de données Amazon RDS configurée avec un groupe de sécurité Amazon VPC. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBInstance": { "Type": "AWS::RDS::DBInstance", "Properties": { "Engine": "mysql", "EngineVersion": 5.7, "DBInstanceClass": "db.t3.small", "StorageType": "gp2", "AllocatedStorage": 5, "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::password}}" }, "StorageEncrypted": true, "Port": 6733, "DBSubnetGroupName": { "Ref": "DBSubnetGroup" }, "VPCSecurityGroups": [ { "Ref": "SecurityGroup" } ] } } }

Exemple YAML

DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: mysql EngineVersion: 5.7 DBInstanceClass: db.t3.small StorageType: gp2 AllocatedStorage: 5 MasterUsername: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' StorageEncrypted: true Port: 6733 DBSubnetGroupName: !Ref 'DBSubnetGroup' VPCSecurityGroups: - !Ref 'SecurityGroup'

Spécification de la règle CT.RDS.PR.15

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_db_security_group_not_allowed_check # # Description: # This control checks whether any Amazon Relational Database Service (RDS) database (DB) security groups are created by, or associated to, an RDS DB instance, because DB security groups are intended for the EC2-Classic platform only. # # Reports on: # AWS::RDS::DBSecurityGroup, AWS::RDS::DBInstance # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any DB security group resources # And: The input document does not contain any RDS DB instance resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a DB security group resource # Then: FAIL # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any DBsecurity group resources # And: The input document contains an RDS DB instance resource # And: 'DBSecurityGroups' has been specified on the RDS DB instance as a non empty list # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any DB security group resources # And: The input document contains an RDS DB instance resource # And: 'DBSecurityGroups' has not been specified on the RDS DB instance or specified as an empty list # Then: PASS # # Constants # let DB_INSTANCE_TYPE = "AWS::RDS::DBInstance" let DB_SECURITY_GROUP_TYPE = "AWS::RDS::DBSecurityGroup" let INPUT_DOCUMENT = this # # Assignments # let db_instances = Resources.*[ Type == %DB_INSTANCE_TYPE ] let db_security_groups = Resources.*[ Type == %DB_SECURITY_GROUP_TYPE ] # # Primary Rules # rule rds_db_security_group_not_allowed_check when is_cfn_template(this) %db_security_groups not empty { check_db_security_group(%db_security_groups) << [CT.RDS.PR.15]: Require that an Amazon RDS instance does not create DB security groups [FIX]: Omit the 'DBSecurityGroups' property. Instead, configure Amazon VPC security groups by means of the 'VPCSecurityGroups' property. >> } rule rds_db_security_group_not_allowed_check when is_cfn_template(this) %db_instances not empty { check_db_instance(%db_instances.Properties) << [CT.RDS.PR.15]: Require that an Amazon RDS instance does not create DB security groups [FIX]: Omit the 'DBSecurityGroups' property. Instead, configure Amazon VPC security groups by means of the 'VPCSecurityGroups' property. >> } rule rds_db_security_group_not_allowed_check when is_cfn_hook(%INPUT_DOCUMENT, %DB_SECURITY_GROUP_TYPE) { check_db_security_group(%INPUT_DOCUMENT.%DB_SECURITY_GROUP_TYPE) << [CT.RDS.PR.15]: Require that an Amazon RDS instance does not create DB security groups [FIX]: Omit the 'DBSecurityGroups' property. Instead, configure Amazon VPC security groups by means of the 'VPCSecurityGroups' property. >> } rule rds_db_security_group_not_allowed_check when is_cfn_hook(%INPUT_DOCUMENT, %DB_INSTANCE_TYPE) { check_db_instance(%INPUT_DOCUMENT.%DB_INSTANCE_TYPE.resourceProperties) << [CT.RDS.PR.15]: Require that an Amazon RDS instance does not create DB security groups [FIX]: Omit the 'DBSecurityGroups' property. Instead, configure Amazon VPC security groups by means of the 'VPCSecurityGroups' property. >> } # # Parameterized Rules # rule check_db_security_group(db_security_group) { # Scenario 2 %db_security_group empty } rule check_db_instance(db_instance) { %db_instance { # Scenario 3 and 4 DBSecurityGroups not exists or check_is_empty_list(this) } } rule check_is_empty_list(db_instance_configuration) { %db_instance_configuration { DBSecurityGroups is_list DBSecurityGroups empty } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

CT.RDS.PR.15exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true SubnetOne: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.0.96.0/19 AvailabilityZone: Fn::Select: - '0' - Fn::GetAZs: {Ref: 'AWS::Region'} VpcId: Ref: VPC SubnetTwo: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.0.128.0/19 AvailabilityZone: Fn::Select: - '1' - Fn::GetAZs: {Ref: 'AWS::Region'} VpcId: Ref: VPC DBSubnetGroup: Type: AWS::RDS::DBSubnetGroup Properties: DBSubnetGroupDescription: DB subnet group SubnetIds: - Ref: SubnetOne - Ref: SubnetTwo DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB instance secret GenerateSecretString: SecretStringTemplate: '{"username": "examplemasterusername"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Example Security Group VpcId: Ref: VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 6733 ToPort: 6733 CidrIp: 10.0.0.0/16 DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: mysql EngineVersion: 5.7 DBInstanceClass: db.t3.small StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' StorageEncrypted: true Port: 6733 DBSubnetGroupName: Ref: DBSubnetGroup VPCSecurityGroups: - Ref: SecurityGroup DeletionPolicy: Delete

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: DBSecurityGroup: Type: AWS::RDS::DBSecurityGroup Properties: DBSecurityGroupIngress: - CIDRIP: "0.0.0.0/0" GroupDescription: "Ingress for Amazon EC2 security group"

[CT.RDS.PR.16] Exiger que le chiffrement au repos soit configuré sur un cluster de bases de données Amazon RDS

Ce contrôle vérifie si le chiffrement du stockage est configuré sur les clusters de base de données (DB) Amazon Relational Database Service (RDS) qui ne sont pas restaurés à partir d'un cluster existant.

  • Objectif de contrôle : crypter les données au repos

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBCluster

  • AWS CloudFormationrègle de garde : CT.RDS.PR.16spécification des règles

Détails et exemples

Explication

Nous vous recommandons de configurer vos clusters de base de données Amazon RDS pour qu'ils soient chiffrés au repos, afin de renforcer la sécurité de vos données sensibles. Pour chiffrer vos clusters de base de données RDS et vos instantanés au repos, activez l'option de chiffrement pour vos clusters de base de données RDS. Les données chiffrées au repos incluent le stockage sous-jacent pour les clusters de bases de données, ses sauvegardes automatisées, ses répliques de lecture et ses instantanés.

Les clusters de base de données RDS chiffrés utilisent l'algorithme de chiffrement standard ouvert AES-256 pour chiffrer vos données sur le serveur qui héberge les clusters. Une fois vos données chiffrées, Amazon RDS gère l'authentification de l'accès et le déchiffrement de vos données avec un impact minimal sur les performances. Vous n'avez pas besoin de modifier vos applications clientes de base de données pour utiliser le chiffrement.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux clusters de base de données Amazon RDS qui ne sont pas restaurés à partir d'un cluster existant ou créés en tant que réplique en lecture. (Par exemple, quand SourceDBClusterIdentifier ou ReplicationSourceIdentifier des propriétés ont été fournies.)

Corrections en cas de défaillance des règles

Définissez StorageEncrypted sur true.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Cluster de bases de données Amazon RDS : exemple

Cluster de base de données Amazon RDS configuré avec le chiffrement du stockage activé. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBCluster": { "Type": "AWS::RDS::DBCluster", "Properties": { "Engine": "aurora-mysql", "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBClusterSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBClusterSecret}::password}}" }, "StorageEncrypted": true } } }

Exemple YAML

DBCluster: Type: AWS::RDS::DBCluster Properties: Engine: aurora-mysql MasterUsername: !Sub '{{resolve:secretsmanager:${DBClusterSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBClusterSecret}::password}}' StorageEncrypted: true

CT.RDS.PR.16spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_cluster_storage_encrypted_check # # Description: # This control checks whether the storage encryption is configured on Amazon Relational Database Service (RDS) database (DB) clusters that are not being restored from an existing cluster. # # Reports on: # AWS::RDS::DBCluster # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any RDS DB cluster resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'SourceDBClusterIdentifier' or 'ReplicationSourceIdentifier' has been provided # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'SourceDBClusterIdentifier' or 'ReplicationSourceIdentifier' has not been provided # And: 'StorageEncrypted' has not been provided # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'SourceDBClusterIdentifier' or 'ReplicationSourceIdentifier' has not been provided # And: 'StorageEncrypted' has been provided and set to bool(false) # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'SourceDBClusterIdentifier' or 'ReplicationSourceIdentifier' has not been provided # And: 'StorageEncrypted' has been provided and set to bool(true) # Then: PASS # # Constants # let RDS_CLUSTER_TYPE = "AWS::RDS::DBCluster" let INPUT_DOCUMENT = this # # Assignments # let rds_cluster = Resources.*[ Type == %RDS_CLUSTER_TYPE ] # # Primary Rules # rule rds_cluster_storage_encrypted_check when is_cfn_template(%INPUT_DOCUMENT) %rds_cluster not empty { check(%rds_cluster.Properties) << [CT.RDS.PR.16]: Require an Amazon RDS database cluster to have encryption at rest configured [FIX]: Set 'StorageEncrypted' to 'true'. >> } rule rds_cluster_storage_encrypted_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_CLUSTER_TYPE) { check(%INPUT_DOCUMENT.%RDS_CLUSTER_TYPE.resourceProperties) << [CT.RDS.PR.16]: Require an Amazon RDS database cluster to have encryption at rest configured [FIX]: Set 'StorageEncrypted' to 'true'. >> } # # Parameterized Rules # rule check(rds_cluster) { %rds_cluster [ # Scenario 2 filter_sources(this) ] { # Scenario 3 StorageEncrypted exists # Scenario 4 and 5 StorageEncrypted == true } } rule filter_sources(rds_cluster) { %rds_cluster { # Scenario 2 SourceDBClusterIdentifier not exists or filter_property_is_empty_string(SourceDBClusterIdentifier) or filter_is_not_valid_local_reference(%INPUT_DOCUMENT, SourceDBClusterIdentifier, "AWS::RDS::DBCluster") ReplicationSourceIdentifier not exists or filter_property_is_empty_string(ReplicationSourceIdentifier) or filter_replication_source_identifier(ReplicationSourceIdentifier) } } rule filter_property_is_empty_string(value) { %value { this is_string this == /\A\s*\z/ } } rule filter_is_not_valid_local_reference(doc, reference_properties, referenced_resource_type) { %reference_properties { this not is_string this is_struct when this.'Ref' exists { 'Ref' { when query_for_resource(%doc, this, %referenced_resource_type) { this not exists } this exists } } when this.'Ref' not exists { this exists } } } rule filter_replication_source_identifier(reference_properties) { filter_is_not_valid_local_reference_via_join(%INPUT_DOCUMENT, %reference_properties, "AWS::RDS::DBCluster") filter_is_not_valid_local_reference_via_join(%INPUT_DOCUMENT, %reference_properties, "AWS::RDS::DBInstance") } rule filter_is_not_valid_local_reference_via_join(doc, reference_properties, referenced_resource_type) { %reference_properties { this not is_string this is_struct when this.'Fn::Join' exists { 'Fn::Join' { when filter_list_contains_valid_local_reference(this[1], %doc, %referenced_resource_type) { this not exists } this exists } } when this.'Fn::Join' not exists { this exists } } } rule filter_list_contains_valid_local_reference(list, doc, referenced_resource_type) { some %list.* { check_local_references(%doc, this, %referenced_resource_type) } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists } rule check_local_references(doc, reference_properties, referenced_resource_type) { %reference_properties { 'Fn::GetAtt' { query_for_resource(%doc, this[0], %referenced_resource_type) <<Local Stack reference was invalid>> } or Ref { query_for_resource(%doc, this, %referenced_resource_type) <<Local Stack reference was invalid>> } } } rule query_for_resource(doc, resource_key, referenced_resource_type) { let referenced_resource = %doc.Resources[ keys == %resource_key ] %referenced_resource not empty %referenced_resource { Type == %referenced_resource_type } }

CT.RDS.PR.16exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: DBClusterSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS Cluster secret GenerateSecretString: SecretStringTemplate: '{"username": "examplemasteruser"}' GenerateStringKey: password PasswordLength: 16 ExcludeCharacters: '"@/\' DBCluster: Type: AWS::RDS::DBCluster Properties: Engine: aurora-mysql MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBClusterSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBClusterSecret}::password}}' StorageEncrypted: true

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: DBClusterSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS Cluster secret GenerateSecretString: SecretStringTemplate: '{"username": "examplemasteruser"}' GenerateStringKey: password PasswordLength: 16 ExcludeCharacters: '"@/\' DBCluster: Type: AWS::RDS::DBCluster Properties: Engine: aurora-mysql MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBClusterSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBClusterSecret}::password}}' StorageEncrypted: false

[CT.RDS.PR.17] Exigez un abonnement aux notifications d'événements Amazon RDS pour configurer les événements critiques de l'instance de base de données

Ce contrôle vérifie si vos abonnements aux événements Amazon RDS pour les instances RDS sont configurés pour fournir des notifications sur les catégories d'événements de maintenancefailure, et. configuration change

  • Objectif de contrôle : protéger les configurations

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::EventSubscription

  • AWS CloudFormationrègle de garde : CT.RDS.PR.17spécification des règles

Détails et exemples

Explication

Les notifications d'événements Amazon RDS utilisent Amazon SNS pour vous informer des modifications apportées à la disponibilité ou à la configuration de vos ressources RDS. Ces notifications permettent une réponse rapide.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux abonnements aux événements Amazon RDS pour les instances RDS (SourceTypededb-instance).

Corrections en cas de défaillance des règles

Lorsqu'il SourceType est défini surdb-instance, Enabled définissez-le sur true et assurez-vous que le paramètre EventCategories contient des configuration change valeurs maintenancefailure, et.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Abonnement aux événements Amazon RDS : premier exemple

Abonnement aux événements Amazon RDS pour les instances RDS configurées pour envoyer des notifications sur toutes les catégories d'événements. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "RDSEventSubscription": { "Type": "AWS::RDS::EventSubscription", "Properties": { "SnsTopicArn": { "Ref": "SnsTopic" }, "SourceType": "db-instance", "Enabled": true } } }

Exemple YAML

RDSEventSubscription: Type: AWS::RDS::EventSubscription Properties: SnsTopicArn: !Ref 'SnsTopic' SourceType: db-instance Enabled: true

Les exemples suivants montrent comment mettre en œuvre cette correction.

Abonnement aux événements Amazon RDS : deuxième exemple

Abonnement aux événements Amazon RDS pour les instances RDS configurées pour envoyer des notifications sur maintenancefailure, et catégories d'configuration changeévénements. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "RDSEventSubscription": { "Type": "AWS::RDS::EventSubscription", "Properties": { "SnsTopicArn": { "Ref": "SnsTopic" }, "EventCategories": [ "maintenance", "failure", "configuration change" ], "SourceType": "db-instance", "Enabled": true } } }

Exemple YAML

RDSEventSubscription: Type: AWS::RDS::EventSubscription Properties: SnsTopicArn: !Ref 'SnsTopic' EventCategories: - maintenance - failure - configuration change SourceType: db-instance Enabled: true

CT.RDS.PR.17spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_instance_event_notifications_configured_check # # Description: # Checks whether Amazon RDS event subscriptions for RDS instances are configured to notify on event categories of 'maintenance', 'failure', and 'configuration change'. # # Reports on: # AWS::RDS::EventSubscription # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document does not contain any Amazon RDS event subscription Resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an Amazon RDS event subscription resource # And: 'SourceType' is provided and is not 'db-instance' # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an Amazon RDS event subscription resource # And: 'SourceType' is 'db-instance' # And: 'Enabled' is not provided or set to bool(false) # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an Amazon RDS event subscription resource # And: 'SourceType' is provided and is 'db-instance' # And: 'Enabled' is provided and set to bool(true) # And: 'EventCategories' does not contain 'maintenance', 'failure', and 'configuration change' # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an Amazon RDS event subscription resource # And: 'SourceType' is provided and is 'db-instance' # And: 'Enabled' is provided and set to bool(true) # And: 'EventCategories' does not exist or is an empty list # Then: PASS # Scenario: 6 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an Amazon RDS event subscription resource # And: 'SourceType' is provided and is 'db-instance' # And: 'Enabled' is provided and set to bool(true) # And: 'EventCategories' contains 'maintenance', 'failure', and 'configuration change' # Then: PASS # # Constants # let RDS_EVENTSUBSCRIPTION_TYPE = "AWS::RDS::EventSubscription" let INPUT_DOCUMENT = this let EVENT_CATEGORIES = ["maintenance","failure","configuration change"] let EVENT_SOURCE_TYPE = "db-instance" # # Assignments # let rds_event_subscriptions = Resources.*[ Type == %RDS_EVENTSUBSCRIPTION_TYPE ] # # Primary Rules # rule rds_instance_event_notifications_configured_check when is_cfn_template(%INPUT_DOCUMENT) %rds_event_subscriptions not empty { check(%rds_event_subscriptions.Properties) << [CT.RDS.PR.17]: Require an Amazon RDS event notification subscription to have critical database instance events configured [FIX]: When 'SourceType' is set to 'db-instance', set 'Enabled' to true and ensure that the parameter 'EventCategories' contains 'maintenance', 'failure', and 'configuration change' values. >> } rule rds_instance_event_notifications_configured_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_EVENTSUBSCRIPTION_TYPE) { check(%INPUT_DOCUMENT.%RDS_EVENTSUBSCRIPTION_TYPE.resourceProperties) << [CT.RDS.PR.17]: Require an Amazon RDS event notification subscription to have critical database instance events configured [FIX]: When 'SourceType' is set to 'db-instance', set 'Enabled' to true and ensure that the parameter 'EventCategories' contains 'maintenance', 'failure', and 'configuration change' values. >> } # # Parameterized Rules # rule check(resource) { %resource [ SourceType == %EVENT_SOURCE_TYPE ] { Enabled exists # Scenario 4 Enabled == true # Scenario 5 EventCategories not exists or # Scenario 6 check_event_categories_for_required_events(EventCategories) } } rule check_event_categories_for_required_events(event_categories) { %event_categories { this exists this is_list this empty or %EVENT_CATEGORIES.* in this } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

CT.RDS.PR.17exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: SNSTopic: Type: AWS::SNS::Topic Properties: {} RDSEventSubscription: Type: AWS::RDS::EventSubscription Properties: SnsTopicArn: Ref: SNSTopic SourceType: db-instance Enabled: true

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: SNSTopic: Type: AWS::SNS::Topic Properties: {} RDSEventSubscription: Type: AWS::RDS::EventSubscription Properties: SnsTopicArn: Ref: SNSTopic EventCategories: - maintenance - failure SourceType: db-instance Enabled: true

[CT.RDS.PR.18] Exigez un abonnement aux notifications d'événements Amazon RDS pour configurer les événements critiques des groupes de paramètres de base de données

Ce contrôle vérifie si vos abonnements aux événements Amazon RDS pour les groupes de paramètres RDS sont configurés pour notifier les catégories d'événements de configuration change.

  • Objectif de contrôle : protéger les configurations

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::EventSubscription

  • AWS CloudFormationrègle de garde : CT.RDS.PR.18spécification des règles

Détails et exemples

Explication

Les notifications d'événements Amazon RDS utilisent Amazon SNS pour vous informer des modifications apportées à la disponibilité ou à la configuration de vos ressources RDS. Ces notifications permettent une réponse rapide.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux abonnements aux événements Amazon RDS pour les groupes de paramètres RDS (SourceTypededb-parameter-group).

Corrections en cas de défaillance des règles

Lorsqu'il SourceType est défini surdb-parameter-group, Enabled définissez-le sur true et assurez-vous que le paramètre EventCategories contient configuration change une valeur.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Abonnement aux événements Amazon RDS : premier exemple

Abonnement aux événements Amazon RDS pour les groupes de paramètres RDS configurés pour envoyer des notifications sur toutes les catégories d'événements. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "RDSEventSubscription": { "Type": "AWS::RDS::EventSubscription", "Properties": { "SnsTopicArn": { "Ref": "SnsTopic" }, "SourceType": "db-parameter-group", "Enabled": true } } }

Exemple YAML

RDSEventSubscription: Type: AWS::RDS::EventSubscription Properties: SnsTopicArn: !Ref 'SnsTopic' SourceType: db-parameter-group Enabled: true

Les exemples suivants montrent comment mettre en œuvre cette correction.

Abonnement aux événements Amazon RDS : deuxième exemple

Abonnement aux événements Amazon RDS pour les groupes de paramètres RDS configurés pour envoyer des notifications sur la catégorie d'configuration changeévénement. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "RDSEventSubscription": { "Type": "AWS::RDS::EventSubscription", "Properties": { "SnsTopicArn": { "Ref": "SnsTopic" }, "EventCategories": [ "configuration change" ], "SourceType": "db-parameter-group", "Enabled": true } } }

Exemple YAML

RDSEventSubscription: Type: AWS::RDS::EventSubscription Properties: SnsTopicArn: !Ref 'SnsTopic' EventCategories: - configuration change SourceType: db-parameter-group Enabled: true

CT.RDS.PR.18spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_pg_event_notifications_configured_check # # Description: # Checks whether Amazon RDS event subscriptions for RDS parameter groups are configured to notify on event categories of 'configuration change'. # # Reports on: # AWS::RDS::EventSubscription # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document does not contain any RDS event subscription resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an RDS event subscription resource # And: 'SourceType' is provided and is not 'db-parameter-group' # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an RDS event subscription resource # And: 'SourceType' is 'db-parameter-group' # And: 'Enabled' is not provided or set to bool(false) # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an RDS event subscription resource # And: 'SourceType' is provided and is 'db-parameter-group' # And: 'Enabled' is provided and set to bool(true) # And: 'EventCategories' does not contain 'configuration change' # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an RDS event subscription resource # And: 'SourceType' is provided and is 'db-parameter-group' # And: 'Enabled' is provided and set to bool(true) # And: 'EventCategories' does not exist or is an empty list # Then: PASS # Scenario: 6 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an RDS event subscription resource # And: 'SourceType' is provided and is 'db-parameter-group' # And: 'Enabled' is provided and set to bool(true) # And: 'EventCategories' contains 'configuration change' # Then: PASS # # Constants # let RDS_EVENTSUBSCRIPTION_TYPE = "AWS::RDS::EventSubscription" let INPUT_DOCUMENT = this let EVENT_CATEGORIES = ["configuration change"] let EVENT_SOURCE_TYPE = "db-parameter-group" # # Assignments # let rds_event_subscriptions = Resources.*[ Type == %RDS_EVENTSUBSCRIPTION_TYPE ] # # Primary Rules # rule rds_pg_event_notifications_configured_check when is_cfn_template(%INPUT_DOCUMENT) %rds_event_subscriptions not empty { check(%rds_event_subscriptions.Properties) << [CT.RDS.PR.18]: Require an Amazon RDS event notification subscription to have critical database parameter group events configured [FIX]: When 'SourceType' is set to 'db-parameter-group', set 'Enabled' to true and ensure that the parameter 'EventCategories' contains 'configuration change' as a value. >> } rule rds_pg_event_notifications_configured_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_EVENTSUBSCRIPTION_TYPE) { check(%INPUT_DOCUMENT.%RDS_EVENTSUBSCRIPTION_TYPE.resourceProperties) << [CT.RDS.PR.18]: Require an Amazon RDS event notification subscription to have critical database parameter group events configured [FIX]: When 'SourceType' is set to 'db-parameter-group', set 'Enabled' to true and ensure that the parameter 'EventCategories' contains 'configuration change' as a value. >> } # # Parameterized Rules # rule check(resource) { %resource [ SourceType == %EVENT_SOURCE_TYPE ] { Enabled exists # Scenario 4 Enabled == true # Scenario 5 EventCategories not exists or # Scenario 6 check_event_categories_for_required_events(EventCategories) } } rule check_event_categories_for_required_events(event_categories) { %event_categories { this exists this is_list this empty or %EVENT_CATEGORIES.* in this } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

CT.RDS.PR.18exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: SNSTopic: Type: AWS::SNS::Topic Properties: {} RDSEventSubscription: Type: AWS::RDS::EventSubscription Properties: SnsTopicArn: Ref: SNSTopic SourceType: db-parameter-group Enabled: true

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: SNSTopic: Type: AWS::SNS::Topic Properties: {} RDSEventSubscription: Type: AWS::RDS::EventSubscription Properties: SnsTopicArn: Ref: SNSTopic Enabled: false SourceType: db-parameter-group

[CT.RDS.PR.19] Exigez un abonnement aux notifications d'événements Amazon RDS pour configurer les événements critiques des groupes de sécurité de base de données

Ce contrôle vérifie si vos abonnements aux événements Amazon RDS pour les groupes de sécurité RDS sont configurés pour fournir des notifications sur les catégories d'événements de et failure configuration change

  • Objectif de contrôle : protéger les configurations

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::EventSubscription

  • AWS CloudFormationrègle de garde : CT.RDS.PR.19spécification des règles

Détails et exemples

Explication

Les notifications d'événements Amazon RDS utilisent Amazon SNS pour vous informer des modifications apportées à la disponibilité ou à la configuration de vos ressources RDS. Ces notifications permettent une réponse rapide.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux abonnements aux événements Amazon RDS pour les groupes de sécurité RDS (SourceTypede) db-security-group

Corrections en cas de défaillance des règles

Quand SourceType est défini surdb-security-group, réglez sur true et assurez-vous que le paramètre EventCategories contient Enabled à la fois des configuration change valeurs failure et des valeurs.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Abonnement aux événements Amazon RDS : premier exemple

Abonnement aux événements Amazon RDS pour les groupes de sécurité RDS configurés pour envoyer des notifications sur toutes les catégories d'événements. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "RDSEventSubscription": { "Type": "AWS::RDS::EventSubscription", "Properties": { "SnsTopicArn": { "Ref": "SnsTopic" }, "SourceType": "db-security-group", "Enabled": true } } }

Exemple YAML

RDSEventSubscription: Type: AWS::RDS::EventSubscription Properties: SnsTopicArn: !Ref 'SnsTopic' SourceType: db-security-group Enabled: true

Les exemples suivants montrent comment mettre en œuvre cette correction.

Abonnement aux événements Amazon RDS : deuxième exemple

Abonnement aux événements Amazon RDS pour les groupes de sécurité RDS configurés pour envoyer des notifications sur des catégories d'configuration changeévénements failure et des catégories d'événements. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "RDSEventSubscription": { "Type": "AWS::RDS::EventSubscription", "Properties": { "SnsTopicArn": { "Ref": "SnsTopic" }, "EventCategories": [ "failure", "configuration change" ], "SourceType": "db-security-group", "Enabled": true } } }

Exemple YAML

RDSEventSubscription: Type: AWS::RDS::EventSubscription Properties: SnsTopicArn: !Ref 'SnsTopic' EventCategories: - failure - configuration change SourceType: db-security-group Enabled: true

CT.RDS.PR.19spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_sg_event_notifications_configured_check # # Description: # Checks whether an Amazon RDS event subscription for RDS security groups are configured to notify on event categories of 'failure' and 'configuration change'. # # Reports on: # AWS::RDS::EventSubscription # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document does not contain any Amazon RDS event subscription resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an Amazon RDS event subscription Resource # And: 'SourceType' is provided and is not 'db-security-group' # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an Amazon RDS event subscription resource # And: 'SourceType' is 'db-security-group' # And: 'Enabled' is not provided or set to bool(false) # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an Amazon RDS event subscription resource # And: 'SourceType' is provided and is 'db-security-group' # And: 'Enabled' is provided and set to bool(true) # And: 'EventCategories' does not contain both 'failure' and 'configuration change' # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an Amazon RDS event subscription resource # And: 'SourceType' is provided and is 'db-security-group' # And: 'Enabled' is provided and set to bool(true) # And: 'EventCategories' does not exist or is an empty list # Then: PASS # Scenario: 6 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an Amazon RDS event subscription resource # And: 'SourceType' is provided and is 'db-security-group' # And: 'Enabled' is provided and set to bool(true) # And: 'EventCategories' contains both 'failure' and 'configuration change' # Then: PASS # # Constants # let RDS_EVENTSUBSCRIPTION_TYPE = "AWS::RDS::EventSubscription" let INPUT_DOCUMENT = this let EVENT_CATEGORIES = ["failure","configuration change"] let EVENT_SOURCE_TYPE = "db-security-group" # # Assignments # let rds_event_subscriptions = Resources.*[ Type == %RDS_EVENTSUBSCRIPTION_TYPE ] # # Primary Rules # rule rds_sg_event_notifications_configured_check when is_cfn_template(%INPUT_DOCUMENT) %rds_event_subscriptions not empty { check(%rds_event_subscriptions.Properties) << [CT.RDS.PR.19]: Require an Amazon RDS event notifications subscription to have critical database security group events configured [FIX]: When 'SourceType' is set to 'db-security-group', set 'Enabled' to true and ensure that the parameter 'EventCategories' contains both 'failure' and 'configuration change' values. >> } rule rds_sg_event_notifications_configured_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_EVENTSUBSCRIPTION_TYPE) { check(%INPUT_DOCUMENT.%RDS_EVENTSUBSCRIPTION_TYPE.resourceProperties) << [CT.RDS.PR.19]: Require an Amazon RDS event notifications subscription to have critical database security group events configured [FIX]: When 'SourceType' is set to 'db-security-group', set 'Enabled' to true and ensure that the parameter 'EventCategories' contains both 'failure' and 'configuration change' values. >> } # # Parameterized Rules # rule check(resource) { %resource [ SourceType == %EVENT_SOURCE_TYPE ] { Enabled exists # Scenario 4 Enabled == true # Scenario 5 EventCategories not exists or # Scenario 6 check_event_categories_for_required_events(EventCategories) } } rule check_event_categories_for_required_events(event_categories) { %event_categories { this exists this is_list this empty or %EVENT_CATEGORIES.* in this } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

CT.RDS.PR.19exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: SNSTopic: Type: AWS::SNS::Topic Properties: {} RDSEventSubscription: Type: AWS::RDS::EventSubscription Properties: SnsTopicArn: Ref: SNSTopic SourceType: db-security-group Enabled: true

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: SNSTopic: Type: AWS::SNS::Topic Properties: {} RDSEventSubscription: Type: AWS::RDS::EventSubscription Properties: SnsTopicArn: Ref: SNSTopic EventCategories: - failure SourceType: db-security-group Enabled: true

[CT.RDS.PR.20] Exiger qu'une instance de base de données Amazon RDS n'utilise pas le port par défaut d'un moteur de base de données

Ce contrôle vérifie si les instances de base de données Amazon Relational Database Service (RDS) sont configurées pour le port de base de données par défaut pour leurs types de moteurs spécifiques.

  • Objectif de contrôle : limiter l'accès au réseau

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBInstance

  • AWS CloudFormationrègle de garde : CT.RDS.PR.20spécification des règles

Détails et exemples

Explication

Si vous utilisez un port connu pour déployer un cluster ou une instance Amazon RDS, un attaquant peut deviner des informations sur le cluster ou l'instance. L'attaquant peut utiliser ces informations conjointement avec d'autres informations pour se connecter à un cluster ou à une instance Amazon RDS, ou pour obtenir des informations supplémentaires sur votre application.

Lorsque vous modifiez le port, vous devez également mettre à jour les chaînes de connexion existantes utilisées pour vous connecter à l'ancien port. Vous devez également vérifier le groupe de sécurité de l'instance de base de données pour vous assurer qu'il inclut une règle d'entrée qui autorise la connectivité sur le nouveau port.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux types de moteurs de base de données Amazon RDS mariadb mysql oracle-eeoracle-se2,oracle-ee-cdb,oracle-se2-cdb,postgres,, sqlserver-eesqlserver-se, sqlserver-ex etsqlserver-web.

  • Ce contrôle s'applique uniquement lorsque la Engine propriété est fournie. Cela ne s'applique pas lors de la restauration à partir d'un instantané de base de données ou d'un instantané de cluster pour lequel un n'Enginea pas été défini explicitement.

Corrections en cas de défaillance des règles

Définissez une valeur différente de la valeur par défaut pour le type de moteur d'instance de base de données Amazon RDS. Port

Les exemples suivants montrent comment mettre en œuvre cette correction.

Instance de base de données Amazon RDS - Exemple 1

Instance de base de données Amazon RDS configurée avec un port différent du port par défaut du mysql moteur. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBInstance": { "Type": "AWS::RDS::DBInstance", "Properties": { "Engine": "mysql", "EngineVersion": 5.7, "DBInstanceClass": "db.m5.large", "StorageType": "gp2", "AllocatedStorage": 5, "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::password}}" }, "StorageEncrypted": true, "Port": 6733 }, "DeletionPolicy": "Delete" } }

Exemple YAML

DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: mysql EngineVersion: 5.7 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' StorageEncrypted: true Port: 6733 DeletionPolicy: Delete

Les exemples suivants montrent comment mettre en œuvre cette correction.

Instance de base de données Amazon RDS : deuxième exemple

Instance de base de données Amazon RDS configurée avec un port différent du port par défaut du postgres moteur. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBInstance": { "Type": "AWS::RDS::DBInstance", "Properties": { "Engine": "postgres", "EngineVersion": 14.2, "DBInstanceClass": "db.m5.large", "StorageType": "gp2", "AllocatedStorage": 5, "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::password}}" }, "Port": 5723 }, "DeletionPolicy": "Delete" } }

Exemple YAML

DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' Port: 5723 DeletionPolicy: Delete

CT.RDS.PR.20spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_instance_no_default_ports_check # # Description: # This control checks whether Amazon Relational Database Service (RDS) database instances are configured for default database port for their specific engine types. # # Reports on: # AWS::RDS::DBInstance # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any Amazon RDS DB instance resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is not one of 'mariadb', 'mysql', # 'oracle-ee', 'oracle-se2', 'oracle-ee-cdb', 'oracle-se2-cdb', # 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', # 'oracle-ee', 'oracle-se2', 'oracle-ee-cdb', 'oracle-se2-cdb', # 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'Port' has not been specified # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', # 'oracle-ee', 'oracle-se2', 'oracle-ee-cdb', 'oracle-se2-cdb', # 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'Port' has been specified # And: 'Port' value is default port (includes mysql/mariadb port '3306', sqlserver # port '1433', postgres port '5432', and oracle port '1521') # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql' # And: 'Port' has been specified # And: 'Port' value is not equal to '3306' # Then: PASS # Scenario: 6 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is 'postgres' # And: 'Port' has been specified # And: 'Port' value is not equal to '5432' # Then: PASS # Scenario: 7 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'Port' has been specified # And: 'Port' value is not equal to '1433' # Then: PASS # Scenario: 8 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'oracle-ee', 'oracle-se2', 'oracle-ee-cdb', 'oracle-se2-cdb', # And: 'Port' has been specified # And: 'Port' value is not equal to '1521' # Then: PASS # # Constants # let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance" let INPUT_DOCUMENT = this let ORACLE_ENGINES = [ "oracle-ee", "oracle-se2", "oracle-se1", "oracle-se" ] let SQLSERVER_ENGINES = [ "sqlserver-ee", "sqlserver-se", "sqlserver-ex", "sqlserver-web" ] let MYSQL_OR_MARIA_ENGINES = [ "mariadb", "mysql" ] let POSTGRES_ENGINES = [ "postgres" ] let MYSQL_MARIA_DEFAULT_PORTS = [3306, "3306"] let POSTGRES_DEFAULT_PORTS = [5432, "5432"] let SQL_DEFAULT_PORTS = [1433, "1433"] let ORACLE_DEFAULT_PORTS = [1521, "1521"] # # Assignments # let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ] # # Primary Rules # rule rds_instance_no_default_ports_check when is_cfn_template(%INPUT_DOCUMENT) %rds_db_instances not empty { check(%rds_db_instances.Properties) << [CT.RDS.PR.20]: Require an Amazon RDS database instance not to use a database engine default port [FIX]: Set a value for 'Port' that is different than the default value for the Amazon RDS DB instance engine type. >> } rule rds_instance_no_default_ports_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties) << [CT.RDS.PR.20]: Require an Amazon RDS database instance not to use a database engine default port [FIX]: Set a value for 'Port' that is different than the default value for the Amazon RDS DB instance engine type. >> } # # Parameterized Rules # rule check(rds_db_instance) { # Scenario: 4 and 5 %rds_db_instance[ filter_engine(this, %MYSQL_OR_MARIA_ENGINES) ] { check_port(Port, %MYSQL_MARIA_DEFAULT_PORTS) } # Scenario: 4 and 6 %rds_db_instance[ filter_engine(this, %POSTGRES_ENGINES) ] { check_port(Port, %POSTGRES_DEFAULT_PORTS) } # Scenario: 4 and 7 %rds_db_instance[ filter_engine(this, %SQLSERVER_ENGINES) ] { check_port(Port, %SQL_DEFAULT_PORTS) } # Scenario: 4 and 8 %rds_db_instance[ filter_engine(this, %ORACLE_ENGINES) ] { check_port(Port, %ORACLE_DEFAULT_PORTS) } } rule filter_engine(db_properties, engine) { %db_properties { # Scenario: 2 Engine exists Engine is_string Engine in %engine } } rule check_port(port, default_ports) { # Scenario: 3 %port exists %port not in %default_ports } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

CT.RDS.PR.20exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB instance secret GenerateSecretString: SecretStringTemplate: '{"username": "testUser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: mysql EngineVersion: 5.7 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' Port: 6733 DeletionPolicy: Delete

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB instance secret GenerateSecretString: SecretStringTemplate: '{"username": "testUser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: mysql EngineVersion: 5.7 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' Port: 3306 DeletionPolicy: Delete

[CT.RDS.PR.21] Exiger qu'un cluster de base de données Amazon RDS possède un nom d'utilisateur d'administrateur unique

Ce contrôle vérifie si un cluster de base de données (DB) Amazon Relational Database Service (RDS) a modifié le nom d'utilisateur de l'administrateur par rapport à sa valeur par défaut.

  • Objectif de contrôle : protéger les configurations

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBCluster

  • AWS CloudFormationrègle de garde : CT.RDS.PR.21spécification des règles

Détails et exemples

Explication

Lorsque vous créez une base de données Amazon RDS, nous vous recommandons de remplacer le nom d'utilisateur par défaut de l'administrateur par une valeur unique. Les noms d'utilisateur par défaut sont connus du public et doivent être modifiés, car la modification de ces noms d'utilisateur réduit le risque d'accès involontaire.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux clusters de base de données Amazon RDS qui définissent la MasterUsername propriété.

Corrections en cas de défaillance des règles

MasterUsernameDéfini sur une valeur autre que admin oupostgres.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Cluster de bases de données Amazon RDS : exemple

Cluster de base de données Amazon RDS configuré avec un nom d'utilisateur d'administrateur unique. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBCluster": { "Type": "AWS::RDS::DBCluster", "Properties": { "Engine": "aurora-mysql", "MasterUsername": "samplemasteruser", "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${RDSClusterSecret}::password}}" }, "DBSubnetGroupName": { "Ref": "DBSubnetGroup" } } } }

Exemple YAML

DBCluster: Type: AWS::RDS::DBCluster Properties: Engine: aurora-mysql MasterUsername: samplemasteruser MasterUserPassword: !Sub '{{resolve:secretsmanager:${RDSClusterSecret}::password}}' DBSubnetGroupName: !Ref 'DBSubnetGroup'

CT.RDS.PR.21spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_cluster_default_admin_check # # Description: # This control checks whether an Amazon Relational Database Service (RDS) database (DB) cluster has changed the administrator username from its default value. # # Reports on: # AWS::RDS::DBCluster # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any RDS DB cluster resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'MasterUsername' has not been provided # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'MasterUsername' has been provided and it is set to 'admin' or 'postgres' # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'MasterUsername' has been provided and is not set to 'admin' or 'postgres' # Then: PASS # # Constants # let RDS_DB_CLUSTER_TYPE = "AWS::RDS::DBCluster" let DISALLOWED_MASTER_USERNAMES = ["admin", "postgres"] let INPUT_DOCUMENT = this # # Assignments # let db_clusters = Resources.*[ Type == %RDS_DB_CLUSTER_TYPE ] # # Primary Rules # rule rds_cluster_default_admin_check when is_cfn_template(%INPUT_DOCUMENT) %db_clusters not empty { check(%db_clusters.Properties) << [CT.RDS.PR.21]: Require an Amazon RDS DB cluster to have a unique administrator username [FIX]: Set 'MasterUsername' to a value other than 'admin' or 'postgres'. >> } rule rds_cluster_default_admin_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_CLUSTER_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_CLUSTER_TYPE.resourceProperties) << [CT.RDS.PR.21]: Require an Amazon RDS DB cluster to have a unique administrator username [FIX]: Set 'MasterUsername' to a value other than 'admin' or 'postgres'. >> } rule check(db_cluster) { %db_cluster [ # scenario 2 filter_master_username_provided(this) ] { # scenario 3 and 4 MasterUsername not in %DISALLOWED_MASTER_USERNAMES } } # # Utility Rules # rule filter_master_username_provided(dbcluster_properties) { %dbcluster_properties{ MasterUsername exists } } rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

CT.RDS.PR.21exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true SubnetOne: Type: AWS::EC2::Subnet Properties: VpcId: Ref: VPC CidrBlock: 10.0.0.0/25 AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: '' SubnetTwo: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.0.0.128/25 AvailabilityZone: Fn::Select: - 1 - Fn::GetAZs: '' VpcId: Ref: VPC DBSubnetGroup: Type: AWS::RDS::DBSubnetGroup Properties: DBSubnetGroupDescription: DB subnet group for DBCluster SubnetIds: - Ref: SubnetOne - Ref: SubnetTwo DBClusterSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB cluster secret GenerateSecretString: SecretStringTemplate: '{"username": "examplemasteruser"}' GenerateStringKey: password PasswordLength: 32 ExcludeCharacters: "/@\"'\\" DBCluster: Type: AWS::RDS::DBCluster Properties: Engine: aurora-mysql MasterUsername: examplemasteruser MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBClusterSecret}::password}}' DBSubnetGroupName: Ref: DBSubnetGroup

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true SubnetOne: Type: AWS::EC2::Subnet Properties: VpcId: Ref: VPC CidrBlock: 10.0.0.0/25 AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: '' SubnetTwo: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.0.0.128/25 AvailabilityZone: Fn::Select: - 1 - Fn::GetAZs: '' VpcId: Ref: VPC DBSubnetGroup: Type: AWS::RDS::DBSubnetGroup Properties: DBSubnetGroupDescription: DB subnet group for DBCluster SubnetIds: - Ref: SubnetOne - Ref: SubnetTwo DBClusterSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB cluster secret GenerateSecretString: SecretStringTemplate: '{"username": "examplemasteruser"}' GenerateStringKey: password PasswordLength: 32 ExcludeCharacters: "/@\"'\\" DBCluster: Type: AWS::RDS::DBCluster Properties: Engine: aurora-mysql MasterUsername: admin MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBClusterSecret}::password}}' DBSubnetGroupName: Ref: DBSubnetGroup

[CT.RDS.PR.22] Exiger qu'une instance de base de données Amazon RDS possède un nom d'utilisateur d'administrateur unique

Ce contrôle vérifie si une base de données Amazon Relational Database Service (RDS) a modifié le nom d'utilisateur de l'administrateur par rapport à sa valeur par défaut.

  • Objectif de contrôle : protéger les configurations

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBInstance

  • AWS CloudFormationrègle de garde : CT.RDS.PR.22spécification des règles

Détails et exemples

Explication

Les noms d'utilisateur administratifs par défaut sur les bases de données Amazon RDS sont de notoriété publique. Lorsque vous créez une base de données Amazon RDS, vous devez remplacer le nom d'utilisateur administratif par défaut par une valeur unique, afin de réduire le risque d'accès involontaire.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux types de moteurs de base de données Amazon RDS mariadb mysql oracle-eeoracle-ee-cdb,oracle-se2,oracle-se2-cdb,postgres,,sqlserver-ee, sqlserver-sesqlserver-ex, etsqlserver-web.

Corrections en cas de défaillance des règles

MasterUsernameDéfini sur une valeur autre que postgres ouadmin.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Instance de base de données Amazon RDS : exemple

Instance de base de données Amazon RDS configurée avec un nom d'utilisateur d'administrateur personnalisé. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBInstance": { "Type": "AWS::RDS::DBInstance", "Properties": { "Engine": "postgres", "EngineVersion": 14.2, "DBInstanceClass": "db.m5.large", "StorageType": "gp2", "AllocatedStorage": 5, "MasterUsername": "testUser", "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::password}}" } }, "DeletionPolicy": "Delete" } }

Exemple YAML

DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: testUser MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' DeletionPolicy: Delete

CT.RDS.PR.22spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_instance_default_admin_check # # Description: # This control checks whether an Amazon Relational Database Service (RDS) database has changed the adminstrator username from its default value. # # Reports on: # AWS::RDS::DBInstance # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any RDS DB instance resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is not one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'MasterUsername' has been specified and is one of 'postgres' or 'admin' # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'MasterUsername' has been specified and is not one of 'postgres' or 'admin' # Then: PASS # # Constants # let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance" let INPUT_DOCUMENT = this let SUPPORTED_RDS_INSTANCE_ENGINES = [ "mariadb", "mysql", "oracle-ee", "oracle-ee-cdb", "oracle-se2", "oracle-se2-cdb", "postgres", "sqlserver-ee", "sqlserver-se", "sqlserver-ex", "sqlserver-web" ] let RDS_DEFAULT_USERNAMES = [ "postgres", "admin" ] # # Assignments # let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ] # # Primary Rules # rule rds_instance_default_admin_check when is_cfn_template(%INPUT_DOCUMENT) %rds_db_instances not empty { check(%rds_db_instances.Properties) << [CT.RDS.PR.22]: Require an Amazon RDS database instance to have a unique administrator username [FIX]: Set 'MasterUsername' to a value other than 'postgres' or 'admin'. >> } rule rds_instance_default_admin_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties) << [CT.RDS.PR.22]: Require an Amazon RDS database instance to have a unique administrator username [FIX]: Set 'MasterUsername' to a value other than 'postgres' or 'admin'. >> } # # Parameterized Rules # rule check(rds_db_instance) { %rds_db_instance [ filter_engine_and_master_username_provided(this) ] { # Scenario: 3 and 4 MasterUsername not in %RDS_DEFAULT_USERNAMES } } rule filter_engine_and_master_username_provided(db_properties) { %db_properties { # Scenario: 2 MasterUsername exists Engine exists Engine is_string Engine in %SUPPORTED_RDS_INSTANCE_ENGINES } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

CT.RDS.PR.22exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: Test RDS DB Instance secret GenerateSecretString: SecretStringTemplate: '{"username": "testUser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: testUser MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' DeletionPolicy: Delete

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: Test RDS DB Instance secret GenerateSecretString: SecretStringTemplate: '{"username": "testUser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: postgres MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' DeletionPolicy: Delete

[CT.RDS.PR.23] Exiger qu'une instance de base de données Amazon RDS ne soit pas accessible au public

Cette règle vérifie si les instances de base de données (DB) Amazon Relational Database Service (RDS) sont accessibles au public, comme cela est déterminé en vérifiant la propriété de configuration. PubliclyAccessible

  • Objectif de contrôle : limiter l'accès au réseau

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBInstance

  • AWS CloudFormationrègle de garde : CT.RDS.PR.23spécification des règles

Détails et exemples

Explication

La PubliclyAccessible propriété de la CloudFormation ressource d'instance RDS indique si l'instance de base de données est accessible au public. Lorsque l'instance de base de données est configurée avec PubliclyAccessible set totrue, il s'agit d'une instance connectée à Internet avec un nom DNS pouvant être résolu publiquement, qui se résout en une adresse IP publique. Lorsque l'instance de base de données n'est pas accessible publiquement, il s'agit d'une instance interne avec un nom DNS qui correspond à une adresse IP privée.

À moins que vous n'ayez l'intention de rendre votre instance RDS accessible au public, ne configurez pas l'instance RDS avec la PubliclyAccessible valeur définie surtrue, car cette configuration peut autoriser un trafic indésirable vers votre instance de base de données.

Corrections en cas de défaillance des règles

Définissez la valeur de PubliclyAccessible àfalse.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Instance de base de données Amazon RDS : exemple

Instance de base de données Amazon RDS configurée en tant qu'instance interne, au moyen d'une configuration accessible au public. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBInstance": { "Type": "AWS::RDS::DBInstance", "Properties": { "Engine": "postgres", "EngineVersion": 14.2, "DBInstanceClass": "db.m5.large", "StorageType": "gp2", "AllocatedStorage": 5, "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::password}}" }, "PubliclyAccessible": false }, "DeletionPolicy": "Delete" } }

Exemple YAML

DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' PubliclyAccessible: false DeletionPolicy: Delete

CT.RDS.PR.23spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_instance_public_access_check # # Description: # This rule checks whether Amazon Relational Database Service (RDS) database (DB) instances are publicly accessible, as determined by checking the 'PubliclyAccessible' configuration property. # # Reports on: # AWS::RDS::DBInstance # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any RDS DB instance resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'PubliclyAccessible' has not been specified # Then: FAIL # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'PubliclyAccessible' is present and is a value other than bool(false) # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'PubliclyAccessible' has been specified and set to bool(false) # Then: PASS # # Constants # let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance" let INPUT_DOCUMENT = this # # Assignments # let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ] # # Primary Rules # rule rds_instance_public_access_check when is_cfn_template(%INPUT_DOCUMENT) %rds_db_instances not empty { check(%rds_db_instances.Properties) << [CT.RDS.PR.23]: Require an Amazon RDS database instance to not be publicly accessible [FIX]: Set the value of 'PubliclyAccessible' to 'false'. >> } rule rds_instance_public_access_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties) << [CT.RDS.PR.23]: Require an Amazon RDS database instance to not be publicly accessible [FIX]: Set the value of 'PubliclyAccessible' to 'false'. >> } # # Parameterized Rules # rule check(rds_db_instance) { %rds_db_instance{ #Scenario: 2 PubliclyAccessible exists #Scenario: 3 and 4 PubliclyAccessible == false } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

CT.RDS.PR.23exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB instance secret GenerateSecretString: SecretStringTemplate: '{"username": "examplemasteruser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' PubliclyAccessible: false DeletionPolicy: Delete

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB instance secret GenerateSecretString: SecretStringTemplate: '{"username": "examplemasteruser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' PubliclyAccessible: true DeletionPolicy: Delete

[CT.RDS.PR.24] Exiger que le chiffrement au repos soit configuré sur une instance de base de données Amazon RDS

Ce contrôle vérifie si le chiffrement du stockage est activé pour votre instance de base de données (DB) Amazon RDS.

  • Objectif de contrôle : crypter les données au repos

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBInstance

  • AWS CloudFormationrègle de garde : CT.RDS.PR.24spécification des règles

Détails et exemples

Explication

Pour renforcer la sécurité de vos données sensibles dans les instances de base de données Amazon RDS, vous devez configurer vos instances de base de données RDS pour qu'elles soient chiffrées au repos. Pour chiffrer vos instances et vos instantanés de base de données RDS au repos, activez l'option de chiffrement pour vos instances de base de données RDS. Les données qui sont chiffrées au repos incluent le stockage sous-jacent pour des instance DB, les sauvegardes automatisées, les réplicas en lecture et les instantanés.

Les instances de base de données Amazon RDS chiffrées utilisent l'algorithme de chiffrement standard ouvert AES-256 pour chiffrer vos données sur le serveur qui héberge vos instances de base de données RDS. Une fois vos données chiffrées, Amazon RDS gère l'authentification de l'accès et le déchiffrement de vos données de manière transparente avec un impact minimal sur les performances. Vous n'avez pas besoin de modifier vos applications clientes de base de données pour utiliser le chiffrement.

Le chiffrement Amazon RDS est actuellement disponible pour tous les moteurs de base de données et types de stockage. Le chiffrement Amazon RDS est disponible pour la plupart des classes d'instance de base de données.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux types de moteurs de base de données Amazon RDS mariadb mysql oracle-eeoracle-ee-cdb,oracle-se2,oracle-se2-cdb,,postgres, sqlserver-eesqlserver-se, et sqlserver-ex sqlserver-web

  • Ce contrôle s'applique uniquement lorsque la Engine propriété est fournie. Cela ne s'applique pas lors de la restauration à partir d'un instantané de base de données ou d'un instantané de cluster pour lequel un n'Enginea pas été défini explicitement.

Corrections en cas de défaillance des règles

Le paramètre StorageEncrypted doit être défini sur true pour les instances de base de données RDS.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Instance de base de données Amazon RDS - Exemple

Instance de base de données Amazon RDS avec chiffrement du stockage activé. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "RDSDBInstance": { "Type": "AWS::RDS::DBInstance", "Properties": { "Engine": "postgres", "EngineVersion": 14.2, "DBInstanceClass": "db.m5.large", "StorageType": "gp2", "AllocatedStorage": 5, "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${RDSDBInstanceSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${RDSDBInstanceSecret}::password}}" }, "StorageEncrypted": true } } }

Exemple YAML

RDSDBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: !Sub '{{resolve:secretsmanager:${RDSDBInstanceSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${RDSDBInstanceSecret}::password}}' StorageEncrypted: true

CT.RDS.PR.24spécification des règles

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_instance_storage_encrypted_check # # Description: # Checks whether storage encryption is enabled for your Amazon RDS DB instances. # # Reports on: # AWS::RDS::DBInstance # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document does not contain any RDS DB instance resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is not one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'StorageEncrypted' has not been provided # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'StorageEncrypted' has been provided and set to bool(false) # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or CloudFormation hook document # And: The input document contains an RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', # 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web' # And: 'StorageEncrypted' has been provided and set to bool(true) # Then: PASS # # Constants # let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance" let INPUT_DOCUMENT = this let SUPPORTED_RDS_INSTANCE_ENGINES = [ "mariadb", "mysql", "oracle-ee", "oracle-ee-cdb", "oracle-se2", "oracle-se2-cdb", "postgres", "sqlserver-ee", "sqlserver-se", "sqlserver-ex", "sqlserver-web" ] # # Assignments # let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ] # # Primary Rules # rule rds_instance_storage_encrypted_check when is_cfn_template(%INPUT_DOCUMENT) %rds_db_instances not empty { check(%rds_db_instances.Properties) << [CT.RDS.PR.24]: Require an Amazon RDS database instance to have encryption at rest configured [FIX]: The parameter 'StorageEncrypted' must be set to true for RDS DB Instances. >> } rule rds_instance_storage_encrypted_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties) << [CT.RDS.PR.24]: Require an Amazon RDS database instance to have encryption at rest configured [FIX]: The parameter 'StorageEncrypted' must be set to true for RDS DB Instances. >> } # # Parameterized Rules # rule check(rds_db_instance) { %rds_db_instance [filter_restore_and_engine(this)] { #Scenario: 3 StorageEncrypted exists #Scenario: 4 and 5 StorageEncrypted == true } } rule filter_restore_and_engine(db_properties) { %db_properties { #Scenario: 2 Engine exists Engine is_string Engine in %SUPPORTED_RDS_INSTANCE_ENGINES } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

CT.RDS.PR.24exemples de modèles

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS instance secret GenerateSecretString: SecretStringTemplate: '{"username": "exampleuser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: "/@\"" DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' StorageEncrypted: true DeletionPolicy: Delete

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS instance secret GenerateSecretString: SecretStringTemplate: '{"username": "exampleuser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: "/@\"" DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' StorageEncrypted: false DeletionPolicy: Delete

[CT.RDS.PR.25] Exiger qu'un cluster de bases de données Amazon RDS exporte des journaux vers Amazon Logs au moyen de la propriété CloudWatch EnableCloudwatchLogsExports

Ce contrôle vérifie si tous les types de journaux disponibles sont activés pour les clusters de bases de données Amazon RDS pour l'exportation vers Amazon CloudWatch Logs.

  • Objectif de contrôle : établir une journalisation et une surveillance

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBCluster

  • AWS CloudFormationrègle de garde : Spécification de la règle CT.RDS.PR.25

Détails et exemples

Explication

AWS Control Tower vous recommande d'activer l'exportation des journaux pertinents pour tous les clusters de bases de données Amazon RDS vers Amazon CloudWatch Logs. La journalisation de la base de données fournit des enregistrements détaillés des demandes adressées à RDS. Les journaux de base de données peuvent faciliter les audits de sécurité et d'accès, et ils peuvent vous aider à diagnostiquer les problèmes de disponibilité.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux types de moteurs de cluster de base de données Amazon RDS auroraaurora-mysql,aurora-postgresql, mysql etpostgres.

  • Des conditions supplémentaires peuvent être requises pour activer la journalisation en fonction du type de moteur de base de données sélectionné. Reportez-vous à la section Surveillance des fichiers journaux Amazon Aurora dans le guide de l'utilisateur Amazon Aurora pour plus d'informations.

Corrections en cas de défaillance des règles

Spécifiez EnableCloudwatchLogsExports avec une liste de tous les types de journaux pris en charge pour le moteur de cluster de base de données Amazon RDS.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Cluster de bases de données (DB) Amazon RDS : premier exemple

Cluster de base de données Amazon RDS Aurora configuré avec tous les types de journaux disponibles activés pour l'exportation vers Amazon CloudWatch Logs. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBCluster": { "Type": "AWS::RDS::DBCluster", "Properties": { "Engine": "aurora", "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBClusterSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBClusterSecret}::password}}" }, "DBSubnetGroupName": { "Ref": "DBSubnetGroup" }, "EnableCloudwatchLogsExports": [ "audit", "error", "general", "slowquery" ] } } }

Exemple YAML

DBCluster: Type: AWS::RDS::DBCluster Properties: Engine: aurora MasterUsername: !Sub '{{resolve:secretsmanager:${DBClusterSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBClusterSecret}::password}}' DBSubnetGroupName: !Ref 'DBSubnetGroup' EnableCloudwatchLogsExports: - audit - error - general - slowquery

Les exemples suivants montrent comment mettre en œuvre cette correction.

Cluster de bases de données Amazon RDS : deuxième exemple

Cluster de base de données Postgres multi-AZ Amazon RDS configuré avec tous les types de journaux disponibles activés pour l'exportation vers Amazon Logs. CloudWatch L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBCluster": { "Type": "AWS::RDS::DBCluster", "Properties": { "Engine": "aurora", "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBClusterSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBClusterSecret}::password}}" }, "DBSubnetGroupName": { "Ref": "DBSubnetGroup" }, "EnableCloudwatchLogsExports": [ "audit", "error", "general", "slowquery" ] } } }

Exemple YAML

DBCluster: Type: AWS::RDS::DBCluster Properties: Engine: aurora MasterUsername: !Sub '{{resolve:secretsmanager:${DBClusterSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBClusterSecret}::password}}' DBSubnetGroupName: !Ref 'DBSubnetGroup' EnableCloudwatchLogsExports: - audit - error - general - slowquery

Spécification de la règle CT.RDS.PR.25

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_cluster_logging_enabled_check # # Description: # This control checks whether Amazon RDS database clusters have all available log types enabled for export to Amazon CloudWatch Logs. # # Reports on: # AWS::RDS::DBCluster # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any RDS DB cluster resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster Resource # And: 'Engine' is not one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mysql' or 'postgres' # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'Engine' is one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mysql' or 'postgres' # And: 'EnableCloudwatchLogsExports' has not been specified or has been specified as an empty list # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'Engine' is one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mysql' or 'postgres' # And: 'EnableCloudwatchLogsExports' has been specified and is a non-empty list # And: One or more log types in 'EnableCloudwatchLogsExports' are not supported by the specified 'Engine' # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'Engine' is one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mysql' or 'postgres' # And: 'EnableCloudwatchLogsExports' has been specified and is a non-empty list # And: 'EnableCloudwatchLogsExports' does not contain all log types supported by the specified 'Engine' # Then: FAIL # Scenario: 6 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'Engine' is one of 'aurora', 'aurora-mysql' or 'mysql' # And: 'EnableCloudwatchLogsExports' has been specified as a list with all supported log types # for the 'Engine' ('audit', 'error', 'general' and 'slowquery') # Then: PASS # Scenario: 7 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'Engine' is 'aurora-postgresql' # And: 'EnableCloudwatchLogsExports' has been specified as a list with all supported log types # for the 'Engine' ('postgresql') # Then: PASS # Scenario: 8 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an RDS DB cluster resource # And: 'Engine' is 'postgres' # And: 'EnableCloudwatchLogsExports' has been specified as a list with all supported log types # for the 'Engine' ('postgresql', 'upgrade') # Then: PASS # # Constants # let RDS_DB_CLUSTER_TYPE = "AWS::RDS::DBCluster" let INPUT_DOCUMENT = this let SUPPORTED_RDS_CLUSTER_ENGINES = [ "aurora", "aurora-mysql", "aurora-postgresql", "mysql", "postgres" ] let MYSQL_ENGINE_SUBTYPES = [ "aurora", "aurora-mysql", "mysql" ] let AURORA_POSTGRES_ENGINE_SUBTYPES = [ "aurora-postgresql" ] let POSTGRES_ENGINE_SUBTYPES = [ "postgres" ] let MYSQL_SUPPORTED_LOG_TYPES = [ "audit", "error", "general", "slowquery" ] let AURORA_POSTGRES_SUPPORTED_LOG_TYPES = [ "postgresql" ] let POSTGRES_SUPPORTED_LOG_TYPES = [ "postgresql", "upgrade" ] # # Assignments # let rds_db_clusters = Resources.*[ Type == %RDS_DB_CLUSTER_TYPE ] # # Primary Rules # rule rds_cluster_logging_enabled_check when is_cfn_template(%INPUT_DOCUMENT) %rds_db_clusters not empty { check(%rds_db_clusters.Properties) << [CT.RDS.PR.25]: Require an Amazon RDS database cluster to have logging configured [FIX]: Specify 'EnableCloudwatchLogsExports' with a list of all supported log types for the Amazon RDS database cluster engine. >> } rule rds_cluster_logging_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_CLUSTER_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_CLUSTER_TYPE.resourceProperties) << [CT.RDS.PR.25]: Require an Amazon RDS database cluster to have logging configured [FIX]: Specify 'EnableCloudwatchLogsExports' with a list of all supported log types for the Amazon RDS database cluster engine. >> } # # Parameterized Rules # rule check(rds_db_cluster) { %rds_db_cluster [ filter_engine(this) ] { # Scenario 3 EnableCloudwatchLogsExports exists check_is_list_and_not_empty(EnableCloudwatchLogsExports) # Scenario 4 and 6 when Engine IN %MYSQL_ENGINE_SUBTYPES { %MYSQL_SUPPORTED_LOG_TYPES.* IN EnableCloudwatchLogsExports[*] EnableCloudwatchLogsExports.* IN %MYSQL_SUPPORTED_LOG_TYPES[*] } # Scenario 4 and 7 when Engine IN %AURORA_POSTGRES_ENGINE_SUBTYPES { %AURORA_POSTGRES_SUPPORTED_LOG_TYPES.* IN EnableCloudwatchLogsExports[*] EnableCloudwatchLogsExports.* IN %AURORA_POSTGRES_SUPPORTED_LOG_TYPES[*] } # Scenario 4 and 8 when Engine IN %POSTGRES_ENGINE_SUBTYPES { %POSTGRES_SUPPORTED_LOG_TYPES.* in EnableCloudwatchLogsExports[*] EnableCloudwatchLogsExports.* IN %POSTGRES_SUPPORTED_LOG_TYPES[*] } } } rule filter_engine(db_properties) { %db_properties { # Scenario 2 Engine exists Engine in %SUPPORTED_RDS_CLUSTER_ENGINES } } # # Utility Rules # rule check_is_list_and_not_empty(value) { %value { this is_list this not empty } } rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

Exemples de modèles CT.RDS.PR.25

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: DBCluster: Type: AWS::RDS::DBCluster Properties: MasterUsername: exampleusername MasterUserPassword: example-password DBSubnetGroupName: example-db-subnet-group Engine: aurora EnableCloudwatchLogsExports: - audit - error - general - slowquery

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: DBCluster: Type: AWS::RDS::DBCluster Properties: DBClusterInstanceClass: db.m6gd.large MasterUsername: exampleusername MasterUserPassword: example-password DBSubnetGroupName: example-db-subnet-group Engine: postgres AllocatedStorage: 100 StorageType: io1 Iops: 3000 EnableCloudwatchLogsExports: - postgresql - upgrade

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: DBCluster: Type: AWS::RDS::DBCluster Properties: MasterUsername: exampleusername MasterUserPassword: example-password DBSubnetGroupName: example-db-subnet-group Engine: aurora

[CT.RDS.PR.26] Nécessite un proxy de base de données Amazon Relational Database Service pour exiger des connexions TLS (Transport Layer Security)

Ce contrôle vérifie si un proxy de base de données Amazon Relational Database Service est configuré pour exiger le protocole TLS (Transport Layer Security) pour les connexions au proxy.

  • Objectif de contrôle : crypter les données en transit

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBProxy

  • AWS CloudFormationrègle de garde : Spécification de la règle CT.RDS.PR.26

Détails et exemples

Explication

Amazon RDS Proxy peut constituer une couche de sécurité supplémentaire entre les applications clientes et la base de données sous-jacente. Par exemple, vous pouvez vous connecter au proxy à l'aide de TLS 1.2, même si l'instance de base de données sous-jacente prend en charge une version antérieure de TLS. Vous pouvez vous connecter au proxy à l'aide d'un rôle IAM, même si le proxy se connecte à la base de données avec la méthode d'authentification native par utilisateur et mot de passe. Grâce à cette technique, vous pouvez appliquer des exigences d'authentification strictes pour les applications de base de données sans devoir effectuer de migration coûteuse pour les instances de base de données elles-mêmes.

Considérations d'utilisation
  • Pour obtenir des informations générales sur les limites du proxy Amazon RDS, consultez la section Quotas et limites du proxy RDS dans le guide de l'utilisateur d'Amazon Relational Database Service.

Corrections en cas de défaillance des règles

Définissez la valeur de la propriété Requiretls sur true.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Proxy de base de données Amazon RDS : exemple

Un proxy de base de données Amazon RDS configuré pour exiger des connexions TLS au proxy. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBProxy": { "Type": "AWS::RDS::DBProxy", "Properties": { "DBProxyName": "sample-db-proxy", "EngineFamily": "MYSQL", "IdleClientTimeout": 120, "RoleArn": { "Fn::GetAtt": "ProxySecretAccessRole.Arn" }, "Auth": [ { "AuthScheme": "SECRETS", "SecretArn": { "Ref": "DBInstanceSecret" }, "IAMAuth": "DISABLED" } ], "VpcSubnetIds": [ { "Ref": "SubnetOne" }, { "Ref": "SubnetTwo" } ], "RequireTLS": true } } }

Exemple YAML

DBProxy: Type: AWS::RDS::DBProxy Properties: DBProxyName: sample-db-proxy EngineFamily: MYSQL IdleClientTimeout: 120 RoleArn: !GetAtt 'ProxySecretAccessRole.Arn' Auth: - AuthScheme: SECRETS SecretArn: !Ref 'DBInstanceSecret' IAMAuth: DISABLED VpcSubnetIds: - !Ref 'SubnetOne' - !Ref 'SubnetTwo' RequireTLS: true

Spécification de la règle CT.RDS.PR.26

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_proxy_tls_check # # Description: # This control checks whether an Amazon RDS DB Proxy is configured to require Transport Layer Security (TLS) for connections to the proxy. # # Reports on: # AWS::RDS::DBProxy # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any Amazon RDS DB proxy resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an Amazon RDS DB proxy resource # And: 'RequireTLS' has not been provided # Then: FAIL # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an Amazon RDS DB proxy resource # And: 'RequireTLS' has been provided and set to a value other than bool(true) # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an Amazon RDS DB proxy resource # And: 'RequireTLS' has been provided and set to bool(true) # Then: PASS # # Constants # let INPUT_DOCUMENT = this let RDS_DB_PROXY_TYPE = "AWS::RDS::DBProxy" # # Assignments # let rds_db_proxies = Resources.*[ Type == %RDS_DB_PROXY_TYPE ] # # Primary Rules # rule rds_proxy_tls_check when is_cfn_template(%INPUT_DOCUMENT) %rds_db_proxies not empty { check(%rds_db_proxies.Properties) << [CT.RDS.PR.26]: Require an Amazon RDS DB Proxy to require Transport Layer Security (TLS) connections [FIX]: Set the value of the RequireTLS property to true. >> } rule rds_proxy_tls_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_PROXY_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_PROXY_TYPE.resourceProperties) << [CT.RDS.PR.26]: Require an Amazon RDS DB Proxy to require Transport Layer Security (TLS) connections [FIX]: Set the value of the RequireTLS property to true. >> } # # Parameterized Rules # rule check(rds_db_proxy) { %rds_db_proxy { # Scenarios 2 RequireTLS exists # Scenarios 3 and 4 RequireTLS == true } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

Exemples de modèles CT.RDS.PR.26

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsSupport: 'true' EnableDnsHostnames: 'true' SubnetOne: Type: AWS::EC2::Subnet Properties: VpcId: Ref: VPC CidrBlock: 10.0.0.0/24 AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: '' SubnetTwo: Type: AWS::EC2::Subnet Properties: VpcId: Ref: VPC CidrBlock: 10.0.1.0/24 AvailabilityZone: Fn::Select: - 1 - Fn::GetAZs: '' DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB instance secret GenerateSecretString: SecretStringTemplate: '{"username": "examplemasteruser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' ProxySecretAccessRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: rds.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: SecretAccessPolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - secretsmanager:GetSecretValue Resource: Ref: DBInstanceSecret - Effect: Allow Action: - kms:Decrypt Resource: Fn::Sub: arn:${AWS::Partition}:kms:${AWS::Region}:${AWS::AccountId}:key/* Condition: StringEquals: kms:ViaService: Fn::Sub: secretsmanager.${AWS::Region}.amazonaws.com ForAnyValue:StringEquals: kms:ResourceAliases: alias/aws/secretsmanager DBProxy: Type: AWS::RDS::DBProxy Properties: DBProxyName: Fn::Sub: ${AWS::StackName}-example EngineFamily: MYSQL IdleClientTimeout: 120 RoleArn: Fn::GetAtt: ProxySecretAccessRole.Arn Auth: - AuthScheme: SECRETS SecretArn: Ref: DBInstanceSecret IAMAuth: DISABLED VpcSubnetIds: - Ref: SubnetOne - Ref: SubnetTwo RequireTLS: true

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsSupport: 'true' EnableDnsHostnames: 'true' SubnetOne: Type: AWS::EC2::Subnet Properties: VpcId: Ref: VPC CidrBlock: 10.0.0.0/24 AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: '' SubnetTwo: Type: AWS::EC2::Subnet Properties: VpcId: Ref: VPC CidrBlock: 10.0.1.0/24 AvailabilityZone: Fn::Select: - 1 - Fn::GetAZs: '' DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB instance secret GenerateSecretString: SecretStringTemplate: '{"username": "examplemasteruser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' ProxySecretAccessRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: rds.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: SecretAccessPolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - secretsmanager:GetSecretValue Resource: Ref: DBInstanceSecret - Effect: Allow Action: - kms:Decrypt Resource: Fn::Sub: arn:${AWS::Partition}:kms:${AWS::Region}:${AWS::AccountId}:key/* Condition: StringEquals: kms:ViaService: Fn::Sub: secretsmanager.${AWS::Region}.amazonaws.com ForAnyValue:StringEquals: kms:ResourceAliases: alias/aws/secretsmanager DBProxy: Type: AWS::RDS::DBProxy Properties: DBProxyName: Fn::Sub: ${AWS::StackName}-example EngineFamily: MYSQL IdleClientTimeout: 120 RoleArn: Fn::GetAtt: ProxySecretAccessRole.Arn Auth: - AuthScheme: SECRETS SecretArn: Ref: DBInstanceSecret IAMAuth: DISABLED VpcSubnetIds: - Ref: SubnetOne - Ref: SubnetTwo RequireTLS: false

[CT.RDS.PR.27] Exiger un groupe de paramètres de cluster de base de données Amazon Relational Database Service pour exiger des connexions TLS (Transport Layer Security) pour les types de moteurs pris en charge

Ce contrôle vérifie si un groupe de paramètres de cluster de base de données Amazon Relational Database Service nécessite des connexions TLS (Transport Layer Security) pour les types de moteurs pris en charge.

  • Objectif de contrôle : crypter les données en transit

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBClusterParameterGroup

  • AWS CloudFormationrègle de garde : Spécification de la règle CT.RDS.PR.27

Détails et exemples

Explication

Vous pouvez utiliser le protocole SSL (Secure Socket Layer) ou le protocole TLS (Transport Layer Security) depuis votre application pour chiffrer une connexion à un cluster de bases de données exécutant Aurora MySQL, Aurora PostgreSQL, MySQL ou PostgreSQL. Les connexions SSL/TLS fournissent une couche de sécurité en chiffrant les données qui circulent entre votre client et le cluster de base de données.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux groupes de paramètres du cluster de base de données Amazon RDS avec les familles aurora-mysqlaurora-postgresql,postgres, oumysql.

Corrections en cas de défaillance des règles

Pour les groupes de paramètres du cluster de base de données Amazon RDS avec aurora-mysql et mysql familles, dans la propriété Parameters, définissez la valeur require_secure_transport sur true. Pour les groupes de paramètres de cluster de base de données Amazon RDS dotés de postgres familles aurora-postgresql AMD, dans la propriété Parameters, définissez la valeur rds.force_ssl sur true.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Groupe de paramètres du cluster de base de données Amazon RDS : premier exemple

Un groupe de paramètres de cluster de base de données Amazon RDS configuré pour exiger le protocole TLS/SSL pour toutes les connexions aux clusters de bases de données Aurora MySQL. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "RDSDBClusterParameterGroup": { "Type": "AWS::RDS::DBClusterParameterGroup", "Properties": { "Description": "sample-db-parameter-group", "Family": "aurora-mysql5.7", "Parameters": { "require_secure_transport": "ON" } } } }

Exemple YAML

RDSDBClusterParameterGroup: Type: AWS::RDS::DBClusterParameterGroup Properties: Description: sample-db-parameter-group Family: aurora-mysql5.7 Parameters: require_secure_transport: 'ON'

Les exemples suivants montrent comment mettre en œuvre cette correction.

Groupe de paramètres du cluster de base de données Amazon RDS : deuxième exemple

Un groupe de paramètres de cluster de base de données Amazon RDS configuré pour exiger le protocole TLS/SSL pour toutes les connexions aux clusters de bases de données PostgreSQL. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "RDSDBClusterParameterGroup": { "Type": "AWS::RDS::DBClusterParameterGroup", "Properties": { "Description": "sample-db-parameter-group", "Family": "postgres14", "Parameters": { "rds.force_ssl": true } } } }

Exemple YAML

RDSDBClusterParameterGroup: Type: AWS::RDS::DBClusterParameterGroup Properties: Description: sample-db-parameter-group Family: postgres14 Parameters: rds.force_ssl: true

Spécification de la règle CT.RDS.PR.27

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_db_cluster_parameter_group_tls_check # # Description: # This control checks whether an Amazon RDS DB cluster parameter group requires Transport Layer Security (TLS) connections for supported engine types. # # Reports on: # AWS::RDS::DBClusterParameterGroup # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any Amazon RDS DB cluster parameter group resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an Amazon RDS DB cluster parameter group resource # And: 'Family' has not been provided or has been provided and set to an RDS DB cluster # parameter group family other than 'aurora-mysql', 'aurora-postgresql', 'postgres', # or 'mysql' families # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an Amazon RDS DB cluster parameter group resource # And: 'Family' has been provided and set to an 'aurora-mysql' Amazon RDS DB cluster parameter # group family # And: In 'Parameters', 'require_secure_transport' has not been provided, or # has been provided and set to a value other than 'ON' # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an Amazon RDS DB cluster parameter group resource # And: 'Family' has been provided and set to a 'mysql' Amazon RDS DB cluster parameter # group family # And: In 'Parameters', 'require_secure_transport' has not been provided, or # has been provided and set to a value other than a boolean true value # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an Amazon RDS DB cluster parameter group resource # And: 'Family' has been provided and set to an 'aurora-postgresql' or 'postgres' # Amazon RDS DB cluster parameter group family # And: In 'Parameters', 'rds.force_ssl' has not been provided, or has been provided # and set to a value other than a boolean true value # Then: FAIL # Scenario: 6 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an Amazon RDS DB cluster parameter group resource # And: 'Family' has been provided and set to an 'aurora-mysql' RDS DB cluster parameter # group family # And: In 'Parameters', 'require_secure_transport' has been provided and set # to 'ON' # Then: PASS # Scenario: 7 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an Amazon RDS DB cluster parameter group resource # And: 'Family' has been provided and set to a 'mysql' Amazon RDS DB cluster parameter group family # And: In 'Parameters', 'require_secure_transport' has been provided and set # to a boolean true value # Then: PASS # Scenario: 8 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an Amazon RDS DB cluster parameter group resource # And: 'Family' has been provided and set to an 'aurora-postgresql' or 'postgres' RDS DB # cluster parameter group family # And: In 'Parameters', 'rds.force_ssl' has been provided and set # to a boolean true value # Then: PASS # # Constants # let INPUT_DOCUMENT = this let RDS_DB_CLUSTER_PARAMETER_GROUP_TYPE = "AWS::RDS::DBClusterParameterGroup" let AURORA_MYSQL_PG_FAMILY = /^aurora-mysql/ let AURORA_POSTGRES_PG_FAMILY = /^aurora-postgresql/ let MYSQL_PG_FAMILY = /^mysql/ let POSTGRES_PG_FAMILY = /^postgres/ let BOOLEAN_TRUE_VALUES = [ true, 1, "1", "true", "True", "TRUE", "on", "On", "ON" ] let AURORA_MSQL_ON_PATTERN = /(?i)^on$/ # # Assignments # let rds_db_cluster_parameter_groups = Resources.*[ Type == %RDS_DB_CLUSTER_PARAMETER_GROUP_TYPE ] # # Primary Rules # rule rds_db_cluster_parameter_group_tls_check when is_cfn_template(%INPUT_DOCUMENT) %rds_db_cluster_parameter_groups not empty { check(%rds_db_cluster_parameter_groups.Properties) << [CT.RDS.PR.27]: Require an Amazon RDS DB cluster parameter group to require Transport Layer Security (TLS) connections for supported engine types [FIX]: For RDS DB cluster parameter groups with 'aurora-mysql' and 'mysql' families, in the Parameters property, set the value of 'require_secure_transport' to true. For RDS DB cluster parameter groups with 'aurora-postgresql' amd 'postgres' families, in the Parameters property, set the value of 'rds.force_ssl' to true. >> } rule rds_db_cluster_parameter_group_tls_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_CLUSTER_PARAMETER_GROUP_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_CLUSTER_PARAMETER_GROUP_TYPE.resourceProperties) << [CT.RDS.PR.27]: Require an Amazon RDS DB cluster parameter group to require Transport Layer Security (TLS) connections for supported engine types [FIX]: For RDS DB cluster parameter groups with 'aurora-mysql' and 'mysql' families, in the Parameters property, set the value of 'require_secure_transport' to true. For Amazon RDS DB cluster parameter groups with 'aurora-postgresql' amd 'postgres' families, in the Parameters property, set the value of 'rds.force_ssl' to true. >> } # # Parameterized Rules # rule check(rds_parameter_group) { %rds_parameter_group [ # Scenario 2 filter_pg_aurora_mysql_families(this) ] { # Scenarios 3 and 5 Parameters exists Parameters is_struct Parameters { require_secure_transport exists require_secure_transport in %AURORA_MSQL_ON_PATTERN } } %rds_parameter_group [ # Scenario 2 filter_pg_mysql_families(this) ] { # Scenarios 3 and 5 Parameters exists Parameters is_struct Parameters { require_secure_transport exists require_secure_transport in %BOOLEAN_TRUE_VALUES } } %rds_parameter_group [ # Scenario 2 filter_pg_postgres_families(this) ] { # Scenarios 4 and 6 Parameters exists Parameters is_struct Parameters { "rds.force_ssl" exists "rds.force_ssl" in %BOOLEAN_TRUE_VALUES } } } rule filter_pg_aurora_mysql_families(parameter_group) { %parameter_group { Family exists Family in %AURORA_MYSQL_PG_FAMILY } } rule filter_pg_mysql_families(parameter_group) { %parameter_group { Family exists Family in %MYSQL_PG_FAMILY } } rule filter_pg_postgres_families(parameter_group) { %parameter_group { Family exists Family in %AURORA_POSTGRES_PG_FAMILY or Family in %POSTGRES_PG_FAMILY } } # # Utility Rules # rule check_is_list_and_not_empty(value) { %value { this is_list this not empty } } rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

Exemples de modèles CT.RDS.PR.27

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: RDSDBClusterParameterGroup: Type: AWS::RDS::DBClusterParameterGroup Properties: Description: Fn::Sub: ${AWS::StackName}-example Family: aurora-mysql5.7 Parameters: require_secure_transport: 'ON'

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: RDSDBClusterParameterGroup: Type: AWS::RDS::DBClusterParameterGroup Properties: Description: Fn::Sub: ${AWS::StackName}-example Family: postgres14 Parameters: rds.force_ssl: true

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: RDSDBClusterParameterGroup: Type: AWS::RDS::DBClusterParameterGroup Properties: Description: Fn::Sub: ${AWS::StackName}-example Family: aurora-mysql5.7 Parameters: require_secure_transport: 'OFF'

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: RDSDBClusterParameterGroup: Type: AWS::RDS::DBClusterParameterGroup Properties: Description: Fn::Sub: ${AWS::StackName}-example Family: mysql8.0 Parameters: require_secure_transport: 0

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: RDSDBClusterParameterGroup: Type: AWS::RDS::DBClusterParameterGroup Properties: Description: Fn::Sub: ${AWS::StackName}-example Family: postgres15 Parameters: rds.force_ssl: false

[CT.RDS.PR.28] Exiger un groupe de paramètres de base de données Amazon Relational Database Service pour exiger des connexions TLS (Transport Layer Security) pour les types de moteurs pris en charge

Ce contrôle vérifie si un groupe de paramètres de base de données Amazon Relational Database Service nécessite des connexions TLS (Transport Layer Security), pour les types de moteurs pris en charge.

  • Objectif de contrôle : crypter les données en transit

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBParameterGroup

  • AWS CloudFormationrègle de garde : Spécification de la règle CT.RDS.PR.28

Détails et exemples

Explication

Vous pouvez utiliser le protocole SSL ou le protocole TLS (Transport Layer Security) à partir de votre application pour chiffrer une connexion à une instance de base de données exécutant MariaDB, Microsoft SQL Server, MySQL, Oracle ou PostgreSQL. Les connexions SSL/TLS fournissent une couche de sécurité en chiffrant les données qui circulent entre votre client et l'instance de base de données.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux groupes de paramètres de base de données Amazon RDS comportant des familles postgressqlserver, mariadb (mariadb10.0à l'exception demariadb10.4) et mysql (mysql5.5à l'exception demysql5.6)

Corrections en cas de défaillance des règles

Pour les groupes de paramètres d'instances de base de données Amazon RDS avec mysql et mariadb familles, dansParameters, définis surrequire_secure_transport. true Pour les groupes de paramètres d'instances de base de données Amazon RDS avec postgres et sqlserver familles, dansParameters, définis surrds.force_ssl. true

Les exemples suivants montrent comment mettre en œuvre cette correction.

Groupe de paramètres de base de données Amazon RDS : premier exemple

Un groupe de paramètres de base de données Amazon RDS configuré pour exiger le protocole TLS/SSL pour toutes les connexions aux instances de base de données MariaDB. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "RDSDBParameterGroup": { "Type": "AWS::RDS::DBParameterGroup", "Properties": { "Description": "sample-db-parameter-group", "Family": "mariadb10.6", "Parameters": { "require_secure_transport": true } } } }

Exemple YAML

RDSDBParameterGroup: Type: AWS::RDS::DBParameterGroup Properties: Description: sample-db-parameter-group Family: mariadb10.6 Parameters: require_secure_transport: true

Les exemples suivants montrent comment mettre en œuvre cette correction.

Groupe de paramètres de base de données Amazon RDS : deuxième exemple

Un groupe de paramètres de base de données Amazon RDS configuré pour exiger le protocole TLS/SSL pour toutes les connexions aux instances de base de données PostgreSQL. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "RDSDBParameterGroup": { "Type": "AWS::RDS::DBParameterGroup", "Properties": { "Description": "sample-db-parameter-group", "Family": "postgres14", "Parameters": { "rds.force_ssl": true } } } }

Exemple YAML

RDSDBParameterGroup: Type: AWS::RDS::DBParameterGroup Properties: Description: sample-db-parameter-group Family: postgres14 Parameters: rds.force_ssl: true

Spécification de la règle CT.RDS.PR.28

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_db_parameter_group_tls_check # # Description: # This control checks whether an Amazon RDS DB parameter group requires Transport Layer Security (TLS) connections, for supported engine types. # # Reports on: # AWS::RDS::DBParameterGroup # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any Amazon RDS DB parameter group resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an Amazon RDS DB parameter group resource # And: 'Family' has not been provided or has been provided and set to an Amazon RDS DB # parameter group family other than one with support for requiring TLS connections # ('mariadb' - excluding mariadb families 10.0 to 10.4, 'mysql' - excluding mysql # families 5.5 to 5.6, 'postgres' or 'sqlserver') # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an Amazon RDS DB parameter group resource # And: 'Family' has been provided and set to Amazon RDS parameter group families 'mariadb' # (excluding families 10.0 to 10.4) or 'mysql' (excluding families 5.5 to 5.6) # And: In 'Parameters', 'require_secure_transport' has not been provided, or # has been provided and set to a value other than a boolean true value # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an Amazon RDS DB parameter group resource # And: 'Family' has been provided and set to Amazon RDS parameter group families 'sqlserver' or 'postgres' # And: In 'Parameters', 'rds.force_ssl' has not been provided, or has been provided # and set to a value other than a boolean true value # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an Amazon RDS DB parameter group resource # And: 'Family' has been provided and set to Amazon RDS parameter group families 'mariadb' # (excluding families 10.0 to 10.4) or 'mysql' (excluding families 5.5 to 5.6) # And: In 'Parameters', 'require_secure_transport' has been provided and set to # a boolean true value # Then: PASS # Scenario: 6 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an Amazon RDS DB parameter group resource # And: 'Family' has been provided and set to Amazon RDS parameter group families 'sqlserver' or 'postgres' # And: In 'Parameters', 'rds.force_ssl' has been provided and set to # a boolean true value # Then: PASS # # Constants # let INPUT_DOCUMENT = this let RDS_DB_PARAMETER_GROUP_TYPE = "AWS::RDS::DBParameterGroup" let MYSQL_PG_FAMILY = /^mysql/ let MARIADB_PG_FAMILY = /^mariadb/ let POSTGRES_PG_FAMILY = /^postgres/ let SQLSERVER_PG_FAMILY = /^sqlserver/ let MYSQL_FAMILIES_WITH_NO_SECURE_TRANSPORT_SUPPORT = [ "mysql5.5", "mysql5.6" ] let MARIADB_FAMILIES_WITH_NO_SECURE_TRANSPORT_SUPPORT = [ "mariadb10.0", "mariadb10.1", "mariadb10.2", "mariadb10.3", "mariadb10.4" ] let BOOLEAN_TRUE_VALUES = [ true, 1, "1", "true", "True", "TRUE", "on", "On", "ON" ] # # Assignments # let rds_db_parameter_groups = Resources.*[ Type == %RDS_DB_PARAMETER_GROUP_TYPE ] # # Primary Rules # rule rds_db_parameter_group_tls_check when is_cfn_template(%INPUT_DOCUMENT) %rds_db_parameter_groups not empty { check(%rds_db_parameter_groups.Properties) << [CT.RDS.PR.28]: Require an Amazon RDS DB parameter group to require Transport Layer Security (TLS) connections for supported engine types [FIX]: For Amazon RDS DB instance parameter groups with 'mysql' and 'mariadb' families, in 'Parameters', set 'require_secure_transport' to 'true'. For Amazon RDS DB instance parameter groups with 'postgres' and 'sqlserver' families, in 'Parameters', set 'rds.force_ssl' to 'true'. >> } rule rds_db_parameter_group_tls_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_PARAMETER_GROUP_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_PARAMETER_GROUP_TYPE.resourceProperties) << [CT.RDS.PR.28]: Require an Amazon RDS DB parameter group to require Transport Layer Security (TLS) connections for supported engine types [FIX]: For Amazon RDS DB instance parameter groups with 'mysql' and 'mariadb' families, in 'Parameters', set 'require_secure_transport' to 'true'. For Amazon RDS DB instance parameter groups with 'postgres' and 'sqlserver' families, in 'Parameters', set 'rds.force_ssl' to 'true'. >> } # # Parameterized Rules # rule check(rds_parameter_group) { %rds_parameter_group [ # Scenario 2 filter_pg_mysql_maria_families(this) ] { # Scenarios 3 and 5 Parameters exists Parameters is_struct Parameters { require_secure_transport exists require_secure_transport in %BOOLEAN_TRUE_VALUES } } %rds_parameter_group [ # Scenario 2 filter_pg_postgres_sqlserver_families(this) ] { # Scenarios 4 and 6 Parameters exists Parameters is_struct Parameters { "rds.force_ssl" exists "rds.force_ssl" in %BOOLEAN_TRUE_VALUES } } } rule filter_pg_mysql_maria_families(parameter_group) { %parameter_group { Family exists filter_mysql_family(this) or filter_mariadb_family(this) } } rule filter_mysql_family(parameter_group) { %parameter_group { Family in %MYSQL_PG_FAMILY Family not in %MYSQL_FAMILIES_WITH_NO_SECURE_TRANSPORT_SUPPORT } } rule filter_mariadb_family(parameter_group) { %parameter_group { Family in %MARIADB_PG_FAMILY Family not in %MARIADB_FAMILIES_WITH_NO_SECURE_TRANSPORT_SUPPORT } } rule filter_pg_postgres_sqlserver_families(parameter_group) { %parameter_group { Family exists Family in %POSTGRES_PG_FAMILY or Family in %SQLSERVER_PG_FAMILY } } # # Utility Rules # rule check_is_list_and_not_empty(value) { %value { this is_list this not empty } } rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

Exemples de modèles CT.RDS.PR.28

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: RDSDBParameterGroup: Type: AWS::RDS::DBParameterGroup Properties: Description: Fn::Sub: ${AWS::StackName}-example Family: mariadb10.6 Parameters: require_secure_transport: true

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: RDSDBParameterGroup: Type: AWS::RDS::DBParameterGroup Properties: Description: Fn::Sub: ${AWS::StackName}-example Family: postgres14 Parameters: rds.force_ssl: true

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: RDSDBParameterGroup: Type: AWS::RDS::DBParameterGroup Properties: Description: Fn::Sub: ${AWS::StackName}-example Family: mariadb10.6 Parameters: require_secure_transport: false

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: RDSDBParameterGroup: Type: AWS::RDS::DBParameterGroup Properties: Description: Fn::Sub: ${AWS::StackName}-example Family: postgres15 Parameters: rds.force_ssl: false

[CT.RDS.PR.29] Exiger qu'un cluster Amazon RDS ne soit pas configuré pour être accessible au public au moyen de la propriété « PubliclyAccessible »

Ce contrôle vérifie si un cluster de base de données Amazon Relational Database Service est configuré pour être accessible au public ou non, conformément au paramètre de PubliclyAccessible la propriété.

  • Objectif de contrôle : limiter l'accès au réseau

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBCluster

  • AWS CloudFormationrègle de garde : Spécification de la règle CT.RDS.PR.29

Détails et exemples

Explication

La PubliclyAccessible propriété de la AWS CloudFormation ressource de cluster de base de données Amazon RDS indique si le cluster de base de données est accessible au public. Lorsque l'instance de base de données est configurée avec la PubliclyAccessible propriété définie sur true, son point de terminaison DNS (Domain Name System) est résolu vers l'adresse IP publique depuis l'extérieur du cloud privé virtuel (VPC) du cluster de bases de données, et il est également résolu vers l'adresse IP privée depuis le VPC du cluster de base de données.

À moins que vous n'ayez l'intention de rendre votre cluster de base de données Amazon RDS accessible au public, ne configurez pas le cluster de base de données Amazon RDS avec la PubliclyAccessible valeur true, car cette configuration peut autoriser un trafic indésirable vers votre instance de base de données.

Corrections en cas de défaillance des règles

Définissez la valeur de la PubliclyAccessible propriété sur false.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Cluster de bases de données Amazon RDS : exemple

Un cluster de base de données Postgres Amazon RDS Multi-AZ configuré pour ne pas être accessible au public. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "DBCluster": { "Type": "AWS::RDS::DBCluster", "Properties": { "Engine": "postgres", "DBClusterInstanceClass": "db.m6gd.large", "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBClusterSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBClusterSecret}::password}}" }, "DBSubnetGroupName": { "Ref": "DBSubnetGroup" }, "AllocatedStorage": 100, "StorageType": "io1", "Iops": 3000, "PubliclyAccessible": false } } }

Exemple YAML

DBCluster: Type: AWS::RDS::DBCluster Properties: Engine: postgres DBClusterInstanceClass: db.m6gd.large MasterUsername: !Sub '{{resolve:secretsmanager:${DBClusterSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBClusterSecret}::password}}' DBSubnetGroupName: !Ref 'DBSubnetGroup' AllocatedStorage: 100 StorageType: io1 Iops: 3000 PubliclyAccessible: false

Spécification de la règle CT.RDS.PR.29

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_cluster_public_access_check # # Description: # This control checks whether an Amazon RDS database cluster is configured to be publicly accessible, or not, as determined by the setting of the PubliclyAccessible property. # # Reports on: # AWS::RDS::DBCluster # # Evaluates: # AWS CloudFormation, AWS CloudFormation hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any Amazon RDS DB cluster resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an Amazon RDS DB cluster resource # And: 'Engine' has been provided and set to a database engine type other than a # Multi-AZ database engine (type other than 'mysql' or 'postgres') # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an Amazon RDS DB cluster resource # And: 'Engine' has been provided and set to a Multi-AZ database engine # ('mysql', 'postgres') # And: 'PubliclyAccessible' has not been provided # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an Amazon RDS DB cluster resource # And: 'Engine' has been provided and set to a Multi-AZ database engine # ('mysql', 'postgres') # And: 'PubliclyAccessible' has been provided and set to a value other than bool(false) # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains an Amazon RDS DB cluster resource # And: 'Engine' has been provided and set to a Multi-AZ database engine # ('mysql', 'postgres') # And: 'PubliclyAccessible' has been provided and set to bool(false) # Then: PASS # # Constants # let INPUT_DOCUMENT = this let RDS_DB_CLUSTER_TYPE = "AWS::RDS::DBCluster" let MULTI_AZ_ENGINE_TYPES = [ "mysql", "postgres" ] # # Assignments # let rds_db_clusters = Resources.*[ Type == %RDS_DB_CLUSTER_TYPE ] # # Primary Rules # rule rds_cluster_public_access_check when is_cfn_template(%INPUT_DOCUMENT) %rds_db_clusters not empty { check(%rds_db_clusters.Properties) << [CT.RDS.PR.29]: Require an Amazon RDS cluster not be configured to be publicly accessible by means of the 'PubliclyAccessible' property [FIX]: Set the value of the PubliclyAccessible property to false. >> } rule rds_cluster_public_access_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_CLUSTER_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_CLUSTER_TYPE.resourceProperties) << [CT.RDS.PR.29]: Require an Amazon RDS cluster not be configured to be publicly accessible by means of the 'PubliclyAccessible' property [FIX]: Set the value of the PubliclyAccessible property to false. >> } # # Parameterized Rules # rule check(rds_db_cluster) { %rds_db_cluster[ filter_multi_az_engine(this) ] { # Scenario 2 PubliclyAccessible exists # Scenarios 3 and 4 PubliclyAccessible == false } } rule filter_multi_az_engine(rds_db_cluster) { %rds_db_cluster { Engine exists Engine in %MULTI_AZ_ENGINE_TYPES } } # # Utility Rules # rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists }

Exemples de modèles CT.RDS.PR.29

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: DBClusterSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB cluster secret GenerateSecretString: SecretStringTemplate: '{"username": "exampleuser"}' GenerateStringKey: password PasswordLength: 16 ExcludeCharacters: '"@/\' DBCluster: Type: AWS::RDS::DBCluster Properties: DBClusterIdentifier: example-db-cluster DBClusterInstanceClass: db.m5d.large MasterUsername: Fn::Sub: "{{resolve:secretsmanager:${DBClusterSecret}::username}}" MasterUserPassword: Fn::Sub: "{{resolve:secretsmanager:${DBClusterSecret}::password}}" Engine: mysql AllocatedStorage: 100 StorageType: io1 Iops: 1000 PubliclyAccessible: false

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: DBClusterSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB cluster secret GenerateSecretString: SecretStringTemplate: '{"username": "exampleuser"}' GenerateStringKey: password PasswordLength: 16 ExcludeCharacters: '"@/\' DBCluster: Type: AWS::RDS::DBCluster Properties: DBClusterIdentifier: example-db-cluster-public DBClusterInstanceClass: db.m5d.large MasterUsername: Fn::Sub: "{{resolve:secretsmanager:${DBClusterSecret}::username}}" MasterUserPassword: Fn::Sub: "{{resolve:secretsmanager:${DBClusterSecret}::password}}" Engine: mysql AllocatedStorage: 100 StorageType: io1 Iops: 1000 PubliclyAccessible: true

[CT.RDS.PR.30] Exiger que le chiffrement au repos d'une instance de base de données Amazon RDS soit configuré pour utiliser une clé KMS que vous spécifiez pour les types de moteurs pris en charge

Ce contrôle vérifie si le chiffrement du stockage est activé pour votre instance de base de données (DB) Amazon RDS et si le chiffrement utilise une clé KMS que vous spécifiez pour les types de moteurs pris en charge.

  • Objectif de contrôle : crypter les données au repos

  • Mise en œuvre : règle de AWS CloudFormation garde

  • Comportement de contrôle : proactif

  • Types de ressources : AWS::RDS::DBInstance

  • AWS CloudFormationrègle de garde : Spécification de la règle CT.RDS.PR.30

Détails et exemples

Explication

Pour renforcer la sécurité de vos données sensibles dans les instances de base de données Amazon RDS, vous pouvez configurer vos instances de base de données Amazon RDS pour qu'elles soient chiffrées au repos. Pour chiffrer vos instances de base de données Amazon RDS et vos instantanés au repos, activez l'option de chiffrement pour vos instances de base de données Amazon RDS. Les données qui sont chiffrées au repos incluent le stockage sous-jacent pour des instance DB, les sauvegardes automatisées, les réplicas en lecture et les instantanés.

Les instances de base de données cryptées Amazon RDS utilisent l'algorithme de chiffrement standard ouvert AES-256 pour chiffrer vos données résidant sur le serveur qui héberge vos instances de base de données Amazon RDS. Une fois vos données chiffrées, Amazon RDS gère l'authentification de l'accès et le déchiffrement de vos données de manière transparente, avec un impact minimal sur les performances. Vous n'avez pas besoin de modifier vos applications clientes de base de données pour utiliser le chiffrement.

Le chiffrement Amazon RDS est disponible pour tous les moteurs de base de données et types de stockage. Le chiffrement Amazon RDS est disponible pour la plupart des classes d'instance de base de données.

Considérations d'utilisation
  • Ce contrôle s'applique uniquement aux types de moteurs de base de données Amazon RDS mariadb mysql oracle-eeoracle-ee-cdb,oracle-se2,oracle-se2-cdb,,postgres, sqlserver-eesqlserver-se, et sqlserver-web

  • Ce contrôle s'applique uniquement lorsque la Engine propriété est fournie. Cela ne s'applique pas lors de la restauration à partir d'un instantané de base de données ou d'un instantané de cluster pour lequel un n'Enginea pas été défini explicitement.

  • Ce contrôle nécessite qu'une clé KMS soit spécifiée pour les ressources de l'instance de base de données Amazon RDS. Il ne vérifie pas les propriétés de la clé KMS utilisée, par exemple si la clé KMS est gérée par le client ou par le service.

  • Envisagez d'utiliser une clé gérée par le client si vous souhaitez contrôler totalement la clé KMS, ce qui inclut l'établissement et la maintenance des politiques, des politiques IAM et des autorisations de la clé, ainsi que l'activation et la désactivation de la clé, la rotation de son matériel cryptographique, l'ajout de balises, la création d'alias faisant référence à la clé KMS et la planification de la suppression de la clé KMS.

Corrections en cas de défaillance des règles

Définissez la KmsKeyId propriété sur l'ARN d'un fichier AWS KMS key configuré pour accorder des autorisations d'utilisation des clés à Amazon RDS.

Les exemples suivants montrent comment mettre en œuvre cette correction.

Instance de base de données Amazon RDS - Exemple

Une instance de base de données Amazon RDS avec le chiffrement du stockage activé. L'exemple est présenté en JSON et en YAML.

Exemple JSON

{ "RDSDBInstance": { "Type": "AWS::RDS::DBInstance", "Properties": { "Engine": "postgres", "EngineVersion": 14.2, "DBInstanceClass": "db.m5.large", "StorageType": "gp2", "AllocatedStorage": 5, "MasterUsername": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::username}}" }, "MasterUserPassword": { "Fn::Sub": "{{resolve:secretsmanager:${DBInstanceSecret}::password}}" }, "StorageEncrypted": true, "KmsKeyId": { "Ref": "KMSKey" } } } }

Exemple YAML

RDSDBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 14.2 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' StorageEncrypted: true KmsKeyId: !Ref 'KMSKey'

Spécification de la règle CT.RDS.PR.30

# ################################### ## Rule Specification ## ##################################### # # Rule Identifier: # rds_storage_encrypted_kms_key_check # # Description: # This control checks whether storage encryption is enabled for your Amazon RDS database (DB) instance, and that the encryption uses a KMS key that you specify for supported engine types. # # Reports on: # AWS::RDS::DBInstance # # Evaluates: # AWS CloudFormation, AWS CloudFormation Hook # # Rule Parameters: # None # # Scenarios: # Scenario: 1 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document does not contain any Amazon RDS DB instance resources # Then: SKIP # Scenario: 2 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Amazon RDS DB instance resource # And: 'Engine' is not one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', # 'oracle-se2', 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', # 'sqlserver-web' # Then: SKIP # Scenario: 3 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Amazon RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', # 'oracle-se2', 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', # 'sqlserver-web' # And: 'KmsKeyId' has not been provided # Then: FAIL # Scenario: 4 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Amazon RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', # 'oracle-se2', 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', # 'sqlserver-web' # And: 'KmsKeyId' has been provided as an empty string or invalid local reference # to a KMS key ID or alias or ARN # Then: FAIL # Scenario: 5 # Given: The input document is an AWS CloudFormation or AWS CloudFormation hook document # And: The input document contains a Amazon RDS DB instance resource # And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', # 'oracle-se2', 'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', # 'sqlserver-web' # And: 'KmsKeyId' has been provided as a non-empty string or valid local reference # to a KMS key ID or alias or ARN # Then: PASS # # Constants # let INPUT_DOCUMENT = this let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance" let SUPPORTED_RDS_INSTANCE_ENGINES = [ "mariadb", "mysql", "oracle-ee", "oracle-ee-cdb", "oracle-se2", "oracle-se2-cdb", "postgres", "sqlserver-ee", "sqlserver-se", "sqlserver-web" ] # # Assignments # let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ] # # Primary Rules # rule rds_storage_encrypted_kms_key_check when is_cfn_template(%INPUT_DOCUMENT) %rds_db_instances not empty { check(%rds_db_instances.Properties) << [CT.RDS.PR.30]: Require that an Amazon RDS database instance has encryption at rest configured to use a KMS key that you specify for supported engine types [FIX]: Set the KmsKeyId property to the ARN of an AWS KMS key that is configured to grant key usage permissions to Amazon RDS. >> } rule rds_storage_encrypted_kms_key_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) { check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties) << [CT.RDS.PR.30]: Require that an Amazon RDS database instance has encryption at rest configured to use a KMS key that you specify for supported engine types [FIX]: Set the KmsKeyId property to the ARN of an AWS KMS key that is configured to grant key usage permissions to Amazon RDS. >> } # # Parameterized Rules # rule check(rds_db_instance) { %rds_db_instance [ # Scenario 2 filter_engine(this) ] { # Scenario 3 KmsKeyId exists # Scenarios 4 and 5 check_is_string_and_not_empty(KmsKeyId) or check_local_references(%INPUT_DOCUMENT, KmsKeyId, "AWS::KMS::Key") or check_local_references(%INPUT_DOCUMENT, KmsKeyId, "AWS::KMS::Alias") } } rule filter_engine(rds_db_instance) { %rds_db_instance { Engine exists Engine is_string Engine in %SUPPORTED_RDS_INSTANCE_ENGINES } } # # Utility Rules # rule check_is_string_and_not_empty(value) { %value { this is_string this != /\A\s*\z/ } } rule is_cfn_template(doc) { %doc { AWSTemplateFormatVersion exists or Resources exists } } rule is_cfn_hook(doc, RESOURCE_TYPE) { %doc.%RESOURCE_TYPE.resourceProperties exists } rule check_local_references(doc, reference_properties, referenced_RESOURCE_TYPE) { %reference_properties { 'Fn::GetAtt' { query_for_resource(%doc, this[0], %referenced_RESOURCE_TYPE) <<Local Stack reference was invalid>> } or Ref { query_for_resource(%doc, this, %referenced_RESOURCE_TYPE) <<Local Stack reference was invalid>> } } } rule query_for_resource(doc, resource_key, referenced_RESOURCE_TYPE) { let referenced_resource = %doc.Resources[ keys == %resource_key ] %referenced_resource not empty %referenced_resource { Type == %referenced_RESOURCE_TYPE } }

Exemples de modèles CT.RDS.PR.30

Vous pouvez consulter des exemples d'artefacts de test PASS et FAIL pour les contrôles proactifs de l'AWS Control Tower.

Exemple PASS - Utilisez ce modèle pour vérifier la conformité de la création d'une ressource.

Resources: KMSKey: Type: AWS::KMS::Key Properties: KeyPolicy: Version: 2012-10-17 Id: example-policy Statement: - Sid: Enable IAM User Permissions Effect: Allow Principal: AWS: Fn::Sub: arn:${AWS::Partition}:iam::${AWS::AccountId}:root Action: kms:* Resource: '*' KeySpec: SYMMETRIC_DEFAULT EnableKeyRotation: true DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS DB instance secret GenerateSecretString: SecretStringTemplate: '{"username": "examplemasteruser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: '"@/\' DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: mysql EngineVersion: 5.7 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' StorageEncrypted: true KmsKeyId: Ref: KMSKey DeletionPolicy: Delete

Exemple d'échec : utilisez ce modèle pour vérifier que le contrôle empêche la création de ressources non conformes.

Resources: DBInstanceSecret: Type: AWS::SecretsManager::Secret Properties: Description: RDS instance secret GenerateSecretString: SecretStringTemplate: '{"username": "exampleuser"}' GenerateStringKey: password PasswordLength: 22 ExcludeCharacters: "/@\"" DBInstance: Type: AWS::RDS::DBInstance Properties: Engine: postgres EngineVersion: 15.4 DBInstanceClass: db.m5.large StorageType: gp2 AllocatedStorage: 5 MasterUsername: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::username}}' MasterUserPassword: Fn::Sub: '{{resolve:secretsmanager:${DBInstanceSecret}::password}}' DeletionPolicy: Delete