In today’s digital age, database security is paramount, especially with the rise of cyber-attacks targeting sensitive information. Securing your PostgreSQL database with hardening techniques based on CIS Benchmarks (Center for Internet Security) can significantly enhance security. This blog will walk you through how to harden your PostgreSQL database and containerize it using Docker for a robust and secure database deployment.
What is CIS Benchmarks for PostgreSQL?
The CIS PostgreSQL Benchmark provides best practices for securing your PostgreSQL database, focusing on various aspects such as:
- Access Control: Enforcing strict access control to limit who can access the database.
- Authentication: Implementing secure authentication mechanisms, including strong password policies and disabling insecure protocols.
- Configuration: Ensuring that configuration settings, such as logging and encryption, are optimized for security.
- Auditing and Logging: Enabling detailed auditing and logging to track and monitor activities in your database.
- Encryption: Securing data both in transit and at rest to prevent unauthorized access.
By following these guidelines, you can significantly reduce the risk of vulnerabilities that could lead to data breaches.
Why Dockerize a Hardened PostgreSQL Database?
Dockerization offers many benefits when it comes to running PostgreSQL, especially when combined with database hardening:
- Consistency: Docker allows you to package your PostgreSQL instance with hardened configurations, ensuring the same level of security across different environments.
- Isolation: Running PostgreSQL in a Docker container ensures that the database is isolated from the host system, reducing the attack surface.
- Portability: Docker containers can run on any system, making it easier to deploy your secure PostgreSQL instance anywhere.
- Automation: Automate the deployment of a pre-hardened PostgreSQL image in CI/CD pipelines, ensuring security from the start.
A hardened PostgreSQL Docker image reduces the risk of vulnerabilities and ensures you meet security compliance standards such as those provided by the CIS Benchmark.
Steps to Dockerize a Hardened PostgreSQL Database
Now, let’s dive into the practical aspects of how you can Dockerize a PostgreSQL database, incorporating hardened configurations and security features such as logging, encryption, and auditing.
Project Structure
dockerized-hardened-postgres/
├── Certificate/
│ ├── server.crt # SSL certificate file
│ └── server.key # SSL private key file
├── init-postgres.sh # Initialization script for PostgreSQL settings
├── Dockerfile # Dockerfile for building the hardened PostgreSQL image
└── README.md # Documentation for the project
Step 1: Generate SSL Certificate for PostgreSQL Connection
Before Dockerizing and securing your PostgreSQL database, it’s essential to enable SSL to ensure encrypted connections. You can follow the steps to generate a self-signed certificate in my detailed blog Understanding HTTPS, SSL/TLS & Certificate Generation.
Alternatively, if you prefer to use a pre-generated SSL certificate, you can download it directly from my GitHub repository: Postgres CIS Docker Certificates.
Step 2: Dockerizing a Hardened PostgreSQL Database
Now, let’s dive into how to Dockerize a PostgreSQL database with hardened configurations and security features, such as logging, encryption, and auditing.
Create a Hardened PostgreSQL Docker Image
We’ll start by creating a Dockerfile
that builds a secure PostgreSQL instance. The following Dockerfile accomplishes this by:
- Using the official PostgreSQL image.
- Installing necessary security extensions like
pgaudit
andset_user
. - Configuring SSL for secure connections.
- Hardening the configuration according to CIS guidelines
Dockerfile:
# Use the official PostgreSQL image from Docker Hub
FROM kubedb/postgres:13.2-alpine-pgaudit
# Update packages and install necessary build tools and dependencies for pgaudit and set_user
RUN apk update && apk upgrade && apk add --no-cache \
alpine-sdk \
postgresql-dev \
postgresql-contrib
# Copy the set_user source code into the image
COPY ./set_user /usr/src/set_user
# Build and install the set_user extension
RUN cd /usr/src/set_user && make && make install
# Set environment variables for PostgreSQL timezone and logging
ENV POSTGRES_INITDB_ARGS="--data-checksums"
ENV POSTGRES_INITDB_WALDIR="/var/lib/postgresql/wal"
# Copy SSL certificates into the container
COPY Certificate/server.crt /var/lib/postgresql/server.crt
COPY Certificate/server.key /var/lib/postgresql/server.key
# Set the correct permissions and ownership
RUN chown postgres:postgres /var/lib/postgresql/server.crt /var/lib/postgresql/server.key && \
chmod 0600 /var/lib/postgresql/server.key
# Set timezone and logging settings via SQL commands
COPY init-postgres.sh /docker-entrypoint-initdb.d/
# Ensure the script is executable
RUN chmod +x /docker-entrypoint-initdb.d/init-postgres.sh
# Ensure umask and permissions are set correctly
RUN echo 'umask 0077' >> /root/.bashrc
# Set PostgreSQL configuration to use the custom config file and preload libraries
CMD ["postgres", "-c", "shared_preload_libraries=pgaudit,set_user"]
Step 3: Script to Harden PostgreSQL Settings
Next, we need a script to configure PostgreSQL according to the CIS Benchmark, enabling SSL, logging, and other essential security features. Below is an example of how the init-postgres.sh
script should look:
init-postgres.sh:
#!/bin/bash
set -e
# Set timezone and log timezone
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
ALTER SYSTEM SET timezone = 'Asia/Kolkata';
ALTER SYSTEM SET log_timezone = 'Asia/Kolkata';
EOSQL
# Enable logging settings
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
ALTER SYSTEM SET logging_collector = 'on';
ALTER SYSTEM SET log_rotation_size = '500MB';
ALTER SYSTEM SET log_connections = 'on';
ALTER SYSTEM SET log_disconnections = 'on';
ALTER SYSTEM SET log_truncate_on_rotation = 'on';
ALTER SYSTEM SET log_statement = 'ddl';
EOSQL
# Enable SSL settings
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
ALTER SYSTEM SET ssl = 'on';
ALTER SYSTEM SET ssl_cert_file = '/var/lib/postgresql/server.crt';
ALTER SYSTEM SET ssl_key_file = '/var/lib/postgresql/server.key';
EOSQL
# Reload PostgreSQL configuration to apply changes
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
SELECT pg_reload_conf();
EOSQL
# Create extensions if they do not exist
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
CREATE EXTENSION IF NOT EXISTS pgaudit;
CREATE EXTENSION IF NOT EXISTS set_user;
CREATE EXTENSION IF NOT EXISTS pgcrypto;
EOSQL
Step 4: Build the Docker Image
docker build -t hardened-postgres .
Step 5: Run the Hardened PostgreSQL Container
docker run -d \
-e POSTGRES_USER=admin \
-e POSTGRES_PASSWORD=strongpassword \
-v /path/to/ssl/certificates:/var/lib/postgresql/ \
-p 5432:5432 \
hardened-postgres
Benefits of a Dockerized Hardened PostgreSQL Database
- Enhanced Security: Dockerizing a hardened PostgreSQL instance ensures that the database is isolated and follows best security practices.
- Portability: The ability to deploy a hardened PostgreSQL database in any environment helps organizations standardize security.
- Automation: You can automate the security configurations, ensuring that each instance is compliant with CIS standards.
- Consistency Across Environments: Whether you deploy locally, in the cloud, or on a different machine, the hardened image ensures security consistency.
- Compliance: Following CIS benchmarks helps meet compliance requirements for security audits and regulatory standards.
Conclusion
Securing PostgreSQL is crucial in today’s data-driven world. By following the CIS Benchmark and Dockerizing your database with a hardened image, you can ensure that your PostgreSQL instance is protected from vulnerabilities and meets compliance standards. Docker not only provides isolation but also facilitates the easy and consistent deployment of security-compliant databases across different environments.
For additional resources, refer to:
You can also check out our other guides on database security and Docker containerization on our website to enhance your understanding and implementation of best practices. Your commitment to securing your database is a vital step in protecting your organization’s valuable data assets.