显式引入数据库 TLS 配置并在生产环境拒绝弱 sslmode,避免连接静默降级。同步更新 deploy/README 与运维 runbook,落地 db.refining.ltd 的证书与服务器配置流程。 Made-with: Cursor
2.5 KiB
2.5 KiB
PostgreSQL TLS Hardening Runbook
This runbook applies to:
- PostgreSQL server:
47.117.131.22(db.refining.ltd) secrets-mcpapp server:47.238.146.244(secrets.refining.app)
1) Issue certificate for db.refining.ltd (Let's Encrypt + Cloudflare DNS-01)
Install acme.sh on the PostgreSQL server and use a Cloudflare API token with DNS edit permission for the target zone.
curl https://get.acme.sh | sh -s email=ops@refining.ltd
export CF_Token="your_cloudflare_dns_token"
export CF_Zone_ID="your_zone_id"
~/.acme.sh/acme.sh --issue --dns dns_cf -d db.refining.ltd --keylength ec-256
Install cert/key into a PostgreSQL-readable path:
sudo mkdir -p /etc/postgresql/tls
sudo ~/.acme.sh/acme.sh --install-cert -d db.refining.ltd --ecc \
--fullchain-file /etc/postgresql/tls/fullchain.pem \
--key-file /etc/postgresql/tls/privkey.pem \
--reloadcmd "systemctl reload postgresql || systemctl restart postgresql"
sudo chown -R postgres:postgres /etc/postgresql/tls
sudo chmod 600 /etc/postgresql/tls/privkey.pem
sudo chmod 644 /etc/postgresql/tls/fullchain.pem
2) Configure PostgreSQL TLS and access rules
In postgresql.conf:
ssl = on
ssl_cert_file = '/etc/postgresql/tls/fullchain.pem'
ssl_key_file = '/etc/postgresql/tls/privkey.pem'
In pg_hba.conf, allow app traffic via TLS only (example):
hostssl secrets-mcp postgres 47.238.146.244/32 scram-sha-256
Keep a safe admin path (local socket or restricted source CIDR) before removing old plaintext host rules.
Reload PostgreSQL:
sudo systemctl reload postgresql
3) Verify server-side TLS
openssl s_client -starttls postgres -connect db.refining.ltd:5432 -servername db.refining.ltd
The handshake should succeed and the certificate should match db.refining.ltd.
4) Update secrets-mcp app server env
Use environment values like:
SECRETS_DATABASE_URL=postgres://postgres:***@db.refining.ltd:5432/secrets-mcp
SECRETS_DATABASE_SSL_MODE=verify-full
SECRETS_ENV=production
If you use private CA instead of public CA, also set:
SECRETS_DATABASE_SSL_ROOT_CERT=/etc/secrets/pg-ca.crt
Restart secrets-mcp after updating env.
5) Verify from app server
Run positive and negative checks:
- Positive: app starts, migrations pass, dashboard + MCP API work.
- Negative:
- wrong hostname -> connection fails
- wrong CA file -> connection fails
- disable TLS on DB -> connection fails
This ensures no silent downgrade to weak TLS in production.