【问题标题】:MySQL connection over SSH tunnel通过 SSH 隧道的 MySQL 连接
【发布时间】:2012-06-19 04:04:35
【问题描述】:

我在两台服务器 AB 之间建立了 SSH 隧道。 B 有 MySQL 服务器,这是可行的:

mysql -h localhost -P 3306 -u user -p

虽然不是这样:

mysql -h 127.0.0.1 -P 3306 -u user -p

虽然 my.cnf 有这些行:

bind-address        = 127.0.0.1
# Next addr differs slightly, but anyway
bind-address        = 99.99.99.99

现在关于隧道。它连接以下内容:(A) localhost(9989) -> (B) localhost(3306) 但是当(在A上,端口转发)我做

mysql -v -h 127.0.0.1 -P 9989 -u user userdb -p

我收到ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0

当我这样做时

mysql -v -h localhost -P 9989 -u user userdb -p

我收到ERROR 1045 (28000): Access denied for user 'user'@'localhost' (using password: YES)

可能是什么原因?我做错了什么?

【问题讨论】:

    标签: mysql ssh ssh-tunnel


    【解决方案1】:

    在我的例子中,SSH 守护程序中的配置阻塞了隧道。应该启用 AllowTcpForwarding。

    AllowTcpForwarding yes
    

    【讨论】:

      【解决方案2】:

      分步 SSH 隧道

      --- 服务器端 ----

      在目标机器(可以通过 IP 或托管域进行寻址)中有配置文件 /etc/mysql/my.cnf 有一行

      bind-address    = 127.0.0.1
      

      通过控制台确认

      netstat -tapn |  grep mysql
      // tcp    0    0 127.0.0.1:3306     0.0.0.0:*    LISTEN      18469/mysqld
      

      这意味着mysql服务器将只响应来自本地主机的请求

      --- 客户端 ----

      你有一个使用 cygwin、putty 或 linux_shell 登录的帐户(最终是一个 ssh 密钥)

      ssh user_name@host_name
      

      创建 SSH 隧道

      ssh -f -N -L 1000:127.0.0.1:3306    user_name@host_name
      

      这意味着嘿 ssh 创建一个从我键入(客户端)上的端口 1000 到远程主机名:3306 的永久连接 .... 127.0.0.1 在这里表示远程(主机名),不应替换为 localhost 字因为这将在 unix(命名)套接字上建立连接,而不是通过 IP ... 你会得到 'ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysql. sock' (2)' 尝试 co connect mysql 时

      -f = 进入后台 -N = 不执行

      both -f -N 一种 nohoop - 你可以关闭控制台并且隧道仍然存在

      --- 服务器端 ---

      netstat -tapn |  grep ssh
      // tcp  0  0  server_ip:22   clint_ip:port  ESTABLISHED 24915/sshd: user_name
      

      表示通过 shh 协议存在永久连接

      --- 客户端 ---

      mysql -h 127.0.0.1 -P 1000 -u mysql_user -pmysql_pass
      

      现在你的(客户端)mysql客户端连接到远程mysql服务器......这里127.0.0.1是客户端机器

      同样适用于工作台,heidiSQL


      如何杀死 ssh 隧道

      ps fax | grep ssh
      kill process_id
      

      【讨论】:

      • 很好的清晰解释。我在 ssh 隧道命令中使用了 host_name 而不是 127.0.0.1。谢谢
      【解决方案3】:

      我在 Windows 上确实遇到了同样的问题 ("Lost connection...")(通过 Putty 使用 ssh 隧道时)。我在这里遇到了 2 个问题:

      1. 使用了错误的端口,请仔细检查是否设置正确
      2. 我忘记在Putty: Connection > SSH > Tunnels > Local ports accept connections from other hosts 中启用

      【讨论】:

        【解决方案4】:

        一个简单的步骤对我有用...我会分享这个,所以也许你们中的一些人可以免于头痛。

        我的设置

        在我的特殊情况下,我有一个在 Ubuntu 上运行的 Percona 服务器,通过 SSH 连接到 MySQL Workbench(在 Windows VM 中);服务器运行了好几天,然后在处理查询时出现错误 10060。

        什么对我有用

        我在 Acquia.com 的一个论坛中发现,在某些情况下,Workbench 不会接受“127.0.0.1”作为主机,因此您必须将其更改为“localhost”。我做到了,而且成功了(奇怪的是,Workbench 再次要求输入密码,即使密码已经存储,但仍然有效)。

        【讨论】:

          【解决方案5】:

          我刚刚遇到了这个问题。

          在我的例子中,MySQL 服务器配置了bind-address: 192.168.4.4。 我最初使用通常提到的-L 3306:localhost:3306 user@server 字符串设置了一个 SSH 隧道,并从我的计算机连接到mysql -h 127.0.0.1

          这不起作用,因为 MySQL 不再监听 0.0.0.0 甚至 "localhost"(aka 127.0.0.1),只监听 192.168.4.4

          正确的隧道字符串应该是-L 3306:192.168.4.4:3306 user@server。 这将告诉远程隧道端使用 MySQL 实际侦听的 IP 连接到 MySQL。

          【讨论】:

            【解决方案6】:

            这里有三个问题。

            1 - 暂时忘记 SSH 隧道

            您不能将 MySQL 绑定到多个特定 IP。 第一个 bind-address 子句被第二个覆盖(因此被忽略)。你的服务器只监听99.99.99.99

            您可以使用-h localhost 连接但不能使用-h 127.0.0.1 的原因是,在第一种形式中,您实际上不是通过 TCP/IP 连接,而是通过本地套接字。

            在您的my.cnf 中查找socket 子句。

            删除一个多余的bind-address 子句。您可能想要使用bind-address=0.0.0.0,它指示 MySQL 守护进程侦听所有网络接口。

            2 - 让我们设置您的 SSH 隧道

            错误ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0 的原因对我来说并不明显。我怀疑 SSH 隧道实际上仅在收到连接请求时才建立(在您的情况下,当您运行mysql 客户端时)。由于你的服务器不监听 127.0.0.1(见上一段),所以无法建立 SSH 隧道,连接失败,你的客户端将其解释为网络故障。

            3 - 为什么mysql -v -h localhost -P 9989 -u user userdb -p 失败

            请张贴

            的输出

            [编辑:刚刚在下面添加了...OR host LIKE 'localhost',因为这可能与故障排除有关]

            mysql > SELECT user, host FROM mysql.user WHERE user LIKE 'user' OR host LIKE 'localhost';
            

            (在LIKE子句之后替换'user',必要时使用实际用户名)

            MySQL 访问控制会检查用户名/密码 (user) 和连接来源 (host) 以识别用户。您可能没有创建用户'user'@'localhost'

            注意:此时无法从我的位置访问 mysql.com,我无法链接到相关的手册页。

            【讨论】:

            • 非常感谢您的详细解答!解决第一个问题使其工作。
            • 你可能错过了我上次的编辑:“你可能想使用bind-address=0.0.0.0,它指示 MySQL 守护进程监听所有网络接口。”。不客气。
            • localhost、127.0.0.1和本地socket有什么区别?
            • 本地套接字(又名 Unix 域套接字 en.wikipedia.org/wiki/Unix_domain_socket)是 IPC(进程间通信 - 在同一台机器上运行的两个进程之间的通信路径)的众多可能性之一。它可以与共享内存相媲美。使用mysql -hlocalhost,客户端使用套接字。 mysql -h127.0.0.1 明确指示客户端使用 TCP/IP。 Local Socket 更高效,因为它们绕过了网络层。
            • 通过绑定地址修复救了我!
            猜你喜欢
            • 2018-10-06
            • 1970-01-01
            • 2014-03-21
            • 2014-09-17
            • 1970-01-01
            • 2021-02-15
            • 2016-02-04
            相关资源
            最近更新 更多