PostgreSQL TLS
The Floating Server (FS) supports secure database connections over TLS. You can configure your PostgreSQL instance in two ways:
sslmode=require: Encrypts the connection (no hostname verification).sslmode=verify-full: Encrypts and verifies the server’s identity (recommended for production).
Depending on your use case, enable TLS on PostgreSQL (install cert/key) and then set the Floating Server connection accordingly:
Encrypt-only:
sslmode=requireFull verification:
sslmode=verify-full
sslrootcert=/path/to/ca.pemSetting up Verify-Full TLS for PostgreSQL (single or multiple machine)
Create a Certificate Authority (CA)
This CA will be used to sign PostgreSQL server certificates. Clients will trust this CA via sslrootcert.
mkdir -p ~/pg-tls && cd ~/pg-tls# Root CA (keep the key private)
openssl genrsa -out ca.key 4096
openssl req -x509 -new -key ca.key -sha256 -days 3650 \
-out ca.crt -subj "/CN=Org-Postgres-CA"Artifacts:
CA certificate (for clients):
~/pg-tls/ca.crtCA private key (do not share):
~/pg-tls/ca.key
Issue a Server Certificate for Each PostgreSQL Host
Generate a server certificate for each PostgreSQL machine. The certificate must include the DNS name clients use to connect. If clients connect via IP, include the IP as a SAN as well.
Set your host values:
HOST="db1.example.com" # the DNS name clients will use
IP1="1.0.1.1" # if clients will connect by IPGenerate key + CSR config with SANs:
openssl genrsa -out server.key 4096
cat > server.cnf <<EOF
[ req ]
distinguished_name = dn
req_extensions = v3_req
prompt = no
[ dn ]
CN = ${HOST}
[ v3_req ]
extendedKeyUsage = serverAuth
subjectAltName = @alt
[ alt ]
DNS.1 = ${HOST}
$( [ -n "$IP1" ] && echo "IP.1 = ${IP1}" )
EOFMake and sign the CSR:
openssl req -new -key server.key -out server.csr -config server.cnf
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-out server.crt -days 825 -sha256 -extfile server.cnf -extensions v3_reqArtifacts for this host:
Server leaf cert:
server.crtServer private key:
server.key
Repeat for each Postgres machine. Do not reuse the same private key across machines.
Install Certificates on the PostgreSQL Host
Copy the leaf certificate and key into the Postgres data directory:
# Copy leaf + key into the Postgres data dir
cp server.crt /PATH/TO/DATADIR/server.crt
cp server.key /PATH/TO/DATADIR/server.keyEnsure the key is restricted:
# key must be restricted
chown postgres:postgres /PATH/TO/DATADIR/server.{crt,key}
chmod 600 /PATH/TO/DATADIR/server.key
chmod 644 /PATH/TO/DATADIR/server.crtEnable TLS and listen on your network:
Find your Postgres data dir ($PGDATA):
sudo -u postgres psql -tAc "SHOW data_directory;"Open postgresql.conf:
sudo -u postgres ${EDITOR:-nano} "$PGDATA/postgresql.conf"Add / confirm these lines:
ssl = on
ssl_cert_file = 'server.crt' # or an absolute path
ssl_key_file = 'server.key' # key must be chmod 600, owned by postgres
listen_addresses = '*' # or a comma list like '10.0.1.15,127.0.0.1'Allow TLS connections from your client networks (order matters):
Open pg_hba.conf:
sudo -u postgres ${EDITOR:-nano} "$PGDATA/pg_hba.conf"Add these lines near the top (before broader rules) and adjust DB/user/CIDRs:
# Tighten the CIDRs to your environment
hostssl fsdb fsuser 10.0.0.0/16 scram-sha-256
hostssl fsdb fsuser 192.168.0.0/24 scram-sha-256Restart Postgres (e.g., pg_ctl -D /PATH/TO/DATADIR restart) and ensure port 5432 is open.
Client (Floating Server) connection using verify-full
Clients must connect using the same DNS name that’s in the server cert SAN.
Place the CA cert on the app host (or inside the container), for example:
/etc/ssl/certs/org-postgres-ca.crt
Config file example:
database:
type: "postgres"
host: db1.example.com
port: 5432
user: fsuser
password: fspassword
name: fsdb
sslmode: "verify-full" # options: disable, require, verify-full
sslrootcert: "/etc/ssl/certs/org-postgres-ca.crt"Run PostgreSQL with TLS in Docker
After you’ve created your certs (ca.crt, server.crt, server.key), mount them into the container and let an init script place them in Postgres’s data dir with the right ownership/permissions.
Init script (runs on first boot)
Create init/00-ssl.sh:
Make it executable:
Place your certificate files in ./certs/:
Start the PostgreSQL container:
Bash Script
The following script implements the steps described above. Create a file named fs-pg.sh and copy the script into it. Make sure to adjust paths and parameters as needed. The ca.crt will be saved under ./pg-tls/. This script only generates the certificates required for TLS setup.
Notes
The init script runs only when the
pgdatavolume is new/empty. If you’ve already used it, either remove the volume and re-run, or copy the files into$PGDATA/certsand fix ownership/permissions manually.Adjust DB/user/CIDRs to your environment.
On the Floating Server side, use
sslmode=verify-fulland point to your CA:sslrootcert=/path/to/ca.crt.Paths and exact details may vary in your environment (OS, image, mount points). Adjust them as needed. The only requirements are that Postgres can read the certs at the paths you configure and that
server.keyis owned by postgres with0600permissions.
Was this helpful?