4-node: safe
A 3+1 node template with hardened security, delayed cluster, following high-standard security best practices.
Categories:
The safe is a specialized configuration template for security hardening, based on the full template.
Overview
- Conf Name :
safe - Node Count : 4-node,
pigsty/vagrant/spec/full.rb - Description : A 3+1 node template with hardened security, delayed cluster, following high-standard security best practices.
- Content :
pigsty/conf/safe.yml - OS Distro :
el7,el8,el9,u20,u22,u24 - OS Arch :
x86_64 - Related :
full
To enable: Use the -c safe parameter during the configure process:
./configure -c safe This is a 4-node template, you need to modify the IP address of the other 3 nodes after configure
Content
Source: pigsty/conf/safe.yml
#==============================================================# # File : safe.yml # Desc : Pigsty 3-node security enhance template # Ctime : 2020-05-22 # Mtime : 2024-11-12 # Docs : https://pigsty.io/docs/conf/safe # Author : Ruohang Feng ([email protected]) # License : AGPLv3 #==============================================================# #===== SECURITY ENHANCEMENT CONFIG TEMPLATE WITH 3 NODES ======# # * 3 infra nodes, 3 etcd nodes, single minio node # * 3-instance pgsql cluster with an extra delayed instance # * crit.yml templates, no data loss, checksum enforced # * enforce ssl on postgres & pgbouncer, use postgres by default # * enforce an expiration date for all users (20 years by default) # * enforce strong password policy with passwordcheck extension # * enforce changing default password for all users # * log connections and disconnections # * restrict listen ip address for postgres/patroni/pgbouncer all: children: infra: # infra cluster for proxy, monitor, alert, etc hosts: # 1 for common usage, 3 nodes for production 10.10.10.10: { infra_seq: 1 } # identity required 10.10.10.11: { infra_seq: 2, repo_enabled: false } 10.10.10.12: { infra_seq: 3, repo_enabled: false } vars: { patroni_watchdog_mode: off } minio: # minio cluster, s3 compatible object storage hosts: { 10.10.10.10: { minio_seq: 1 } } vars: { minio_cluster: minio } etcd: # dcs service for postgres/patroni ha consensus hosts: # 1 node for testing, 3 or 5 for production 10.10.10.10: { etcd_seq: 1 } # etcd_seq required 10.10.10.11: { etcd_seq: 2 } # assign from 1 ~ n 10.10.10.12: { etcd_seq: 3 } # odd number please vars: # cluster level parameter override roles/etcd etcd_cluster: etcd # mark etcd cluster name etcd etcd_safeguard: false # safeguard against purging etcd_clean: true # purge etcd during init process pg-meta: # 3 instance postgres cluster `pg-meta` hosts: 10.10.10.10: { pg_seq: 1, pg_role: primary } 10.10.10.11: { pg_seq: 2, pg_role: replica } 10.10.10.12: { pg_seq: 3, pg_role: replica , pg_offline_query: true } vars: pg_cluster: pg-meta pg_conf: crit.yml pg_users: - { 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 } pg_databases: - { name: meta ,baseline: cmdb.sql ,comment: pigsty meta database ,schemas: [ pigsty ] ,extensions: [ { name: vector } ] } pg_services: - { name: standby , ip: "*" ,port: 5435 , dest: default ,selector: "[]" , backup: "[? pg_role == `primary`]" } pg_listen: '${ip},${vip},${lo}' pg_vip_enabled: true pg_vip_address: 10.10.10.2/24 pg_vip_interface: eth1 # OPTIONAL delayed cluster for pg-meta pg-meta-delay: # delayed instance for pg-meta (1 hour ago) hosts: { 10.10.10.13: { pg_seq: 1, pg_role: primary, pg_upstream: 10.10.10.10, pg_delay: 1h } } vars: { pg_cluster: pg-meta-delay } #################################################################### # Parameters # #################################################################### vars: # global variables version: v3.3.0 # pigsty version string admin_ip: 10.10.10.10 # admin node ip address region: default # upstream mirror region: default|china|europe node_tune: oltp # node tuning specs: oltp,olap,tiny,crit pg_conf: oltp.yml # pgsql tuning specs: {oltp,olap,tiny,crit}.yml patroni_ssl_enabled: true # secure patroni RestAPI communications with SSL? pgbouncer_sslmode: require # pgbouncer client ssl mode: disable|allow|prefer|require|verify-ca|verify-full, disable by default pg_default_service_dest: postgres # default service destination to postgres instead of pgbouncer pgbackrest_method: minio # pgbackrest repo method: local,minio,[user-defined...] #----------------------------------# # Credentials #----------------------------------# #grafana_admin_username: admin grafana_admin_password: You.Have2Use-A_VeryStrongPassword #pg_admin_username: dbuser_dba pg_admin_password: PessWorb.Should8eStrong-eNough #pg_monitor_username: dbuser_monitor pg_monitor_password: MekeSuerYour.PassWordI5secured #pg_replication_username: replicator pg_replication_password: doNotUseThis-PasswordFor.AnythingElse #patroni_username: postgres patroni_password: don.t-forget-to-change-thEs3-password #haproxy_admin_username: admin haproxy_admin_password: GneratePasswordWith-pwgen-s-16-1 #----------------------------------# # MinIO Related Options #----------------------------------# minio_users: # and configure `pgbackrest_repo` & `minio_users` accordingly - { access_key: dba , secret_key: S3User.DBA.Strong.Password, policy: consoleAdmin } - { access_key: pgbackrest , secret_key: Min10.bAckup ,policy: readwrite } pgbackrest_repo: # pgbackrest repo: https://pgbackrest.org/configuration.html#section-repository local: # default pgbackrest repo with local posix fs path: /pg/backup # local backup directory, `/pg/backup` by default retention_full_type: count # retention full backups by count retention_full: 2 # keep 2, at most 3 full backup when using local fs repo minio: # optional minio repo for pgbackrest s3_key: pgbackrest # <-------- CHANGE THIS, SAME AS `minio_users` access_key s3_key_secret: Min10.bAckup # <-------- CHANGE THIS, SAME AS `minio_users` secret_key cipher_pass: 'pgBR.${pg_cluster}' # <-------- CHANGE THIS, you can use cluster name as part of password type: s3 # minio is s3-compatible, so s3 is used s3_endpoint: sss.pigsty # minio endpoint domain name, `sss.pigsty` by default s3_region: us-east-1 # minio region, us-east-1 by default, useless for minio s3_bucket: pgsql # minio bucket name, `pgsql` by default s3_uri_style: path # use path style uri for minio rather than host style path: /pgbackrest # minio backup path, default is `/pgbackrest` storage_port: 9000 # minio port, 9000 by default storage_ca_file: /etc/pki/ca.crt # minio ca file path, `/etc/pki/ca.crt` by default bundle: y # bundle small files into a single file cipher_type: aes-256-cbc # enable AES encryption for remote backup repo retention_full_type: time # retention full backup by time on minio repo retention_full: 14 # keep full backup for last 14 days #----------------------------------# # Access Control #----------------------------------# # add passwordcheck extension to enforce strong password policy pg_libs: '$libdir/passwordcheck, pg_stat_statements, auto_explain' pg_extensions: - passwordcheck, supautils, pgsodium, pg_vault, pg_session_jwt, anonymizer, pgsmcrypto, pgauditlogtofile, pgaudit #, pgaudit17, pgaudit16, pgaudit15, pgaudit14 - pg_auth_mon, credcheck, pgcryptokey, pg_jobmon, logerrors, login_hook, set_user, pgextwlist, pg_auditor, sslutils, noset #pg_tde #pg_snakeoil pg_default_roles: # default roles and users in postgres cluster - { name: dbrole_readonly ,login: false ,comment: role for global read-only access } - { name: dbrole_offline ,login: false ,comment: role for restricted read-only access } - { name: dbrole_readwrite ,login: false ,roles: [ dbrole_readonly ] ,comment: role for global read-write access } - { name: dbrole_admin ,login: false ,roles: [ pg_monitor, dbrole_readwrite ] ,comment: role for object creation } - { 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 } pg_default_hba_rules: # postgres host-based auth rules by default - { user: '${dbsu}' ,db: all ,addr: local ,auth: ident ,title: 'dbsu access via local os user ident' } - { user: '${dbsu}' ,db: replication ,addr: local ,auth: ident ,title: 'dbsu replication from local os ident' } - { user: '${repl}' ,db: replication ,addr: localhost ,auth: ssl ,title: 'replicator replication from localhost' } - { user: '${repl}' ,db: replication ,addr: intra ,auth: ssl ,title: 'replicator replication from intranet' } - { user: '${repl}' ,db: postgres ,addr: intra ,auth: ssl ,title: 'replicator postgres db from intranet' } - { user: '${monitor}' ,db: all ,addr: localhost ,auth: pwd ,title: 'monitor from localhost with password' } - { user: '${monitor}' ,db: all ,addr: infra ,auth: ssl ,title: 'monitor from infra host with password' } - { user: '${admin}' ,db: all ,addr: infra ,auth: ssl ,title: 'admin @ infra nodes with pwd & ssl' } - { user: '${admin}' ,db: all ,addr: world ,auth: cert ,title: 'admin @ everywhere with ssl & cert' } - { user: '+dbrole_readonly',db: all ,addr: localhost ,auth: ssl ,title: 'pgbouncer read/write via local socket' } - { user: '+dbrole_readonly',db: all ,addr: intra ,auth: ssl ,title: 'read/write biz user via password' } - { user: '+dbrole_offline' ,db: all ,addr: intra ,auth: ssl ,title: 'allow etl offline tasks from intranet' } pgb_default_hba_rules: # pgbouncer host-based authentication rules - { user: '${dbsu}' ,db: pgbouncer ,addr: local ,auth: peer ,title: 'dbsu local admin access with os ident' } - { user: 'all' ,db: all ,addr: localhost ,auth: pwd ,title: 'allow all user local access with pwd' } - { user: '${monitor}' ,db: pgbouncer ,addr: intra ,auth: ssl ,title: 'monitor access via intranet with pwd' } - { user: '${monitor}' ,db: all ,addr: world ,auth: deny ,title: 'reject all other monitor access addr' } - { user: '${admin}' ,db: all ,addr: intra ,auth: ssl ,title: 'admin access via intranet with pwd' } - { user: '${admin}' ,db: all ,addr: world ,auth: deny ,title: 'reject all other admin access addr' } - { user: 'all' ,db: all ,addr: intra ,auth: ssl ,title: 'allow all user intra access with pwd' } #----------------------------------# # Repo, Node, Packages #----------------------------------# # if you wish to customize your own repo, change these settings: repo_modules: infra,node,pgsql # install upstream repo during repo bootstrap repo_remove: true # remove existing repo on admin node during repo bootstrap node_repo_modules: local # install the local module in repo_upstream for all nodes node_repo_remove: true # remove existing node repo for node managed by pigsty repo_packages: [ # default packages to be downloaded node-bootstrap, infra-package, infra-addons, node-package1, node-package2, pgsql-common #,docker ] repo_extra_packages: [ # default postgres packages to be downloaded pg17-main, pg17-sec # replace with the following line if you want all extensions #pg17-core ,pg17-time ,pg17-gis ,pg17-rag ,pg17-fts ,pg17-olap ,pg17-feat ,pg17-lang ,pg17-type ,pg17-func ,pg17-admin ,pg17-stat ,pg17-sec ,pg17-fdw ,pg17-sim ,pg17-etl ] Caveat
Beware that not all security-related extensions are available in ARM64 environments, ARM system users should enable extensions at their discretion.
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.