diff --git a/avd_docs/google/sql/AVD-GCP-0015/Terraform.md b/avd_docs/google/sql/AVD-GCP-0015/Terraform.md index 74819cc4..740d77d2 100644 --- a/avd_docs/google/sql/AVD-GCP-0015/Terraform.md +++ b/avd_docs/google/sql/AVD-GCP-0015/Terraform.md @@ -2,6 +2,7 @@ Enforce SSL for all connections ```hcl + # For terraform-provider-google < 6.0.1 resource "google_sql_database_instance" "postgres" { name = "postgres-instance-a" database_version = "POSTGRES_11" @@ -20,6 +21,27 @@ Enforce SSL for all connections } } +``` +```hcl + # For terraform-provider-google >= 6.0.1 + resource "google_sql_database_instance" "postgres" { + name = "postgres-instance-a" + database_version = "POSTGRES_11" + + settings { + tier = "db-f1-micro" + + ip_configuration { + ipv4_enabled = false + authorized_networks { + value = "108.12.12.0/24" + name = "internal" + } + ssl_mode = "TRUSTED_CLIENT_CERTIFICATE_REQUIRED" + } + } + } + ``` #### Remediation Links diff --git a/checks/cloud/google/sql/encrypt_in_transit_data.rego b/checks/cloud/google/sql/encrypt_in_transit_data.rego index b68476a5..9a00211c 100644 --- a/checks/cloud/google/sql/encrypt_in_transit_data.rego +++ b/checks/cloud/google/sql/encrypt_in_transit_data.rego @@ -30,11 +30,29 @@ package builtin.google.sql.google0015 import rego.v1 +ssl_mode_trusted_client_certificate_required := "TRUSTED_CLIENT_CERTIFICATE_REQUIRED" + deny contains res if { some instance in input.google.sql.instances - instance.settings.ipconfiguration.requiretls.value == false + not is_ssl_enforced(instance.settings.ipconfiguration) res := result.new( "Database instance does not require TLS for all connections.", - instance.settings.ipconfiguration.requiretls, + instance.settings.ipconfiguration, ) } + +# sslMode=ENCRYPTED_ONLY also allows SSL/TLS encrypted connections, +# but the client certificate is not validated as in the case of `requiretls`. +# https://cloud.google.com/sql/docs/postgres/admin-api/rest/v1beta4/instances#sslmode +is_ssl_enforced(ipconf) if { + ipconf.sslmode.value == ssl_mode_trusted_client_certificate_required +} + +# "sslMode" has been added to replace "requireSsl", but we still have to support +# the deprecated attribute for users using an older version of the provider +is_ssl_enforced(ipconf) if { + not has_ssl_mode(ipconf) + ipconf.requiretls.value == true +} + +has_ssl_mode(ipconf) if ipconf.sslmode.value != "" diff --git a/checks/cloud/google/sql/encrypt_in_transit_data.tf.go b/checks/cloud/google/sql/encrypt_in_transit_data.tf.go index 6f568f72..63878789 100644 --- a/checks/cloud/google/sql/encrypt_in_transit_data.tf.go +++ b/checks/cloud/google/sql/encrypt_in_transit_data.tf.go @@ -2,6 +2,7 @@ package sql var terraformEncryptInTransitDataGoodExamples = []string{ ` + # For terraform-provider-google < 6.0.1 resource "google_sql_database_instance" "postgres" { name = "postgres-instance-a" database_version = "POSTGRES_11" @@ -18,6 +19,26 @@ var terraformEncryptInTransitDataGoodExamples = []string{ require_ssl = true } } + } + `, + ` + # For terraform-provider-google >= 6.0.1 + resource "google_sql_database_instance" "postgres" { + name = "postgres-instance-a" + database_version = "POSTGRES_11" + + settings { + tier = "db-f1-micro" + + ip_configuration { + ipv4_enabled = false + authorized_networks { + value = "108.12.12.0/24" + name = "internal" + } + ssl_mode = "TRUSTED_CLIENT_CERTIFICATE_REQUIRED" + } + } } `, } @@ -42,6 +63,25 @@ var terraformEncryptInTransitDataBadExamples = []string{ } } `, + ` + resource "google_sql_database_instance" "postgres" { + name = "postgres-instance-a" + database_version = "POSTGRES_11" + + settings { + tier = "db-f1-micro" + + ip_configuration { + ipv4_enabled = false + authorized_networks { + value = "108.12.12.0/24" + name = "internal" + } + ssl_mode = "ALLOW_UNENCRYPTED_AND_ENCRYPTED" + } + } + } +`, } var terraformEncryptInTransitDataLinks = []string{ diff --git a/checks/cloud/google/sql/encrypt_in_transit_data_test.rego b/checks/cloud/google/sql/encrypt_in_transit_data_test.rego index 08a8c361..4c52d7c9 100644 --- a/checks/cloud/google/sql/encrypt_in_transit_data_test.rego +++ b/checks/cloud/google/sql/encrypt_in_transit_data_test.rego @@ -18,4 +18,11 @@ test_deny_tls_not_required if { count(res) == 1 } +test_deny_tls_not_required_but_ssl_mode_require_ssl if { + inp := build_input({"requiretls": {"value": false}, "ssl_mode": {"value": check.ssl_mode_trusted_client_certificate_required}}) + + res := check.deny with input as inp + count(res) == 1 +} + build_input(ipconfig) := {"google": {"sql": {"instances": [{"settings": {"ipconfiguration": ipconfig}}]}}}