How to Fix “Address Already in Use” and “Connection Refused” Errors When SSH Tunneling MySQL on Mac OS X


2 views

When setting up an SSH tunnel for MySQL access on Mac OS X, you might encounter two common errors:

  1. bind: Address already in use when trying to reuse port 3306
  2. channel 1: open failed: connect failed: Connection refused when using alternative ports

Before creating a new tunnel, you need to clean up any existing ones:


# Find existing SSH processes
ps aux | grep ssh

# Kill the specific tunnel process (replace PID)
kill -9 [PID]

# Alternative method - kill all SSH tunnels
pkill -f "ssh -L"

The proper command structure for MySQL tunneling should be:


ssh -f -N -L [LOCAL_PORT]:localhost:3306 [USER]@[REMOTE_IP] -v

Key flags explanation:

  • -f: Requests ssh to go to background
  • -N: Do not execute remote command
  • -v: Verbose mode (helps debug connection issues)

When you get "Connection refused" even with alternative ports:

1. Verify MySQL is running on remote server:


ssh user@remote_ip "sudo systemctl status mysql"

2. Check MySQL bind address configuration:


ssh user@remote_ip "sudo grep bind-address /etc/mysql/my.cnf"

If it shows bind-address = 127.0.0.1, you'll need to either:

  • Change it to 0.0.0.0 (less secure)
  • Or use SSH tunneling with 127.0.0.1:3306:127.0.0.1:3306 format

Here's a full example that handles common pitfalls:


# First kill any existing tunnels
pkill -f "ssh -L"

# Create new tunnel with debug output
ssh -f -N -L 3310:127.0.0.1:3306 user@remote_ip -v \
  -o ExitOnForwardFailure=yes \
  -o ServerAliveInterval=60 \
  -o TCPKeepAlive=yes

Verify the tunnel works with either:

1. Command line test:


mysql -h 127.0.0.1 -P 3310 -u mysql_user -p

2. Or using MySQL Workbench settings:

  • Connection Method: Standard TCP/IP
  • Hostname: 127.0.0.1
  • Port: 3310
  • Username: [your_mysql_user]
  • Password: [your_password]

For long-running tunnels that survive network interruptions:


autossh -M 0 -f -N -L 3310:127.0.0.1:3306 user@remote_ip \
  -o "ServerAliveInterval 30" \
  -o "ServerAliveCountMax 3"

Note: Install autossh first with brew install autossh


When trying to establish an SSH tunnel for remote MySQL access on Mac OS X, you might encounter two common issues:

  • bind: Address already in use when port 3306 is occupied
  • channel 1: open failed: connect failed: Connection refused when using alternative ports

Before creating a new tunnel, check if any existing SSH processes are using your desired port:

lsof -i :3306
ps aux | grep ssh

To kill an existing SSH tunnel process:

kill [PID]

Here's the proper command syntax for creating an SSH tunnel:

ssh -L [LOCAL_PORT]:[REMOTE_IP]:[REMOTE_PORT] [USER]@[SERVER] -N

Example with alternative port:

ssh -L 127.0.0.1:3310:192.168.1.100:3306 user@example.com -N

After establishing the tunnel, verify it's working:

telnet 127.0.0.1 3310

You should see output similar to:

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

With the tunnel active, configure your MySQL client:

mysql -h 127.0.0.1 -P 3310 -u mysql_user -p

Or in MySQL Workbench:

  • Host: 127.0.0.1
  • Port: 3310
  • Username: Your MySQL username
  • Password: Your MySQL password

If you still get connection errors:

  1. Verify remote MySQL server is running: sudo service mysql status
  2. Check MySQL user permissions: SELECT host, user FROM mysql.user;
  3. Ensure MySQL is configured to accept remote connections (check bind-address in my.cnf)

For long-running connections, consider using autossh:

brew install autossh
autossh -M 0 -f -N -L 3310:localhost:3306 user@example.com

Remember these security best practices:

  • Use SSH key authentication instead of passwords
  • Restrict MySQL user permissions to only necessary databases
  • Consider using a non-standard port for the SSH tunnel