From 6ad14432596d7795b823e46d28cef930ca2ebf43 Mon Sep 17 00:00:00 2001 From: Ashutosh Sharma Date: Wed, 11 Sep 2024 01:24:38 +0530 Subject: [PATCH] [#461] fix ssl connection to postgres in server_passthrough --- doc/tutorial/08_tls_enforced.md | 91 +++++++++++++++++++++++++++++++++ src/libpgagroal/security.c | 10 ++-- 2 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 doc/tutorial/08_tls_enforced.md diff --git a/doc/tutorial/08_tls_enforced.md b/doc/tutorial/08_tls_enforced.md new file mode 100644 index 00000000..b0c50884 --- /dev/null +++ b/doc/tutorial/08_tls_enforced.md @@ -0,0 +1,91 @@ +## Preface + +This tutorial will take you through the connection path from client to `pgagroal` to `postgres` server when TLS is enforced. + +## Setup + +To enforce tls along the whole path, we first need to create X509 certicates for client->pgagroal and pgagroal->postgres seperately. + +For the purpose of this tutorial we will create self-signed certificates and assume only server side authentication. + +### Creating Certificates + +We will create self-signed certificate for the server, valid for 365 days, use the following OpenSSL command, replacing `dbhost.yourdomain.com` with the server's host name, here `localhost`: + +``` +openssl req -new -x509 -days 365 -nodes -text -out pgagroal.crt \ + -keyout pgagroal.key -subj "/CN=dbhost.yourdomain.com" +``` + +for client to pgagroal side authentication and + +``` +openssl req -new -x509 -days 365 -nodes -text -out postgres.crt \ + -keyout postgres.key -subj "/CN=dbhost.yourdomain.com" +``` + +for pgagroal to postgres side authentication. + +then do - + +``` +chmod og-rwx pgagroal.key +chmod og-rwx postgres.key +``` + +because the server will reject the file if its permissions are more liberal than this. For more details on how to create your server private key and certificate, refer to the OpenSSL documentation. + +### Configuration + +Modify the configuration files of postgres and pgagroal. + +Add the following lines in `postgresql.conf` (Generally can be found in `/etc/postgresql//main` directory) + +``` +... +ssl = on +ssl_cert_file = +ssl_key_file = +... +``` + +and make the contents of `pg_hba.conf` - + +``` +hostssl all all all md5 +``` + +here we are choosing md5 for authenticating the requested user and database against postgres catalog + +Make the contents of `pgagroal.conf` to enable tls the whole way - + +``` +[pgagroal] +host = localhost +port = 2345 + +log_type = console +log_level = debug5 +log_path = + +max_connections = 100 +idle_timeout = 600 +validation = off +unix_socket_dir = /tmp/ + +tls = on +tls_cert_file = +tls_key_file = + +[primary] +host = localhost +port = 5432 +tls = on +tls_ca_file = +``` + +### Client Request + +`PGSSLMODE=verify-ca PGSSLROOTCERT= psql -h localhost -p 2345 -U `. + + diff --git a/src/libpgagroal/security.c b/src/libpgagroal/security.c index a7dad428..7c651477 100644 --- a/src/libpgagroal/security.c +++ b/src/libpgagroal/security.c @@ -70,7 +70,7 @@ static int client_password(SSL* c_ssl, int client_fd, char* username, char* pass static int client_md5(SSL* c_ssl, int client_fd, char* username, char* password, int slot); static int client_scram256(SSL* c_ssl, int client_fd, char* username, char* password, int slot); static int client_ok(SSL* c_ssl, int client_fd, int slot); -static int server_passthrough(struct message* msg, int auth_type, SSL* c_ssl, int client_fd, int slot); +static int server_passthrough(struct message* msg, int auth_type, SSL* c_ssl, SSL* s_ssl, int client_fd, int slot); static int server_authenticate(struct message* msg, int auth_type, char* username, char* password, int slot, SSL* server_ssl); static int server_trust(int slot, SSL* server_ssl); @@ -1544,7 +1544,7 @@ use_unpooled_connection(struct message* request_msg, SSL* c_ssl, int client_fd, if (password == NULL) { - if (server_passthrough(msg, auth_type, c_ssl, client_fd, slot)) + if (server_passthrough(msg, auth_type, c_ssl, *server_ssl, client_fd, slot)) { goto error; } @@ -2156,7 +2156,7 @@ client_ok(SSL* c_ssl, int client_fd, int slot) } static int -server_passthrough(struct message* msg, int auth_type, SSL* c_ssl, int client_fd, int slot) +server_passthrough(struct message* msg, int auth_type, SSL* c_ssl, SSL* s_ssl, int client_fd, int slot) { int status = MESSAGE_STATUS_ERROR; int server_fd; @@ -2215,14 +2215,14 @@ server_passthrough(struct message* msg, int auth_type, SSL* c_ssl, int client_fd memcpy(&config->connections[slot].security_messages[auth_index], msg->data, msg->length); auth_index++; - status = pgagroal_write_message(NULL, server_fd, msg); + status = pgagroal_write_message(s_ssl, server_fd, msg); if (status != MESSAGE_STATUS_OK) { goto error; } pgagroal_free_message(msg); - status = pgagroal_read_block_message(NULL, server_fd, &msg); + status = pgagroal_read_block_message(s_ssl, server_fd, &msg); if (status != MESSAGE_STATUS_OK) { goto error;