diff --git a/scripts/generate_pgsql_certs.sh b/scripts/generate_pgsql_certs.sh new file mode 100755 index 0000000000..487f137d81 --- /dev/null +++ b/scripts/generate_pgsql_certs.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +set -euo pipefail + +CERT_DIR="${1:-$(dirname "$0")/../tests-integration/fixtures/pgsql-certs}" +DAYS="${2:-365}" + +mkdir -p "${CERT_DIR}" +cd "${CERT_DIR}" + +echo "Generating CA certificate..." +openssl req -new -x509 -days "${DAYS}" -nodes -text \ + -out root.crt -keyout root.key \ + -subj "/CN=PostgresRootCA" + + +echo "Generating server certificate..." +openssl req -new -nodes -text \ + -out server.csr -keyout server.key \ + -subj "/CN=postgres" + +openssl x509 -req -in server.csr -text -days "${DAYS}" \ + -CA root.crt -CAkey root.key -CAcreateserial \ + -out server.crt \ + -extensions v3_req -extfile <(printf "[v3_req]\nsubjectAltName=DNS:localhost,IP:127.0.0.1") + +echo "Generating client certificate..." +# Make sure the client certificate is for the greptimedb user +openssl req -new -nodes -text \ + -out client.csr -keyout client.key \ + -subj "/CN=greptimedb" + +openssl x509 -req -in client.csr -CA root.crt -CAkey root.key -CAcreateserial \ +-out client.crt -days 365 -extensions v3_req -extfile <(printf "[v3_req]\nsubjectAltName=DNS:localhost") + +rm -f *.csr + +echo "TLS certificates generated successfully in ${CERT_DIR}" + +chmod 600 root.key +chmod 600 client.key +chmod 600 server.key diff --git a/src/common/meta/src/kv_backend/rds/postgres.rs b/src/common/meta/src/kv_backend/rds/postgres.rs index 16fa1b1008..ad59a6b71a 100644 --- a/src/common/meta/src/kv_backend/rds/postgres.rs +++ b/src/common/meta/src/kv_backend/rds/postgres.rs @@ -903,6 +903,7 @@ mod tests { test_txn_compare_less, test_txn_compare_not_equal, test_txn_one_compare_op, text_txn_multi_compare_op, unprepare_kv, }; + use crate::test_util::pgsql_certs_dir; use crate::{maybe_skip_postgres_integration_test, maybe_skip_postgres15_integration_test}; async fn build_pg_kv_backend(table_name: &str) -> Option { @@ -993,6 +994,97 @@ mod tests { unprepare_kv(&kv, prefix).await; } + #[tokio::test] + async fn test_pg_with_tls() { + common_telemetry::init_default_ut_logging(); + maybe_skip_postgres_integration_test!(); + let endpoints = std::env::var("GT_POSTGRES_ENDPOINTS").unwrap(); + let tls_connector = create_postgres_tls_connector(&TlsOption { + mode: TlsMode::Require, + cert_path: String::new(), + key_path: String::new(), + ca_cert_path: String::new(), + watch: false, + }) + .unwrap(); + let mut cfg = Config::new(); + cfg.url = Some(endpoints); + let pool = cfg + .create_pool(Some(Runtime::Tokio1), tls_connector) + .unwrap(); + let client = pool.get().await.unwrap(); + client.execute("SELECT 1", &[]).await.unwrap(); + } + + #[tokio::test] + async fn test_pg_with_mtls() { + common_telemetry::init_default_ut_logging(); + maybe_skip_postgres_integration_test!(); + let certs_dir = pgsql_certs_dir(); + let endpoints = std::env::var("GT_POSTGRES_ENDPOINTS").unwrap(); + let tls_connector = create_postgres_tls_connector(&TlsOption { + mode: TlsMode::Require, + cert_path: certs_dir.join("client.crt").display().to_string(), + key_path: certs_dir.join("client.key").display().to_string(), + ca_cert_path: String::new(), + watch: false, + }) + .unwrap(); + let mut cfg = Config::new(); + cfg.url = Some(endpoints); + let pool = cfg + .create_pool(Some(Runtime::Tokio1), tls_connector) + .unwrap(); + let client = pool.get().await.unwrap(); + client.execute("SELECT 1", &[]).await.unwrap(); + } + + #[tokio::test] + async fn test_pg_verify_ca() { + common_telemetry::init_default_ut_logging(); + maybe_skip_postgres_integration_test!(); + let certs_dir = pgsql_certs_dir(); + let endpoints = std::env::var("GT_POSTGRES_ENDPOINTS").unwrap(); + let tls_connector = create_postgres_tls_connector(&TlsOption { + mode: TlsMode::VerifyCa, + cert_path: certs_dir.join("client.crt").display().to_string(), + key_path: certs_dir.join("client.key").display().to_string(), + ca_cert_path: certs_dir.join("root.crt").display().to_string(), + watch: false, + }) + .unwrap(); + let mut cfg = Config::new(); + cfg.url = Some(endpoints); + let pool = cfg + .create_pool(Some(Runtime::Tokio1), tls_connector) + .unwrap(); + let client = pool.get().await.unwrap(); + client.execute("SELECT 1", &[]).await.unwrap(); + } + + #[tokio::test] + async fn test_pg_verify_full() { + common_telemetry::init_default_ut_logging(); + maybe_skip_postgres_integration_test!(); + let certs_dir = pgsql_certs_dir(); + let endpoints = std::env::var("GT_POSTGRES_ENDPOINTS").unwrap(); + let tls_connector = create_postgres_tls_connector(&TlsOption { + mode: TlsMode::VerifyFull, + cert_path: certs_dir.join("client.crt").display().to_string(), + key_path: certs_dir.join("client.key").display().to_string(), + ca_cert_path: certs_dir.join("root.crt").display().to_string(), + watch: false, + }) + .unwrap(); + let mut cfg = Config::new(); + cfg.url = Some(endpoints); + let pool = cfg + .create_pool(Some(Runtime::Tokio1), tls_connector) + .unwrap(); + let client = pool.get().await.unwrap(); + client.execute("SELECT 1", &[]).await.unwrap(); + } + #[tokio::test] async fn test_pg_put() { maybe_skip_postgres_integration_test!(); diff --git a/src/common/meta/src/test_util.rs b/src/common/meta/src/test_util.rs index 09af2ad8d0..929fc9a5da 100644 --- a/src/common/meta/src/test_util.rs +++ b/src/common/meta/src/test_util.rs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::path::PathBuf; use std::sync::Arc; use api::region::RegionResponse; @@ -299,3 +300,23 @@ macro_rules! maybe_skip_postgres15_integration_test { } }; } + +/// Returns the directory of the etcd TLS certs. +pub fn etcd_certs_dir() -> PathBuf { + let project_path = env!("CARGO_MANIFEST_DIR"); + let project_path = PathBuf::from(project_path); + let base = project_path.ancestors().nth(3).unwrap(); + base.join("tests-integration") + .join("fixtures") + .join("etcd-tls-certs") +} + +/// Returns the directory of the pgsql TLS certs. +pub fn pgsql_certs_dir() -> PathBuf { + let project_path = env!("CARGO_MANIFEST_DIR"); + let project_path = PathBuf::from(project_path); + let base = project_path.ancestors().nth(3).unwrap(); + base.join("tests-integration") + .join("fixtures") + .join("pgsql-certs") +} diff --git a/tests-integration/fixtures/docker-compose.yml b/tests-integration/fixtures/docker-compose.yml index b608c8ef61..1f6c102f50 100644 --- a/tests-integration/fixtures/docker-compose.yml +++ b/tests-integration/fixtures/docker-compose.yml @@ -89,10 +89,26 @@ services: - 5432:5432 volumes: - ~/apps/postgres:/var/lib/postgresql/data + - ./pgsql-certs:/tmp/certs:ro + - ./postgres/tls/pg_hba.conf:/var/lib/postgresql/pg_hba.conf environment: - POSTGRES_USER=greptimedb - POSTGRES_DB=postgres - POSTGRES_PASSWORD=admin + # Hack: Ensures certs are owned by database user with 600 permissions. + command: > + bash -c " + mkdir -p /certs && + cp /tmp/certs/* /certs && + chown -R postgres:postgres /certs && + chmod 600 /certs/*.key && + chmod 644 /certs/*.crt && + exec docker-entrypoint.sh postgres + -c hba_file=/var/lib/postgresql/pg_hba.conf + -c ssl=on + -c ssl_cert_file=/certs/server.crt + -c ssl_key_file=/certs/server.key + -c ssl_ca_file=/certs/root.crt" postgres15: image: docker.io/postgres:15-alpine @@ -106,7 +122,6 @@ services: - POSTGRES_DB=postgres - POSTGRES_PASSWORD=admin - mysql: image: greptime/mysql:5.7 ports: diff --git a/tests-integration/fixtures/pgsql-certs/client.crt b/tests-integration/fixtures/pgsql-certs/client.crt new file mode 100644 index 0000000000..d1e95c1a61 --- /dev/null +++ b/tests-integration/fixtures/pgsql-certs/client.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDFDCCAfygAwIBAgIUFL/NRvcKVxZktJOLq0ly8YWXJ+4wDQYJKoZIhvcNAQEL +BQAwGTEXMBUGA1UEAwwOUG9zdGdyZXNSb290Q0EwHhcNMjUwOTE1MTM0OTI2WhcN +MjYwOTE1MTM0OTI2WjAVMRMwEQYDVQQDDApncmVwdGltZWRiMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwBBgZ5DdB2WdnrMtfsRo+YvF8odppvPaLdNd +bajQs+sf3yRU8W7PskiQFqMSgLwjtp5Vb2C517RMgWAvVfi3+gCXUhRJQHWxfNA0 +neyt2hORimoC7S2uZ0x6o356gFatCRPsTSk0Y9oy4SpVl6a8Ht8q1e78++ojxVRj +PEN326a6PwEGCYw2nNfIN5T6C6Smlmr0FUWvzMhGFNgOaj4DujMZuvTw5fTbFmYN +1FSDTrSg68rzk2djkhht7JHZLkZ6YkRmsTkXaDgHiPnx22FQ6VqpLRmlKH10K1xC +6o7u8UbtkTo3xLbCz0J/2uxF9EclcmLNJIInrPrYU3DsD6lFEQIDAQABo1gwVjAU +BgNVHREEDTALgglsb2NhbGhvc3QwHQYDVR0OBBYEFJBMgeBaZKIfmnCiuI7dVbJq +FPtUMB8GA1UdIwQYMBaAFOTdao2MR8uh2v0lmUnBik8ZPBTBMA0GCSqGSIb3DQEB +CwUAA4IBAQDAJ9Pb7rN4Lf5xpHGlDVBIt6sYGI/JIRJCQhToL1dOPAimQBtkjzuJ +f+AeALJKQ8fGy4yvjgpq+3QzEZzbDCJBCCd4P3Wp2OFt6zbsSs5ZoRw1LQFvBKLM +FEpB50c6z5OLtllh53+RtPjLE6Hrkl9CsbNTN6pH4gbdioLWAMly23JzXjXfC/af +ega0R7W9nPS7D7R5tUvee75a+DBj5hO9S+d4eAIRDYYe4HUyIV8XW7Xf+g0YlBfq +VGQx7/ScM6E3uML8646ztpyOfhTUFRrhpytA1NAkcoWL6Sh+fLp+qF6uafUCP8Qe +eO8KrbBN0f0jHVFj3ykK0+r2ERA9WS8o +-----END CERTIFICATE----- diff --git a/tests-integration/fixtures/pgsql-certs/client.key b/tests-integration/fixtures/pgsql-certs/client.key new file mode 100644 index 0000000000..14255ccb59 --- /dev/null +++ b/tests-integration/fixtures/pgsql-certs/client.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDAEGBnkN0HZZ2e +sy1+xGj5i8Xyh2mm89ot011tqNCz6x/fJFTxbs+ySJAWoxKAvCO2nlVvYLnXtEyB +YC9V+Lf6AJdSFElAdbF80DSd7K3aE5GKagLtLa5nTHqjfnqAVq0JE+xNKTRj2jLh +KlWXprwe3yrV7vz76iPFVGM8Q3fbpro/AQYJjDac18g3lPoLpKaWavQVRa/MyEYU +2A5qPgO6Mxm69PDl9NsWZg3UVINOtKDryvOTZ2OSGG3skdkuRnpiRGaxORdoOAeI ++fHbYVDpWqktGaUofXQrXELqju7xRu2ROjfEtsLPQn/a7EX0RyVyYs0kgies+thT +cOwPqUURAgMBAAECggEAA+TRGjMU/WoRUKmv9G/684Q369DUUtmCxNxnen+qVjDK +y/VVRjJ0Qi23w3MO6aPm0smm+xkU63Xw+cvUvy4fB2cs/4cAbS7K/bgi454WxY28 +Ak21PXsS8W6FgKcMc2mjxxlWTcIrbmglZpc7IQCfs73b2nZ76TI4A297Njo6my4J +1AztlAPrC9hbbyzjjxMmVb6lgBEsYcb4OnDpkaBER28G3d44HKGvahJwl9YWWOCG +N431rT+ScF2iksEJkMR5GrngzFNRzjlpKSbc81krpQRncqgE6mIlTNoiqFCwZ6r+ +Pp6pMCvOSqf5CuE9K4IUk0xUQCII6lKqUfGElmwsoQKBgQDghu1/Dk2MlBy22+qM +MS4sG4RpkN6AY64o6oB2lzum646GT/1/0yzsJ1jDSir3y9l5/ZtjkOxkPXxLwVMZ +4MA6VTg0AzglD3V65eIPFyA/pAcyOitgGVR17aNWjbQZ/XFCaHZqWiJZEUAC+y2q +Z4JBNHVqs898Ri+Bi/Y4tZtDZQKBgQDa/IXKXThsKsGhDgUZ+5g+9ssyxvBIZ0zZ +tucyoXWZnx8v9DLKDa6esxgUy2l6PdbUtR7BW8TqiJ4i3VnqwaKpiK8JBdcs4RFH +bD2hWFVMtPB4B3T3p66kQznaSv9t/t5rhdhDTRoKNxYy2ej8g4lnQHNQ4c6ZF8AK +PAOnatz+PQKBgCKMIFcAeGY9E/3+8KQJnTUkNseXhuTycYXSL1oQAxm3/QIlpLfa +YnsjwsCp1Nqz/w6KOzKixfzWiR2O7Z55upo/Kpq2NBlfu4/hd1sjD887CfBsiugK +fbh3jD5xJ1koahjxweazX72creDHjUs/CgfGbpqweCiDFCQ2yPgI2Y8RAoGADQPL +E87chpk37tF9fiDU2JEkXH00VKlHCP102i58ZcfuO5Rg3F9ZzHbKbJn2R9ybAwNM +s6M3ndTGyT2slWYyu66y8G9XbYRm2X7WXtt4Hln2nLucuQdPOtX//zhL3Aa0w2Eu +DDnt3UOO3zDSRweuR+OtttXkyHZ/5FvSv8V7IuUCgYEArC8bKrBc3rbAM127+3Qv +ERBjtsHwp4T5blo1xtjTDpKVvbefvihqfDn2OLN/s6FgAlNzIOr+Dw4ouBiEXC0i +aZ9oqFYy2RG+bkSFBOj2IOaVVX1HLzfxvAGUvXii0d3H5uZNYS11andeb7qjCLKa +UYVJFcRasXMzRnfIyHggT+E= +-----END PRIVATE KEY----- diff --git a/tests-integration/fixtures/pgsql-certs/root.crt b/tests-integration/fixtures/pgsql-certs/root.crt new file mode 100644 index 0000000000..6a232030ec --- /dev/null +++ b/tests-integration/fixtures/pgsql-certs/root.crt @@ -0,0 +1,77 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 3f:54:27:60:47:aa:7a:b6:4e:5c:82:6f:d8:55:73:b1:50:9b:9b:cc + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN = PostgresRootCA + Validity + Not Before: Sep 15 13:49:26 2025 GMT + Not After : Sep 15 13:49:26 2026 GMT + Subject: CN = PostgresRootCA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:d0:90:b1:24:87:1d:0e:2b:ae:f3:2e:9e:4e:8e: + e1:0f:5b:f8:18:79:a8:d6:89:ea:ae:be:57:69:8a: + 1a:f3:e2:4b:a4:e0:d3:b7:66:84:bb:3c:f3:bf:27: + 3f:e7:a0:ac:3e:2e:2e:90:e7:d0:93:91:43:3d:34: + 5c:6a:ac:4f:0e:a4:c8:a3:58:7b:09:9c:cc:e0:e4: + 98:47:cf:17:b0:0a:cb:1d:17:8b:80:3e:2e:61:90: + e3:98:70:79:2d:84:56:be:59:3e:31:d9:56:31:17: + ec:7a:81:18:1f:9e:74:9a:e0:db:ae:dc:cc:9d:5c: + da:93:d7:b8:99:5d:cc:38:3c:5b:2a:ba:e4:2c:7b: + f7:e9:51:c9:a1:09:40:a2:da:4b:bc:52:bc:27:82: + 7b:4b:5a:76:41:03:5e:47:39:a6:b8:f7:46:ca:6e: + b1:80:31:89:d6:1d:64:a6:86:b1:4a:be:f8:20:54: + cb:f6:ac:01:73:ed:21:54:43:4a:a9:f8:cf:58:2f: + 38:2f:32:77:a3:61:04:01:e5:9d:93:ba:72:c6:5d: + c8:1d:8b:87:a2:96:04:ae:a2:83:46:14:2e:ac:f5: + c3:9d:8b:14:81:91:e4:fb:1f:33:64:28:f0:0c:e7: + 7d:87:4b:ef:45:0f:16:60:7e:a1:61:fa:09:8e:85: + 73:29 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + E4:DD:6A:8D:8C:47:CB:A1:DA:FD:25:99:49:C1:8A:4F:19:3C:14:C1 + X509v3 Authority Key Identifier: + E4:DD:6A:8D:8C:47:CB:A1:DA:FD:25:99:49:C1:8A:4F:19:3C:14:C1 + X509v3 Basic Constraints: critical + CA:TRUE + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 20:61:5c:0e:76:66:c1:f0:31:cd:78:4f:e2:68:85:cc:3c:bd: + 9b:19:44:ed:42:e3:6a:2d:02:94:15:f4:2a:35:73:7a:c6:0c: + af:f4:a4:02:66:bc:3e:9a:4e:24:06:cd:cb:5b:74:07:20:d7: + 84:8c:86:18:f9:1f:13:f5:ab:da:ed:8d:49:33:c0:46:83:be: + c7:6b:7d:84:ab:6b:74:99:02:15:2d:45:3e:a1:ec:1a:1c:9a: + 97:e6:a7:e9:39:66:ee:50:af:01:44:8e:6d:5c:d3:8b:22:f5: + 95:5a:41:67:0a:b3:ca:3d:35:a3:51:42:d3:9c:00:8f:d3:09: + 91:86:76:50:50:06:61:3c:ee:cf:9f:8a:b7:6c:38:97:2b:a5: + bb:45:ab:7a:e9:35:6a:5a:77:81:6d:e4:64:f6:df:19:9e:43: + f8:28:20:39:66:50:f5:4b:1c:31:fb:80:5f:e0:d8:8a:c8:63: + b5:1c:a2:c1:04:60:8d:5e:4c:99:dd:7a:bd:ed:e1:af:88:43: + 5c:d6:3e:e0:73:02:eb:2d:0e:7d:a1:16:10:1b:ba:af:d2:53: + fb:6f:c3:07:b1:81:94:1d:4b:0d:76:98:42:f0:db:6d:4d:d0: + e2:6b:d9:b9:32:cc:ce:7d:72:c4:b8:ea:21:55:d6:83:23:f0: + 6e:df:f6:9c +-----BEGIN CERTIFICATE----- +MIIDEzCCAfugAwIBAgIUP1QnYEeqerZOXIJv2FVzsVCbm8wwDQYJKoZIhvcNAQEL +BQAwGTEXMBUGA1UEAwwOUG9zdGdyZXNSb290Q0EwHhcNMjUwOTE1MTM0OTI2WhcN +MjYwOTE1MTM0OTI2WjAZMRcwFQYDVQQDDA5Qb3N0Z3Jlc1Jvb3RDQTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBANCQsSSHHQ4rrvMunk6O4Q9b+Bh5qNaJ +6q6+V2mKGvPiS6Tg07dmhLs8878nP+egrD4uLpDn0JORQz00XGqsTw6kyKNYewmc +zODkmEfPF7AKyx0Xi4A+LmGQ45hweS2EVr5ZPjHZVjEX7HqBGB+edJrg267czJ1c +2pPXuJldzDg8Wyq65Cx79+lRyaEJQKLaS7xSvCeCe0tadkEDXkc5prj3RspusYAx +idYdZKaGsUq++CBUy/asAXPtIVRDSqn4z1gvOC8yd6NhBAHlnZO6csZdyB2Lh6KW +BK6ig0YULqz1w52LFIGR5PsfM2Qo8AznfYdL70UPFmB+oWH6CY6FcykCAwEAAaNT +MFEwHQYDVR0OBBYEFOTdao2MR8uh2v0lmUnBik8ZPBTBMB8GA1UdIwQYMBaAFOTd +ao2MR8uh2v0lmUnBik8ZPBTBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBACBhXA52ZsHwMc14T+Johcw8vZsZRO1C42otApQV9Co1c3rGDK/0pAJm +vD6aTiQGzctbdAcg14SMhhj5HxP1q9rtjUkzwEaDvsdrfYSra3SZAhUtRT6h7Boc +mpfmp+k5Zu5QrwFEjm1c04si9ZVaQWcKs8o9NaNRQtOcAI/TCZGGdlBQBmE87s+f +irdsOJcrpbtFq3rpNWpad4Ft5GT23xmeQ/goIDlmUPVLHDH7gF/g2IrIY7UcosEE +YI1eTJnder3t4a+IQ1zWPuBzAustDn2hFhAbuq/SU/tvwwexgZQdSw12mELw221N +0OJr2bkyzM59csS46iFV1oMj8G7f9pw= +-----END CERTIFICATE----- diff --git a/tests-integration/fixtures/pgsql-certs/root.key b/tests-integration/fixtures/pgsql-certs/root.key new file mode 100644 index 0000000000..1d1bb77f81 --- /dev/null +++ b/tests-integration/fixtures/pgsql-certs/root.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDQkLEkhx0OK67z +Lp5OjuEPW/gYeajWiequvldpihrz4kuk4NO3ZoS7PPO/Jz/noKw+Li6Q59CTkUM9 +NFxqrE8OpMijWHsJnMzg5JhHzxewCssdF4uAPi5hkOOYcHkthFa+WT4x2VYxF+x6 +gRgfnnSa4Nuu3MydXNqT17iZXcw4PFsquuQse/fpUcmhCUCi2ku8UrwngntLWnZB +A15HOaa490bKbrGAMYnWHWSmhrFKvvggVMv2rAFz7SFUQ0qp+M9YLzgvMnejYQQB +5Z2TunLGXcgdi4eilgSuooNGFC6s9cOdixSBkeT7HzNkKPAM532HS+9FDxZgfqFh ++gmOhXMpAgMBAAECggEAJj7OOQpMxe81QPNExNeXBjPBei1/DD5UqnANg/U3DY9q ++yReNoSmZNZfxScLpSw1wZ5C3EAiI5lQ6O2L3+TSh3cosql0QHZALKJGmW5so9PK +3L4XTvA4HZyN28OOOQ5KQNQJH2eBEnYWX32CQLQUIl2G81kabWXcUB2QBJGqdAoq +cMTsDfWSQvZG+Qtdu5Btyd8rf2WWZPQXYh3GMxsphFYv5TnY+5Nu8oJ/SPlDcHVK +Fk3CI9jpUa98Mo2OWeMbP9ZU9HB+SpTMN1XpBfda9JKq8N67TBAfEkyUTxv2ILr0 +4KUdUCWMyMsl69JpRVlRWCBxKnGOv3HXIkprWT4mzQKBgQD1XdVNm5ui/TCmQirg +3GJQvjsfKqxFKguvlCpC7yW2Z9nNP9B/7k+5lNuKkbdgGVO+G2P+UTBLo2mZ8FjH +hKSoxoDaRpfvmeDG1nrAdcfSSJYNdFOZIyT4bb6LQViTmq79H7J2kHRbM76+exKf +DO3A/nQ0R6NmZhmE3pI0i3/0xQKBgQDZmpL+e+xbc1+4D6UwVQ9E5e0btJha+zyA +qY2331Y2H3o/+wBOLglx7oA2RrVUrovVXGHxnhyZbt7SASOxmdnAtzEgjxQYkt/f +WoCfCRMWVaUaTNFx6yEe3MCzi4p+onuR03P6NeFuZg42Ce7OC/YUPvj3N8slwCHx +7vktQajTFQKBgQDhLeEg3SrjVPt9yYGyZW7w7PQzMSVyQBkDZLW4QeNZWEuBWwxN +K/cMuLkWnY4t6nB5KogFEJuC/xBeDz5atLeskKgWKe0sHgs0UAfNcwoUSTs0U8qY +4rD+MTFKeYkBxVbMxHcy6nVucbme9DHtt57GnH8mr4wc4JyQ3PZOtKuUhQKBgBXk +D/+b9eYpUCrTIBohpHyY6OaNn3ofpjGHXSNvS1v8hK7lEF3NEdQtWyaarGlNefHH +7m6BKn1hAvd7d9zJDnfttfqBilMCi5ULpL7bCdmIWiiwK63bKqTRLm2hjxg4Plgo +PpWgUAJsL+fNzgFagLH+t8sfCMfOcVvGX7jmzxYVAoGBAOG/WA9ag+owBeHFBdIH +astwrDOTFnpHUaZb3lL3YFctkVp+P2MQXVhS/N7Qk+0lu8GbL9rQt8KMRR9Z6z2G +mUNlVTFrLYjrWZUUYxGmGVCs1ML5GWaP4Dv6gu8yxLDN4IhRiLl034j2bJVABTDv +9vPkr7f1j3nDNpLXely/Cv4C +-----END PRIVATE KEY----- diff --git a/tests-integration/fixtures/pgsql-certs/root.srl b/tests-integration/fixtures/pgsql-certs/root.srl new file mode 100644 index 0000000000..d3d8bffebf --- /dev/null +++ b/tests-integration/fixtures/pgsql-certs/root.srl @@ -0,0 +1 @@ +14BFCD46F70A571664B4938BAB4972F1859727EE diff --git a/tests-integration/fixtures/pgsql-certs/server.crt b/tests-integration/fixtures/pgsql-certs/server.crt new file mode 100644 index 0000000000..032a0187bc --- /dev/null +++ b/tests-integration/fixtures/pgsql-certs/server.crt @@ -0,0 +1,77 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 14:bf:cd:46:f7:0a:57:16:64:b4:93:8b:ab:49:72:f1:85:97:27:ed + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN = PostgresRootCA + Validity + Not Before: Sep 15 13:49:26 2025 GMT + Not After : Sep 15 13:49:26 2026 GMT + Subject: CN = postgres + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:8f:d2:77:76:52:9e:e0:87:4d:a3:83:88:58:fc: + 51:61:be:33:8b:c2:37:cd:52:ca:5c:29:78:10:99: + e8:29:a5:2f:af:70:2c:24:46:f8:2c:a7:3e:d3:62: + 15:7e:09:e6:bb:9f:05:e8:ec:cc:e7:38:fc:92:36: + 6d:ba:fd:0e:50:eb:5b:ac:50:93:b2:bd:87:43:95: + f1:b3:5e:88:3f:88:0d:26:0c:05:8f:f3:e2:9e:e9: + d4:f7:8b:ba:0c:af:45:06:29:ff:5b:aa:24:49:0e: + 0e:ee:8a:88:16:3f:89:73:71:0c:e2:26:3b:30:3d: + f5:3f:73:fe:da:2d:cf:b0:46:eb:20:8a:6b:45:01: + 0c:a6:c8:4f:ab:38:62:b2:dd:51:0a:fd:c3:e3:4b: + d2:ed:97:a1:de:03:d6:08:c6:50:5e:9d:03:6a:63: + 03:27:c2:c1:80:e7:c0:88:0f:49:42:72:28:3c:72: + 50:df:ee:47:b6:c5:75:85:61:8f:7c:e7:27:ee:c7: + d7:23:56:c4:bf:76:9e:62:79:b1:6f:3e:0d:b6:bc: + 10:19:ff:c1:16:88:07:14:0e:99:87:21:e0:78:32: + 97:69:b9:ba:30:16:95:ef:12:8d:2e:64:4c:c2:c9: + 78:25:48:70:05:24:45:f1:aa:18:a5:02:33:d2:27: + d5:1b + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: + DNS:localhost, IP Address:127.0.0.1 + X509v3 Subject Key Identifier: + 06:3E:AA:04:F6:4F:3D:21:0E:99:9A:A7:F2:44:9F:B8:4C:23:3E:BA + X509v3 Authority Key Identifier: + E4:DD:6A:8D:8C:47:CB:A1:DA:FD:25:99:49:C1:8A:4F:19:3C:14:C1 + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 4a:55:2d:de:ca:70:fb:54:69:e4:bb:4b:f2:74:a3:27:8d:d1: + 89:3b:29:5d:05:b5:ea:04:ea:32:c8:8e:ca:d2:a4:1e:a3:83: + de:03:fe:cd:86:4d:21:d8:a3:b8:5b:e5:01:61:bd:d0:69:6f: + bd:9a:53:c9:c7:67:34:bd:b8:5c:5d:31:38:3d:d3:33:0d:ec: + 44:a0:37:b3:13:96:50:82:f9:46:5e:3c:fa:c1:77:09:4b:21: + 91:93:f7:59:d1:32:c7:cb:cd:2e:11:51:64:41:97:b0:ac:07: + d8:1d:ee:3d:54:e0:03:f6:74:e4:2b:03:63:e3:f6:3e:cc:61: + c5:0e:81:12:9e:84:1a:5e:64:1c:c5:3c:c4:6b:f3:50:a8:b6: + 3b:53:81:73:fe:1e:fb:35:40:21:57:43:37:e2:de:52:6f:eb: + 72:f6:39:1e:e5:58:1d:09:29:82:ef:c2:24:3f:19:0f:48:c2: + 01:f6:34:2c:37:85:ea:6c:a2:c9:e4:a7:38:a5:e5:6e:0f:20: + 89:ad:1c:4e:c4:21:a3:b1:74:89:dc:c5:67:99:db:83:4c:60: + 74:66:5d:ee:f0:fc:58:30:03:e5:68:59:05:05:1e:cd:db:41: + 16:45:01:b6:3e:04:5b:95:2a:4d:b6:bc:ea:2d:55:99:01:1d: + bd:4a:e6:89 +-----BEGIN CERTIFICATE----- +MIIDGDCCAgCgAwIBAgIUFL/NRvcKVxZktJOLq0ly8YWXJ+0wDQYJKoZIhvcNAQEL +BQAwGTEXMBUGA1UEAwwOUG9zdGdyZXNSb290Q0EwHhcNMjUwOTE1MTM0OTI2WhcN +MjYwOTE1MTM0OTI2WjATMREwDwYDVQQDDAhwb3N0Z3JlczCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAI/Sd3ZSnuCHTaODiFj8UWG+M4vCN81SylwpeBCZ +6CmlL69wLCRG+CynPtNiFX4J5rufBejszOc4/JI2bbr9DlDrW6xQk7K9h0OV8bNe +iD+IDSYMBY/z4p7p1PeLugyvRQYp/1uqJEkODu6KiBY/iXNxDOImOzA99T9z/tot +z7BG6yCKa0UBDKbIT6s4YrLdUQr9w+NL0u2Xod4D1gjGUF6dA2pjAyfCwYDnwIgP +SUJyKDxyUN/uR7bFdYVhj3znJ+7H1yNWxL92nmJ5sW8+Dba8EBn/wRaIBxQOmYch +4Hgyl2m5ujAWle8SjS5kTMLJeCVIcAUkRfGqGKUCM9In1RsCAwEAAaNeMFwwGgYD +VR0RBBMwEYIJbG9jYWxob3N0hwR/AAABMB0GA1UdDgQWBBQGPqoE9k89IQ6Zmqfy +RJ+4TCM+ujAfBgNVHSMEGDAWgBTk3WqNjEfLodr9JZlJwYpPGTwUwTANBgkqhkiG +9w0BAQsFAAOCAQEASlUt3spw+1Rp5LtL8nSjJ43RiTspXQW16gTqMsiOytKkHqOD +3gP+zYZNIdijuFvlAWG90GlvvZpTycdnNL24XF0xOD3TMw3sRKA3sxOWUIL5Rl48 ++sF3CUshkZP3WdEyx8vNLhFRZEGXsKwH2B3uPVTgA/Z05CsDY+P2PsxhxQ6BEp6E +Gl5kHMU8xGvzUKi2O1OBc/4e+zVAIVdDN+LeUm/rcvY5HuVYHQkpgu/CJD8ZD0jC +AfY0LDeF6myiyeSnOKXlbg8gia0cTsQho7F0idzFZ5nbg0xgdGZd7vD8WDAD5WhZ +BQUezdtBFkUBtj4EW5UqTba86i1VmQEdvUrmiQ== +-----END CERTIFICATE----- diff --git a/tests-integration/fixtures/pgsql-certs/server.key b/tests-integration/fixtures/pgsql-certs/server.key new file mode 100644 index 0000000000..a2395717a0 --- /dev/null +++ b/tests-integration/fixtures/pgsql-certs/server.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCP0nd2Up7gh02j +g4hY/FFhvjOLwjfNUspcKXgQmegppS+vcCwkRvgspz7TYhV+Cea7nwXo7MznOPyS +Nm26/Q5Q61usUJOyvYdDlfGzXog/iA0mDAWP8+Ke6dT3i7oMr0UGKf9bqiRJDg7u +iogWP4lzcQziJjswPfU/c/7aLc+wRusgimtFAQymyE+rOGKy3VEK/cPjS9Ltl6He +A9YIxlBenQNqYwMnwsGA58CID0lCcig8clDf7ke2xXWFYY985yfux9cjVsS/dp5i +ebFvPg22vBAZ/8EWiAcUDpmHIeB4MpdpubowFpXvEo0uZEzCyXglSHAFJEXxqhil +AjPSJ9UbAgMBAAECggEAMzjlPSnt1c+6kgrti6vJnEMufo8caq8azTojvd3itrpT +Qmtz/TOdfeHO2WAsgWgrWhUn+K4lyBAevEBQUnGAIMfCLZvBDr67pxGHNLftVJsy ++6L6dCuLQcfMBqIoEA54Sdq5TL9LDw3HuaNzFmFopcnUqdKt79+RMhkw4inAt2nx +8mWzzA+u3FjR6OsjakUV3Xl+ae0GnybtLb3o2LofDbLWtw9LDPDfE8znMd5Zrmsc +fETfAFrrb1bfGRtE8T822EHt5TLc1mAqTGsVc9lMp22NEJwrfj6KLUhZex1MUqwh +q7Q4NQGNO2z89VVDXYuADKOLmk+FN4Yn710xL5HYgQKBgQDBxhbWY4xKXkzMDr2T +os8PjPfObbCmeutbjgZ0T8vf0BzHamHr5lnGjUL/1U0fZDOSO7eiT3WG+juvx4Yz +J+VNxyr6km+1ILJuiZ9N5Smf7mPa3dbbPGY39fatNxHa4nQUkLpzIjRNnQeKjult +I7IAxmKx+9Xkp50VaRrcBBXiQQKBgQC+Ael+mL6/rCaN9O9Ikh4dI4YY3rHtBOEG +uYKflchq9wwiqls+wlDXA4Zy3LRTvCA3k6DcVKHRl1fJiWebD/aLF+5lDFkdcq/H +g8V/HPxOGXt2z1LOBoHtK9z+3X6/iKTEEGs2gFX38AKazErFnmyR8beZGSoPTeV9 +kwqqEPZoWwKBgHY6GGECJ+yQEKdILx7O7Sr9xYxrnKZWxRb9Vq7MqQWLgqOhItG9 +n/Tm54QUbpPCnTyRtv8PIBQUxSoAwL6hjuSfqndrtUB8DKIo0cvDEFyGJOK7C4aE +GZH3PmR8/yXfmRebHkd1DRh1wM4nWADBELAsWrdhgiWaptsTX9HxpDCBAoGBALRm +/FrGi9VQjgqaU9aDZTQlVlymlCiGSWEpIWyDuhZVGaCQPrIHrNl4715/TndyVuRt +tn17nWhyWVdwrn37WgoWXrJyVuouydaUth9KVgORDjhwAB687v9QdjNF+eHAyy+c +py7ICtetecufzB51nH+1EKy7x8NgIlRoF+gA0vOhAoGBAItY2Tl+tNn4Bywfgevb +rSn+DVB/25ZaeQvoHlaE44Af010iYQUReyS6bLckS08XBbBHvFt5N5PDaeCmWKl3 +v2q7S1rvcMhdn5RsgJXNY63xLGSFHt/BKa2QBdFBO2sEmvsZh8K5dYJLvvfq8h3c +nR7IvxmGOWUF677QtjDbrase +-----END PRIVATE KEY----- diff --git a/tests-integration/fixtures/postgres/tls/pg_hba.conf b/tests-integration/fixtures/postgres/tls/pg_hba.conf new file mode 100644 index 0000000000..d822689217 --- /dev/null +++ b/tests-integration/fixtures/postgres/tls/pg_hba.conf @@ -0,0 +1,5 @@ +local all all trust +host all all 0.0.0.0/0 scram-sha-256 +hostssl all all 0.0.0.0/0 cert clientcert=verify-full +hostssl all all 0.0.0.0/0 scram-sha-256 +hostssl all all 0.0.0.0/0 scram-sha-256 clientcert=verify-ca diff --git a/tests-integration/fixtures/postgres/tls/postgresql.conf b/tests-integration/fixtures/postgres/tls/postgresql.conf new file mode 100644 index 0000000000..0d08dda4c1 --- /dev/null +++ b/tests-integration/fixtures/postgres/tls/postgresql.conf @@ -0,0 +1,6 @@ +listen_addresses = '*' + +ssl = on +ssl_cert_file = '/certs/server.crt' +ssl_key_file = '/certs/server.key' +ssl_ca_file = '/certs/root.crt'