Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#461] fix ssl connection to postgres in server_passthrough #462

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions doc/tutorial/08_tls_enforced.md
Original file line number Diff line number Diff line change
@@ -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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tls -> TLS, client->pgagroal -> client to pgagroal, pgagroal->postgres -> pgagroal to PostgreSQL


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/<version_number>/main` directory)

```
...
ssl = on
ssl_cert_file = </path/to/postgres.crt>
ssl_key_file = </path/to/postgres.key>
...
```

and make the contents of `pg_hba.conf` -

```
hostssl all all all md5
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should use scram-sha-256

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do

```

here we are choosing md5 for authenticating the requested user and database against postgres catalog
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

md5 -> scram-sha-256

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scram-sha-256 is giving channal binding check failed errors because we are switching ssl sessions between actual client and postgres server.

Is there some way to bypass it?

Or we will have to present same certificates on both sides (c_ssl == s_ssl)?


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 = </path/to/pgagroal.crt>
tls_key_file = </path/to/pgagroal.key>

[primary]
host = localhost
port = 5432
tls = on
tls_ca_file = </path/to/postgres.crt>
```

### Client Request

`PGSSLMODE=verify-ca PGSSLROOTCERT=</path/to/pgagroal.crt> psql -h localhost -p 2345 -U <username> <database>`.


10 changes: 5 additions & 5 deletions src/libpgagroal/security.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,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);
Expand Down Expand Up @@ -1538,7 +1538,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;
}
Expand Down Expand Up @@ -2152,7 +2152,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;
Expand Down Expand Up @@ -2211,14 +2211,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;
Expand Down
Loading