Security Hardening Guide
This document outlines the security features and hardening measures implemented in this PostgreSQL HA cluster deployment. SECURITY IS CRITICAL - follow this guide carefully for production deployments.
Security Features Enabled by Default
1. PostgreSQL Authentication
SCRAM-SHA-256 authentication (industry standard, replaces deprecated MD5)
- All connections use
scram-sha-256hash algorithm - Passwords never transmitted in cleartext
- Protection against rainbow table attacks
2. Network Access Control
Restricted pg_hba.conf rules:
Default behavior: Only nodes within CLUSTER_NETWORK (e.g., 172.23.202.0/24) can connect to PostgreSQL.
3. SSL/TLS Encryption
PostgreSQL SSL enabled by default (POSTGRESQL_SSL_ENABLED=true)
- Encrypts all client-server communication
- Prevents password sniffing and man-in-the-middle attacks
- Self-signed certificates auto-generated if not provided
4. Patroni REST API Authentication
HTTP Basic Auth enabled by default:
Protected endpoints: /switchover, /failover, /restart, /reload, /reinitialize
5. etcd Authentication
etcd auth enabled (ETCD_AUTH_ENABLED=true)
- Root user password required
- Prevents unauthorized cluster state manipulation
- CRITICAL: etcd stores all cluster secrets and topology
6. PgBouncer Security
SCRAM-SHA-256 authentication:
7. Strong Password Requirements
Mandatory password complexity:
- Minimum 16 characters
- Mix of uppercase, lowercase, numbers, symbols
- Generated with
openssl rand -base64 32
Critical CVE Status
PostgreSQL 18.1 → 18.2+ Required
CVE-2025-8714 (CVSS 8.8 HIGH):
- Affects: pg_dump arbitrary code execution
- Impact: Malicious dumps can execute code during restore
- Action Required: Upgrade to PostgreSQL 18.2+ immediately
Other Recent CVEs Fixed:
- CVE-2025-4207: Optimizer statistics exposure (18.5+)
- CVE-2025-1094: GB18030 encoding vulnerability (18.3+)
- CVE-2024-10979: Quoting API validation bypass (18.1+)
- CVE-2024-10978: PL/Perl environment variable injection (18.1+)
Security Checklist
Pre-Deployment
- Generate strong passwords for all accounts:
- Configure
.envfile with generated passwords:
- Verify SSL is enabled:
- Verify authentication is enabled:
- Review network configuration:
Post-Deployment
- Test SSL connections:
- Verify Patroni API auth:
- Check firewall rules:
- Audit user permissions:
-
Change Grafana password on first login
-
Enable audit logging (optional but recommended):
Common Security Mistakes to Avoid
❌ DON'T:
-
Use weak/default passwords
admin123,password,postgres(avoid these)- Use
openssl rand -base64 32(recommended)
-
Open PostgreSQL to the internet
host all all 0.0.0.0/0 md5(avoid this)- Restrict to
CLUSTER_NETWORKonly (recommended)
-
Disable SSL in production
POSTGRESQL_SSL_ENABLED=false(avoid this)- Always enable SSL:
POSTGRESQL_SSL_ENABLED=true(recommended)
-
Leave Patroni API unprotected
PATRONI_RESTAPI_AUTH_ENABLED=false(avoid this)- Enable auth to prevent unauthorized failovers (recommended)
-
Use MD5 authentication
PGBOUNCER_AUTH_TYPE=md5(vulnerable to rainbow tables, avoid this)- Use
scram-sha-256(recommended)
-
Commit
.envfile to git- Contains all cluster secrets! (avoid committing)
- Ensure
.envis in.gitignore(recommended)
-
Run as root user
- PostgreSQL, etcd should have dedicated users (avoid running as root)
- Already configured with
postgres,etcdusers (recommended)
-
Skip etcd authentication
- Anyone can read/write cluster state (avoid this)
ETCD_AUTH_ENABLED=trueis mandatory (recommended)
Advanced Security Hardening
1. SSL Certificate Management
Production Setup - Use proper CA-signed certificates:
Update .env:
2. etcd TLS Configuration
Generate etcd certificates:
Update etcd.conf.j2:
3. Prometheus/Grafana HTTPS
Nginx reverse proxy with Let's Encrypt:
4. Network Segmentation
Firewall rules (UFW example):
5. Audit Logging
Enable pgAudit extension:
Monitor logs:
6. Intrusion Detection
Install fail2ban:
7. Secrets Management
Use Ansible Vault for .env encryption:
Or use HashiCorp Vault:
Security Monitoring
Metrics to Monitor
- Failed login attempts:
- Superuser connections:
- SSL connection ratio:
- Patroni failover events:
Alerting Rules
Check roles/prometheus/templates/alert_rules.yml.j2 for:
PostgreSQLDownPostgreSQLTooManyConnectionsPatroniNoLeaderEtcdNoLeaderHighReplicationLag
Incident Response
Suspected Breach
- Immediately change all passwords:
- Review connections:
- Terminate suspicious connections:
- Review audit logs:
- Enable connection logging temporarily:
Compliance
GDPR/HIPAA Requirements
- Encryption at rest: Enable with LUKS/dm-crypt
- Encryption in transit: SSL/TLS enabled
- Access control: SCRAM-SHA-256, network restrictions
- Audit logging: pgAudit extension
- Data retention: Configure in Patroni
- Right to be forgotten: Implement data deletion procedures
PCI-DSS Requirements
- Requirement 2.1: Change default passwords (enforced)
- Requirement 4: Encrypt transmission (SSL/TLS)
- Requirement 8: Unique user IDs (no shared accounts)
- Requirement 10: Track and monitor access (audit logging)
Regular Security Tasks
Daily
- Review failed login attempts
- Check for unusual connection patterns
- Monitor replication lag
Weekly
- Review user permissions
- Check for CVE updates
- Rotate backup encryption keys
Monthly
- Password rotation (optional, if policy requires)
- SSL certificate expiry check
- Security patch updates
- Audit log review
Quarterly
- Full security audit
- Penetration testing
- Disaster recovery drill
- Update security documentation
Support
For security issues:
- PostgreSQL Security: security@postgresql.org
- CVE Database: https://www.postgresql.org/support/security/
NEVER disclose security vulnerabilities publicly. Report privately first.