Security hardening for ImpulseDB Postgres
What the module hardens by default — firewall, TLS, admin proxy, pg_hba defaults, role separation — and what you as the operator still own.
Last updated 20 days ago
Security hardening for ImpulseDB Postgres
ImpulseDB Postgres makes a number of hardening choices for you at provision time. This article is the operator's checklist of what's already done, what the Security tab gives you, and what's still your call.
What the module does by default
Firewall
Every dedicated VPS and every shared host comes up with UFW configured for both IPv4 and IPv6. The Postgres listener is open only to your WHMCS server IPs and to the per-tenant access list the module manages — never to `0.0.0.0/0`. The admin-proxy port is firewalled the same way. If you change your WHMCS server IPs, update them under Settings → WHMCS Servers and the firewall rules sync on the next provisioning cron tick.
TLS on the Postgres endpoint
Cloud-init issues a Let's Encrypt certificate via DNS-01 for each host's hostname and configures Postgres to require TLS for non-loopback connections. Customers connect over TLS by default; the connection string the module hands them includes sslmode=require. Certificates renew automatically through the same DNS-01 flow.
Admin proxy authentication
The admin-proxy secret each Postgres host uses to call back into WHMCS is per-region, never global. Compromise of one host's secret limits blast radius to that region. ImpulseCore's region helpers enforce this — there is no path to a single shared secret across the fleet.
pg_hba.conf defaults
Cloud-init writes a pg_hba.conf that:
- Rejects all non-TLS connections outside of
127.0.0.1. - Requires
scram-sha-256for password auth (nevermd5). - Restricts the customer's database role to that customer's database only.
Role separation
Each provisioned database has two roles:
- The admin role the module uses for migrations, backups, extension management, and patching.
- The customer role the customer connects with for normal application traffic. Limited to its own database, no superuser, no role-creation rights.
The customer never sees the admin role credentials.
What the Security tab gives you
The Security tab is a top-level peer of Overview / Servers / Plans / Customers / Settings / Tools. It pulls daily snapshots from each Postgres host (kernel running vs latest, pending updates, reboot-required state, Postgres major version) and correlates them against a CVE feed assembled from three sources:
- Ubuntu USN (hourly) for OS-level CVEs.
- CISA KEV (hourly) for actively-exploited.
- NVD by CPE (daily) for Postgres itself via
cpe:2.3:a:postgresql:postgresql.
Critical (CVSS 9.0+) or KEV-listed matches insert a maintenance schedule at now + 24h (sooner for KEV) and trigger a branded customer email. The Security tab renders a red banner for those; High (CVSS 7.0–8.9) renders amber. A separate amber strip warns if the CVE feed itself has gone stale (no refresh in over 6 hours).
Per-server rows in the Security tab show pending update counts, reboot indicator, kernel drift, Postgres major version, last reboot, uptime, and per-server Patch now / Reboot now buttons. A Patch all servers (N) button appears above the table when at least one server has pending security updates.
Important: the Security tab doesn't auto-patch on its own
The Security tab surfaces and flags risk. It schedules and applies patches only via the actuators the module ships — SecurityActuator (per-service) and ServerActuator (per-server). Both register with ImpulseCore on activation. When a maintenance window is open and a schedule is due, the actuator takes a pre-patch snapshot, applies the patches, reboots if required, and rolls back on failure.
If for some reason the actuators don't register — or for a host outside the snapshot+restore path — the Security tab will still show the CVE risk and the pending updates, but the patches will not apply on their own. The operator owns that gap.
What you still own
The module hardens a lot. Things it can't decide for you:
- WHMCS itself. The admin proxy is only as safe as the WHMCS install it calls back into. Keep WHMCS, PHP, and the web server patched.
- DNS provider account security. Cloudflare account compromise can rewrite hostnames mid-issuance. Use 2FA and limited-scope API tokens.
- Provider account security. A compromised Vultr / Hetzner / DO / Linode account is game over for everything on it. 2FA, IP allow-listing where the provider offers it, audit the team membership periodically.
- Backup target credentials. WAL-G credentials grant read access to every backup written. Scope the access key to one bucket, rotate periodically.
- Customer password discipline. The module sets strong defaults at provision, but customers can rotate to whatever they want from the client area. Provide guidance in your welcome email.
- The maintenance window policy. Defaults are Sunday 02:00 client tz / 60 min. Decide whether that fits your SLA before you go live, and adjust the default if not.
When to investigate
Audit log entries to watch for in ImpulseCore's audit (Addons → ImpulseCore → Audit):
snapshot_skipped— a patch went out without a pre-patch snapshot (provider plan may not support snapshots, e.g. Linode Nanode without backups enabled).security.patch.rollback— a patch failed and the actuator restored the pre-patch snapshot.cve_feed_refresh.failed— the feed itself isn't refreshing; the Security tab's data is going stale.