我们定制并支持客户托管在不同网络托管商的托管服务器上的标准网络应用程序。通常,该应用程序由 PHP 网络应用程序和数据库(主要是 MySQL)组成。
对于我们的客户,我们希望提供一项超出网络托管商提供的备份服务(通常保留时间为四周)。我们希望备份网络应用程序(没有问题)和数据库(有问题)。
其中一个网络托管商的设置阻止用户使用 访问 MySQL 数据库mysql.sock
。相反,他们为托管服务器本身设置了一个单独的名称(如 user123.mydatabaseserver.com)。只有使用 参数才能连接到数据库-h
,mysql
如下所示:
mysql -u mydbuser -p -h user123.mydatabaseserver.com
现在,我们通常使用连接到实时托管服务器的 SSH 隧道从备份服务器备份数据库,并将 MySQL 端口转发到备份服务器,然后通过隧道连接到备份服务器上的数据库并mysqldump
使用转发的端口运行。但是,由于强制主机名参数,在这种情况下这是不可能的。
我们知道我们可以连接到托管服务器,在那里转储数据库,然后使用scp
或其他方法复制生成的备份文件,但我想看看我是否没有遗漏一些东西,使得我们不使用存储和/或计算实时托管服务器进行备份的时间。
有没有仅使用端口转发的解决方案?
编辑 1:试图让问题更清晰
服务器A(备份系统) 服务器B(应用程序服务器) 服务器C(数据库服务器)
服务器A应该在服务器C上备份数据库,但是MySQL的访问权限只允许服务器B连接到服务器C并访问数据库。
在这种特定情况下,服务器 B 和服务器 C 具有相同的 IP 地址,但似乎主机托管者禁用通过套接字访问 MySQL,并且只允许 TCP/IP 连接。
同时,我有了链接 SSH 端口转发的想法:
将服务器 B 上的端口 22222 绑定到服务器 C 上的端口 3306,然后将服务器 A 上的端口 44014 绑定到服务器 B 上的端口 22222。但是,尝试从服务器 B 通过 SSH 连接到服务器 C 时会出现错误消息:host address xxx.xx.xxx.xx not allowed.
答案1
您不需要 SSH 隧道从 B 到 C,因为 B 上的 webapp 使用常规套接字连接到 C,对吗?
在服务器 A 上,您应该像这样调用 SSH:
ssh -L44014:serverc:3306 user@serverb
这会在 A 和 B 之间建立一个 SSH 隧道。当在服务器 A 上运行的备份进程连接到 localhost:44014 时,该隧道将导致服务器 B 上的 sshd 进程连接到服务器 C 上的端口 3306。从服务器 C 的角度来看,该连接似乎来自服务器 b 上的某个随机客户端端口。
如果您想在脚本中使用它,您也可以传递选项-N
以避免生成 shell,只需执行端口转发即可。因此,您可以在后台运行该命令,并在不再需要隧道时将其终止:
ssh -NL44014:serverc:3306 user@serverb &
TUNNEL_PID=$!
# do the backup on localhost:44014
kill $TUNNEL_PID
如果服务器 B 的管理员已禁用本地端口转发,您可以使用它socat
来模拟该行为,但这有点复杂。在这里,我们在本地生成一个 socat 以使数据通过 ssh 的 stdio,并生成一个远程 socat 以将其重定向到适当的套接字。要使其正常工作,您必须已经使 ssh 无密码登录正常工作:
socat TCP-LISTEN:44014 EXEC:"ssh user@serverb socat STDIO TCP:serverc:3306"