Skip to content
Remote DB access Open a database to one specific source IP with a tight allowlist, then revoke it when the work is done.

Remote DB access

By default every database on a MZPanel server is closed to the public internet — it listens on localhost and the firewall keeps the port shut. When you need an external client to connect (a BI tool, a local app, another server), you open access for one specific source IP rather than the whole world, from the Databases section of a server (/servers/:id/databases). Remote DB access is a Pro feature.

  1. Open the server’s Databases section and click the Engine settings gear in the toolbar. Pick the engine you want to expose — MariaDB, PostgreSQL or MongoDB.
  2. In the engine’s settings drawer, find Remote access (the connectivity block). A live reachability verdict tells you the truth about whether the box is currently reachable from outside.
  3. Under Allowed remote IPs, type the client’s IPv4 address or CIDR (e.g. 203.0.113.4 or 203.0.113.0/24) and click Allow.
  4. MZPanel binds the engine to a reachable address (if it wasn’t already) and opens the firewall for that one source IP. Every other address stays locked out.
  • Read the reachability verdict — before and after you change anything, the drawer shows whether the engine is listening publicly, whether the firewall is active, and whether the port is actually open, so you’re not guessing.
  • Revoke an entry — remove any allowlisted IP to close access again (see below).
  • Set the bind + port — the same drawer lets you switch the engine between local-only and remote binding and change its listening port.
  • Get a connection string — for a remote MariaDB account, the connection helper hands you a copy-ready endpoint for the private-network IP, public IP or a domain.

How MariaDB / MongoDB differ from PostgreSQL

Section titled “How MariaDB / MongoDB differ from PostgreSQL”

Remote access uses two different models under the hood:

  • MariaDB / MySQL and MongoDB — enforced through firewall rules. Adding an entry binds the listener to a reachable address (db config-set --bind remote / mongo config-set --bind remote) and opens the firewall for that one source IP; the database stays invisible to every other address. The allowlist you see is the set of allow rules on the engine’s port.
  • PostgreSQL — uses native expose / unexpose controls instead of ad-hoc firewall edits. Exposing an IP updates the pg_hba-style access and the firewall together; un-exposing reverses both, so the two never drift apart. The allowlist is tracked natively and read back with pg exposed.

Open the engine’s settings drawer and revoke the allowlisted entry:

  • MariaDB / MongoDB — remove the firewall rule for that source IP to close the port again.
  • PostgreSQLunexpose the instance, which removes both the listener exposure and the firewall opening in one step.

Actions here dispatch database and firewall jobs to the server’s agent, which runs them natively:

ActionJobAgent runs
Reachability checkdb.net-statusdb net-status --json
Bind MariaDB local/remotedb.config-setdb config-set --bind <local|remote>
Bind MongoDB local/remotemongo.config-setmongo config-set --bind <local|remote>
Allow / revoke IP (MariaDB, Mongo)security.fwsecurity fw add|remove …
List Postgres allowlistpg.exposedpg exposed --json
Expose Postgres to an IPpg.exposepg expose <ip> --json
Unexpose Postgrespg.unexposepg unexpose <ip> --json

For MariaDB and Mongo, allowing an IP is two steps: bind the engine to a reachable address, then add a scoped firewall allow rule. The allowlist is read straight from the server’s firewall (security inventory) — MZPanel doesn’t keep a separate copy. PostgreSQL’s expose/unexpose is a single native operation that edits pg_hba and the firewall together.

Every action maps to an mz command on the box — the same engine the dashboard drives. SSH in and run them directly, or let an on-box AI (ClaudeCode) run them:

Terminal window
mz db net-status --json # is the DB reachable from outside?
# MariaDB / MongoDB — bind, then open the firewall for one source IP
mz db config-set --bind remote --port 3306 --json
mz security fw add 3306 tcp allow 203.0.113.4 "mz db remote" --json
mz security fw remove 3306 tcp allow 203.0.113.4 "" --json # revoke
# PostgreSQL — native expose / unexpose
mz pg exposed --json # current allowlist
mz pg expose 203.0.113.4 --json # open for one IP
mz pg unexpose 203.0.113.4 --json # revoke

Always pass --json for machine output. See The mz CLI and the command catalog.

  • db config-set --bind remote alone does not open the firewall. Binding publicly only makes the engine listen; the port is still closed until you add a scoped allow rule. The dashboard does both for you when you click Allow — on the CLI, run the bind and the security fw add (see above).
  • A stale allowlist entry is dead weight. Firewall rules and Postgres exposures persist across reboots. If a client’s IP changed, revoke the old entry and add the new one — an orphaned allow rule is an open door to nobody useful.
  • The verdict says “reachable” but you still can’t connect. The box-level firewall is only one layer; a cloud provider’s security group or network ACL may also be blocking the port. The reachability verdict reflects the box, not your provider’s edge.
  • Offline servers can’t change access. Reading the current allowlist may render from cache, but binding, allowing or revoking needs the agent online.
  • Databases — create databases and users, and open the engine settings drawer.
  • Server security — the firewall, Fail2ban and SSH hardening.
  • The mz CLI — driving the box from the command line.