Skip to content

Instantly share code, notes, and snippets.

@x-yuri
Last active April 19, 2024 14:59
Show Gist options
  • Save x-yuri/447aec2e72d27db5a70259f0eef33824 to your computer and use it in GitHub Desktop.
Save x-yuri/447aec2e72d27db5a70259f0eef33824 to your computer and use it in GitHub Desktop.
Cloud SQL + SSL/TLS

Cloud SQL + SSL/TLS

main.tf:

provider "google" {
  project = "PROJECT_ID"
}

resource "google_sql_database_instance" "test-sql" {
  # deletion_protection = false
  name = "test-sql"
  region = "europe-central2"
  database_version = "POSTGRES_15"
  settings {
    tier = "db-f1-micro"
    ip_configuration {
      # require_ssl = true
      authorized_networks {
        name = "me"
        value = "SOURCE_IP"
      }
    }
  }
}

resource "google_sql_user" "test-sql" {
  name = "postgres"
  instance = google_sql_database_instance.test-sql.name
  password = 1
}

# resource "google_sql_ssl_cert" "test-sql" {
#   common_name = "whatever"
#   instance = google_sql_database_instance.test-sql.name
# }

a.rb:

require 'pg'
PG.connect(host: 'HOST', password: '1', user: 'postgres')
// replace PROJECT_ID, SOURCE_IP
$ docker run --rm -itv "$PWD:/app" -w /app google/cloud-sdk:457.0.0-alpine
/app # gcloud auth login --update-adc
/app # apk add terraform
/app # terraform init
/app # terraform apply; echo -e '\a'

/app # terraform show -json \
| jq -r '.values.root_module.resources[]
         | select(.address == "google_sql_database_instance.test-sql")
           .values.first_ip_address'
xx.xxx.xx.xxx

/app # psql -h xx.xxx.xx.xxx -U postgres
Password for user postgres:
psql (16.2, server 15.5)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.

postgres=>

/app # psql -h xx.xxx.xx.xxx -U postgres sslmode=disable
Password for user postgres:
psql (16.2, server 15.5)
Type "help" for help.

postgres=>

/app # psql -h xx.xxx.xx.xxx -U postgres sslmode=verify-ca
psql: error: connection to server at "xx.xxx.xx.xxx", port 5432 failed: root certificate file "/root/.postgresql/root.crt" does not exist
Either provide the file, use the system's trusted roots with sslrootcert=system, or change sslmode to disable server certificate verification.

/app # mkdir ~/.postgresql
/app # terraform show -json \
| jq -r '.values.root_module.resources[]
         | select(.address == "google_sql_database_instance.test-sql")
           .values.server_ca_cert[0].cert' \
> ~/.postgresql/root.crt
/app # psql -h xx.xxx.xx.xxx -U postgres sslmode=verify-ca
Password for user postgres:
psql (16.2, server 15.5)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.

postgres=>

/app # psql -h xx.xxx.xx.xxx -U postgres sslmode=verify-full
psql: error: connection to server at "xx.xxx.xx.xxx", port 5432 failed: server certificate for "31-45c75b34-8ff0-4158-a6ca-2b6506d29fff.europe-central2.sql.goog" (and 1 other name) does not match host name "xx.xxx.xx.xxx"

/app # psql -U postgres 'sslmode=verify-full hostaddr=xx.xxx.xx.xxx host=test-sql'
psql: error: connection to server at "xx.xxx.xx.xxx", port 5432 failed: server certificate for "31-45c75b34-8ff0-4158-a6ca-2b6506d29fff.europe-central2.sql.goog" does not match host name "test-sql"

/app # psql -U postgres 'sslmode=verify-full hostaddr=xx.xxx.xx.xxx host=ometv-stage:europe-central2:test-sql'
psql: error: connection to server at "xx.xxx.xx.xxx", port 5432 failed: server certificate for "31-45c75b34-8ff0-4158-a6ca-2b6506d29fff.europe-central2.sql.goog" does not match host name "ometv-stage:europe-central2:test-sql"

// uncomment the lines in main.tf

/app # terraform apply; echo -e '\a'

/app # psql -h xx.xxx.xx.xxx -U postgres sslmode=verify-ca
psql: error: connection to server at "xx.xxx.xx.xxx", port 5432 failed: FATAL:  connection requires a valid client certificate

/app # terraform show -json \
| jq -r '.values.root_module.resources[]
         | select(.address == "google_sql_ssl_cert.test-sql")
           .values.cert' \
> ~/.postgresql/postgresql.crt
/app # terraform show -json \
| jq -r '.values.root_module.resources[]
         | select(.address == "google_sql_ssl_cert.test-sql")
           .values.private_key' \
> ~/.postgresql/postgresql.key
/app # chmod 600 ~/.postgresql/postgresql.key
/app # psql -h xx.xxx.xx.xxx -U postgres sslmode=verify-ca
Password for user postgres:
psql (16.2, server 15.5)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.

postgres=>

// replace HOST in a.rb

/app # apk add ruby-dev postgresql-dev build-base
/app # gem install pg -v 1.5.6
/app # ruby a.rb
#<PG::Connection:0x00007e2d64574a08 host=xx.xxx.xx.xxx port=5432 user=postgres>

SSL is used by default, but the server certificate is not verified. To verify the server certificate it needs root.crt. To use certificate authentication it needs postgresql.crt, postgresql.key, and require_ssl = true.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment