【发布时间】:2012-03-15 21:01:00
【问题描述】:
我按照这篇文章的描述打开了一个 ssh 隧道:Zend_Db: How to connect to a MySQL database over SSH tunnel?
但现在我不知道我到底做了什么。此命令会影响服务器上的任何内容吗? 以及如何关闭这个隧道,因为现在我无法正常使用我的本地mysql。
我使用 OSX Lion,服务器在 Ubuntu 11.10 上运行。
【问题讨论】:
我按照这篇文章的描述打开了一个 ssh 隧道:Zend_Db: How to connect to a MySQL database over SSH tunnel?
但现在我不知道我到底做了什么。此命令会影响服务器上的任何内容吗? 以及如何关闭这个隧道,因为现在我无法正常使用我的本地mysql。
我使用 OSX Lion,服务器在 Ubuntu 11.10 上运行。
【问题讨论】:
假设您运行此命令:ssh -f user@mysql-server.com -L 3306:mysql-server.com:3306 -N,如您链接的帖子中所述。
命令分解:
ssh:这很不言自明。调用ssh。 -f:(来自man ssh页面)
在命令执行之前请求 ssh 进入后台。 如果 ssh 要求输入密码或 密码短语,但用户希望它在后台。
基本上,一旦您输入任何密码以建立连接,就将ssh 发送到后台;它通过localhost 将shell 提示返回给您,而不是让您登录到remote-host。
user@mysql-server.com:你想登录的远程服务器。 -L 3306:mysql-server.com:3306:这很有趣。 -L(来自man ssh页面):
[绑定地址:]端口:主机:主机端口 指定本地(客户端)主机上的给定端口是 转发到远程端的给定主机和端口。
所以-L 3306:mysql-server.com:3306将本地端口3306绑定到远程端口3306在主机mysql-server.com上。
当您连接到本地 端口3306 时,连接会通过安全通道转发到mysql-server.com。 远程主机,mysql-server.com 然后连接到端口3306 上的mysql-server.com。
-N:不执行命令。这对于“仅转发端口”(引用手册页)很有用。
这个命令会影响服务器上的任何东西吗?
是的,它在 localhost 和 mysql-server.com 之间的端口 3306 上建立了连接。
我该如何关闭这条隧道...
如果您使用过-f,您会注意到您打开的ssh 进程进入了后台。关闭它的更好方法是运行ps aux | grep 3306,找到ssh -f ... -L 3306:mysql-server.com:3306 -N 和kill <pid> 的pid。 (或者也许kill -9 <pid>;我忘记了kill是否有效)。这具有不杀死所有其他ssh 连接的美妙好处;如果您有多个,重新建立它们可能会有点……痛苦。
...因为现在我无法正常使用本地 mysql。
这是因为您已经有效地“捕获”了 local mysql 进程并将任何尝试连接到它的流量转发到 remote @987654354 @ 过程。 更好的解决方案是在端口转发中不使用本地端口 3306。使用未使用的东西,例如 33060。(数字越大通常使用较少;端口转发这样的组合很常见:“2525->25”、“8080->80”、“33060->3306”或类似。使记忆稍微容易一些)。
所以,如果您使用ssh -f user@mysql-server.com -L 33060:mysql-server.com:3306 -N,那么您需要将 Zend connect-to-mysql 函数指向端口 33060 上的 localhost,这将连接到端口 3306 上的 mysql-server.com。您显然仍然可以在端口3306 上连接到localhost,因此您仍然可以使用本地mysql 服务器。
【讨论】:
kill 不需要-9,考虑到该过程仍在正常工作;-)
这将终止您从终端打开的所有 ssh 会话。
sudo killall ssh
【讨论】:
killall ssh 是一个相当鲁莽的命令。我建议搜索您的进程列表(即上面@simont 建议的ps aux | grep ssh)以发现您的 ssh 隧道进程的特定进程 ID。然后你可以专门杀死那个pid。
注意:添加为答案,因为 cmets 不支持代码块。
在我看来,最好不要使用-f,而是像平常一样使用& 将进程作为背景。这将为您提供您需要杀死的确切 pid:
ssh -N -L1234:other:1234 server &
pid=$!
echo "waiting a few seconds to establish tunnel..."
sleep 5
... do yer stuff... launch mysql workbench whatever
echo "killing ssh tunnel $pid"
kill $pid
或者更好的是,只需将其创建为包装脚本:
# backend-tunnel <your cmd line, possibly 'bash'>
ssh -N -L1234:other:1234 server &
pid=$!
echo "waiting a few seconds to establish tunnel..."
sleep 5
"$@"
echo "killing ssh tunnel $pid"
kill $pid
backend-tunnel mysql-workbench
backend-tunnel bash
【讨论】:
-f 允许ssh 会话在终端会话关闭时继续,这与推送到后台不同。使用ps aux | grep ssh | grep <LOCAL-PORT> 获取pid 非常简单。
-f 还具有提示本地用户输入登录密码的优点。如果您使用&,除非用户将进程置于前台(例如使用fg),否则用户不会看到该提示。