Introduction
Assume you are bringing up an Exalate on docker, and you have the need to secure the connection between the application and the database using SSL.
With the standard configuration you will encounter the following error:
Caused by: org.postgresql.util.PSQLException: FATAL: SSL connection is required. Please specify SSL options and retry.
Or alternatively, you want to be sure that PostgreSQL is accessed over SSL.
Note: For more information we suggest checking out the following links:
Configuration of the database server
https://www.postgresql.org/docs/9.1/ssl-tcp.html
Configuration of Docker:
https://github.com/readthedocs/readthedocs.org/pull/5556
Setting the permissions:
https://stackoverflow.com/questions/55072221/deploying-postgresql-docker-with-ssl-certificate-and-key-with-volumes
Setting up PostgreSQL using SSL
Configure the docker-compose to bring up PostgreSQL
Adapt the docker-compose.yml such that PostgreSQL comes up in an SSL mode:
version: '2'
services:
database:
restart: unless-stopped
volumes:
- ./persist/db:/var/lib/postgresql/data
- ./createdb.sh:/docker-entrypoint-initdb.d/init-user-db.sh
#
# provide the certificate and the key to the postgres server
#
- ./ca/server.crt:/var/lib/postgresql/server.crt
- ./ca/server.key:/var/lib/postgresql/server.key
image: postgres:alpine
#
# ensure postgres is coming up with ssl mode on
#
command: -c ssl=on -c ssl_cert_file=/var/lib/postgresql/server.crt -c ssl_key_file=/var/lib/postgresql/server.key
environment:
POSTGRES_DB: mydb
POSTGRES_USER: user
POSTGRES_PASSWORD: secret
environment:
- POSTGRES_PASSWORD=password
- DB_NAME=snownode
- DB_USER=idalko
- DB_PASS=idalko
networks:
- database
networks:
database:
driver: bridge
default:
driver: bridge
Create the certificates
You can create self-signed certificates as follows
# Store the certificates in a specific folder on your host
mkdir ca
cd ca
# use openssl to generate the certificates
openssl req -new -text -out server.req
openssl rsa -in privkey.pem -out server.key
rm privkey.pem
openssl req -x509 -in server.req -text -key server.key -out server.crt
# change ownership and permissions. It depend on the underlying operating system. Userid 70 is postgres on the postgres:alpine image
sudo chown 70:70 server.key
sudo chmod 600 server.key
cd ..
docker-compose up -d database
Validate
We like to validate if it works before moving on
# assuming that the database 'snownode' has been setup. if there is another database - use that
docker exec -it <name of the container running the database> /bin/bash
psql -U idalko -h localhost snownode
It must confirm that the SSL is enabled
bash-5.0# psql -U idalko -h localhost snownode
psql (12.3)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
An additional check is to do a PLSQL command
bash-5.0# psql -U idalko -h localhost snownode
psql (12.3)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.
snownode=# show ssl
snownode-# ;
ssl
-----
on
Configure the app to access the database using SSL
The only configuration to be added to the docker-compose is by specifying that the PGSSLMODE is required
The adapted docker-compose looks like
version: '2'
services:
database:
# <snip>
snownode:
restart: unless-stopped
ports:
- 9000:9000
image: idalko/snownode:5.0.19
depends_on:
- database #wait for postgres to be started, not for ready
volumes:
- ./persist/home:/opt/snownode/data
environment:
#ensure that the connection to the database is using SSL
- PGSSLMODE="require"
- SNOWNODE_PORT=9000
- SNOWNODE_PG_HOST=database
- SNOWNODE_PG_DB=snownode
- SNOWNODE_PG_USER=idalko
- SNOWNODE_PG_PWD=idalko
networks:
- database
- default
networks:
database:
driver: bridge
default:
driver: bridge