Allow Remote MySQL Access on Port 3306 (Ubuntu)

Configure MySQL on Ubuntu to accept remote connections safely — bind-address, user grants, and the firewall rule, in the right order.

By DevStudio Online Team · Published September 3, 2026

By default, a fresh MySQL install on Ubuntu only listens on 127.0.0.1 and refuses any connection from outside the server itself. Opening it up to remote access requires three separate changes, and skipping any one of them leaves you with a confusing "connection refused" or "access denied" with no obvious cause.

1. Change the bind address

Find MySQL's config file (usually /etc/mysql/mysql.conf.d/mysqld.cnf on Ubuntu) and update the bind-address line:

# was: bind-address = 127.0.0.1
bind-address = 0.0.0.0

0.0.0.0 means "listen on every network interface," not just localhost. Restart MySQL for it to take effect:

sudo systemctl restart mysql

2. Grant a user permission to connect from outside

A MySQL user account is scoped to a specific host by default ('user'@'localhost'). That grant doesn't cover remote connections — you need a separate grant for the host (or % for "any host"):

CREATE USER 'appuser'@'%' IDENTIFIED BY 'a-strong-password';
GRANT ALL PRIVILEGES ON mydatabase.* TO 'appuser'@'%';
FLUSH PRIVILEGES;

Using % works for testing, but in production scope it down to the actual IP address (or subnet) that needs access — e.g. 'appuser'@'203.0.113.10' — rather than leaving the database reachable from literally anywhere on the internet with just a password.

3. Open the firewall

Even with MySQL listening on all interfaces and the grant in place, Ubuntu's ufw (if enabled) will silently drop the connection unless port 3306 is explicitly allowed:

sudo ufw allow from 203.0.113.10 to any port 3306

Scoping the ufw rule to a specific source IP (rather than sudo ufw allow 3306, which opens it to everyone) is the difference between "my one application server can connect" and "anyone on the internet can attempt to brute-force my database password."

Sanity-check the whole chain

mysql -h your-server-ip -u appuser -p mydatabase

If this hangs and times out, it's almost always the firewall (step 3) or bind-address (step 1). If it connects but then says Access denied, it's the grant (step 2) — that distinction alone tells you which of the three steps to re-check first.

Related tool

MySQL Connector — connect and browse from your browser

More MySQL guides