When setting up an SSH tunnel for MySQL access on Mac OS X, you might encounter two common errors:
bind: Address already in use
when trying to reuse port 3306channel 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 occupiedchannel 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:
- Verify remote MySQL server is running:
sudo service mysql status
- Check MySQL user permissions:
SELECT host, user FROM mysql.user;
- Ensure MySQL is configured to accept remote connections (check
bind-address
inmy.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