Security
Security considerations and best-practices
Pigsty already provides a secure-by-default database authentication and access control model.
It is strong enough for most common scenarios, as long as you follow the security best-practices below.
Confidentiality
Files
Secure your pigsty config file
pigsty.yml
hold very sensitive information like passwords- Limit access to admin/infra nodes to admin/DBA users only
- Limit access to repo, if you are managing pigsty config with GitOps
Secure your CA private key
- Generated at
~/pigsty/files/pki/ca/ca.key
by default - Secure & backup it in a safe place, DON'T THROW IT AWAY!
- Also consider secure other private keys for various certs
Passwords
DO NOT USE THE DEFAULT PASSWORDs
Always change these default passwords in serious deployment
grafana_admin_password
:pigsty
pg_admin_password
:DBUser.DBA
pg_monitor_password
:DBUser.Monitor
pg_replication_password
:DBUser.Replicator
patroni_password
:Patroni.API
haproxy_admin_password
:pigsty
minio_secret_key
:minioadmin
Change MinIO credentials and pgbackrest references
If you are using MinIO as backup storage, also change these credentials:
- Change the password for
minio_users
.[pgbackrest]
.secret_key
- Change pgbackrest references:
pgbackrest_repo
.minio
.s3_key_secret
Enforce strong pg password with the passwordcheck extension
- add
$lib/passwordcheck
topg_libs
to enforce password policy. - stronger version:
passwordcheck_cracklib
Encrypt remote backup with an encryption algorithm
- check
pgbackrest_repo
definitionrepo_cipher_type
cipher_type: aes-256-cbc
by default
Use advanced password encryption method for PostgreSQL
- use
pg_pwd_enc
defaultscram-sha-256
instead of legacymd5
- default behavior is
scram-sha-256
,md5
is deprecated
Add an expiration date to business user passwords
You can set an expiry date for each user for compliance purposes.
- { name: dbuser_meta , password: Pleas3-ChangeThisPwd ,expire_in: 7300 ,pgbouncer: true ,roles: [ dbrole_admin ] ,comment: pigsty admin user }
- { name: dbuser_view , password: Make.3ure-Compl1ance ,expire_in: 7300 ,pgbouncer: true ,roles: [ dbrole_readonly ] ,comment: read-only viewer for meta database }
- { name: postgres ,superuser: true ,expire_in: 7300 ,comment: system superuser }
- { name: replicator ,replication: true ,expire_in: 7300 ,roles: [pg_monitor, dbrole_readonly] ,comment: system replicator }
- { name: dbuser_dba ,superuser: true ,expire_in: 7300 ,roles: [dbrole_admin] ,pgbouncer: true ,pool_mode: session, pool_connlimit: 16 , comment: pgsql admin user }
- { name: dbuser_monitor ,roles: [pg_monitor] ,expire_in: 7300 ,pgbouncer: true ,parameters: {log_min_duration_statement: 1000 } ,pool_mode: session ,pool_connlimit: 8 ,comment: pgsql monitor user }
Don't forget to refresh these expiry dates periodically with pgsql-user.yml
playbook
Don't print password to logs
SET log_statement TO 'none';
ALTER USER "{{ user.name }}" PASSWORD '{{ user.password }}';
SET log_statement TO DEFAULT;
IP Addresses
Bind specific IP addresses for postgres/pgbouncer/patroni
- The default
pg_listen
address is0.0.0.0
, which is all IPv4 addresses. - Consider using
pg_listen: '${ip},${vip},${lo}'
to bind to specific addresses for better security.
Do not expose any port to the Internet; except 80/443, the infra portal
- Grafana/Prometheus are bind to all IP address by default for convenience.
- You can modify their bind configuration to listen on localhost/intranet IP and expose by Nginx.
- Redis server are bind to all IP address by default for convenience. You can change
redis_bind_address
to listen on intranet IP. - You can also implement it with the security group or firewall rules.
Limit postgres client access with HBA
- There's a security enhance config template:
security.yml
Limit patroni admin access from the infra/admin node
- This is restricted by default with
restapi.allowlist
Network Traffic
Access Nginx with SSL and domain names
- Nginx SSL is controlled by
nginx_sslmode
, which isenable
by default. - Nginx Domain names are specified by
infra_portal..domain
.
Secure Patroni REST API with SSL
patroni_ssl_enabled
is disabled by default- Since it affects health checks and API invocation.
- Note this is a global option, and you have to decide before deployment.
Secure Pgbouncer Client Traffic with SSL
pgbouncer_sslmode
isdisable
by default- Since it has a significant performance impact.
Integrity
Consistency
Use consistency-first mode for PostgreSQL
- Use
crit.yml
templates forpg_conf
will trade some availability for the best consistency.
Use node crit tuned template for better consistency
-
set
node_tune
tocrit
to reduce dirty page ratio. -
Enable data checksum to detect silent data corruption.
-
pg_checksum
is disabled by default, and enabled forcrit.yml
by default -
This can be enabled later, which requires a full cluster scan/stop.
Audit
Enable connection logging for audit
- Enable
log_connections
andlog_disconnections
after the pg cluster bootstrap. - Audit incoming sessions; this is enabled in
crit.yml
by default.
Fat Finger
DO NOT RE-RUN install.yml PLAYBOOK
Running install.yml
again will nuke (overwrite) the entire deployment!
RE-RUN pgsql.yml WITH CAUTION
It will OVERWRITE existing PostgreSQL by default before v3.5.
Use pg_safeguard
to avoid fat fingers
Availability
Redundancy
Use enough nodes for serious production deployment
- You need at least three nodes (tolerate one node failure) to achieve production-grade high availability.
- If you only have two nodes, you can tolerate the failure of the specific standby node.
- If you have one node, use an external S3/MinIO for cold backup & wal archive storage.
Use multiple infra nodes in serious production deployment
- Use multiple infra nodes in serious production deployment (e.g., 1~3)
- Usually, 2 ~ 3 is enough for a large production deployment.
Use enough etcd members and use odd numbers
- Use enough etcd members and use odd numbers (1,3,5,7).
- Check ETCD Configuration for details.
Fault Tolerance
Access
Use VIP, DNS, HAProxy instead of fixed IP
- Do not access the database directly via a fixed IP address; use VIP, DNS, HAProxy, or their combination.
- Haproxy will handle the traffic control for the clients in case of failover/switchover.