I have set up a SSH tunnel between two servers A and B. B has MySQL server, and this works:
mysql -h localhost -P 3306 -u user -p
While this doesn't:
mysql -h 127.0.0.1 -P 3306 -u user -p
Although my.cnf has these lines:
bind-address = 127.0.0.1
# Next addr differs slightly, but anyway
bind-address = 99.99.99.99
Now about the tunnel. It connects the following:(A) localhost(9989) -> (B) localhost(3306)
But when (on A, with ports forwarded) I do
mysql -v -h 127.0.0.1 -P 9989 -u user userdb -p
I get ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0
And when I do
mysql -v -h localhost -P 9989 -u user userdb -p
I get ERROR 1045 (28000): Access denied for user 'user'@'localhost' (using password: YES)
What might be the reason? What am I doing wrong?
MySQL, the most popular open-source database server, listens for incoming connections only on localhost. Creating an SSH tunnel allows you to securely connect to the remote MySQL server from your local client.
There are three issues here.
1 - Forget about the SSH tunnel for now
You cannot bind MySQL to more than one specific IP.
The first bind-address
clause is overridden (therefore, ignored) by the second one. Your server only listens to 99.99.99.99
.
The reason why you can connect with -h localhost
but not with -h 127.0.0.1
is that in the first form, you do not actually connect through TCP/IP, but through a local socket.
Look in your my.cnf
for a socket
clause.
Remove one redundant bind-address
clause. You may want to use bind-address=0.0.0.0
, which instructs MySQL daemon to listen to all network interfaces.
2 - Let's setup your SSH tunnel
The reason for you error ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0
is not obvious to me. I suspect SSH tunnel is actually established only when it receives a connection request (in your case, when you run the mysql
client). Since your server does not listen to 127.0.0.1 (see previous paragraph), the SSH tunnel cannot be established, connection fails, and your client interprets it as a network failure.
3 - Why mysql -v -h localhost -P 9989 -u user userdb -p
fails
Please post the output of
[edit : just added ...OR host LIKE 'localhost'
below, as this might be relevant for troubleshooting purposes]
mysql > SELECT user, host FROM mysql.user WHERE user LIKE 'user' OR host LIKE 'localhost';
(replace 'user'
, after the LIKE
clause, with the actual user name if necessary)
MySQL access control checks both the username/password (user
) and the origin of the connection (host
) to identify a user. You probably did not create a user 'user'@'localhost'
.
N.B.: mysql.com being unreachable from my location at this time, I cannot link to the relevant manual pages.
I just encountered this very problem.
In my case MySQL server is configured with bind-address: 192.168.4.4
.
I originally setup an SSH tunnel with a commonly mentioned -L 3306:localhost:3306 user@server
string and from my computer connect with mysql -h 127.0.0.1
.
This does not work because MySQL no longer listens on 0.0.0.0 or even "localhost"
(aka 127.0.0.1), only 192.168.4.4
.
The correct tunnel string should be -L 3306:192.168.4.4:3306 user@server
.
This will tell the remote tunnel end to connect to MySQL using the IP MySQL actually listens on.
STEP-BY-STEP SSH TUNNELING
--- SERVER SIDE ----
in target machine (that can be addresed by IP or a domain hosted) there is config file /etc/mysql/my.cnf having a line
bind-address = 127.0.0.1
confirmed with console
netstat -tapn | grep mysql
// tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 18469/mysqld
which means mysql server will respond only to request from the localhost
--- CLIENT SIDE ----
you have an account (eventualy a ssh-key) to log using cygwin,putty or a linux_shell
ssh user_name@host_name
create SSH TUNNEL
ssh -f -N -L 1000:127.0.0.1:3306 user_name@host_name
which means hey ssh create a permanent connection from port 1000 on the machine that I type (client) to remote host_name:3306 .... 127.0.0.1 means here the remote (host_name) and should not be replaced with localhost word because this will make the connection on unix (named) socket not by IP ... You'll get 'ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysql.sock' (2)' when trying co connect mysql
-f = go in background -N = no excution
both -f -N kind of nohoop - you can close console and tunnels persist
--- SERVER SIDE ---
netstat -tapn | grep ssh
// tcp 0 0 server_ip:22 clint_ip:port ESTABLISHED 24915/sshd: user_name
which means there is a permanent connection through shh protocol
--- CLIENT SIDE ---
mysql -h 127.0.0.1 -P 1000 -u mysql_user -pmysql_pass
now your (client side) mysql client is conected to remote mysql server ... here 127.0.0.1 is client machine
same for workbench, heidiSQL
how to kill ssh tunnels
ps fax | grep ssh
kill process_id
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With