feat: serve plaintext PostgreSQL when TLS is not configured
All checks were successful
Build and Push Image / docker-build-and-push (push) Successful in 5m3s
Test and Release PawSQL / test (push) Successful in 43s
Test and Release PawSQL / release (push) Successful in 7s

This commit is contained in:
2026-09-15 22:03:58 -04:00
parent 4e305d67e3
commit e67698f3c2
6 changed files with 110 additions and 36 deletions

View File

@@ -6,7 +6,7 @@ PawSQL is a TLS-terminating PostgreSQL router. It accepts PostgreSQL clients on
- Go 1.24 or later to build and run PawSQL natively.
- Docker Engine and a usable `docker` CLI to build the PawSQL image. PawSQL also needs them in its own execution environment when it manages PostgreSQL containers.
- A TLS certificate and private key readable by PawSQL. The certificate must cover every hostname clients use for SNI routing.
- Optional: a TLS certificate and private key readable by PawSQL. Omit the `tls` block to serve plaintext PostgreSQL; with TLS, the certificate must cover every hostname clients use for SNI routing.
- Docker Engine access for each `postgres` route. Managed database images are limited to `postgres:16`, `postgres:17`, and `postgres:18`.
## Build, configure, and run
@@ -83,13 +83,15 @@ docker compose up --build
## Routing and TLS
PawSQL requires PostgreSQL's SSL negotiation and terminates client TLS before proxying PostgreSQL bytes to the selected upstream.
When the Barkfile configures `tls`, PawSQL handles PostgreSQL's SSL negotiation and terminates client TLS before proxying PostgreSQL bytes to the selected upstream:
- **With SNI:** PawSQL uses the TLS server name to select an exact configured `hostname` match. Hostname matching is case-insensitive and ignores a trailing dot. An unknown SNI name is rejected; PawSQL does not fall back to a database-name route when SNI is present.
- **Without SNI:** After TLS is established, PawSQL reads the PostgreSQL startup message and selects the route whose `database` name exactly matches the requested PostgreSQL database. This makes a route without `hostname` usable by non-SNI clients.
Use a certificate trusted by clients and containing the SNI hostname they present. Clients that do not send SNI must request the configured database route name.
Without a `tls` block, PawSQL serves plaintext PostgreSQL: clients connect without SSL negotiation, and routes are selected only by database name. Hostname routing is unavailable because it relies on TLS SNI.
## Managed PostgreSQL lifecycle
Managed PostgreSQL is lazy: PawSQL creates or starts its `pawsql-<database>` container only when a client selects that route, waits for PostgreSQL to accept connections, then proxies the session. PawSQL stops managed containers but does not remove their data volumes.