我依靠tunnel.sh
其他人编写的以下脚本来保持 ssh 隧道处于活动状态:
#!/bin/bash
export SSH_HOST=tim@server
if [ ! -f /tmp/.tunnel ]
then
echo "Creat SSH tunnel"
ssh -f -D 9999 $SSH_HOST "if [ -f ~/.tunnel ]; then rm ~/.tunnel; fi; while [ ! -f ~/.tunnel ]; do echo > /dev/null; done" &
touch /tmp/.tunnel
else
echo "Close SSH tunnel"
ssh $SSH_HOST "touch ~/.tunnel"
rm /tmp/.tunnel
fi
exit
要创建持久的 ssh 隧道,我只需发出tunnel.sh
.在我再次发出之前,隧道不会关闭tunnel.sh
。
我想知道如何验证 ssh 隧道是否确实创建成功?
我对隧道的主要用途是打印文档到与服务器在同一局域网中的一些打印机,而这些打印机只能从局域网内访问。创建隧道后,现在打印不会报告任何问题,但由于我不在现场,我无法检查文档是否确实已打印。
我想既然我现在在 LAN 中(多亏了隧道),我的外部 IP 应该与服务器的相同。但实际上它们并不相同(我通过 发现它们wget -q -O - checkip.dyndns.org|sed -e 's/.*Current IP Address: //' -e 's/<.*$//'
)。我想知道为什么?当我在隧道处于活动状态的情况下连接到互联网上的某个网站时,由于我和服务器之间的隧道,服务器是否不是我和连接中的互联网网站之间的中点?
答案1
这比需要的要复杂得多:-)
启动隧道:
ssh -f -N -D 9999 -M -S /tmp/ssh_tunnel_%h.sock -o ExitOnForwardFailure=yes $SSH_HOST && \
echo "ssh tunnel started successfully" || \
echo "ssh tunnel failed to start"
停止隧道:
ssh -S /tmp/ssh_tunnel_%h.sock -O exit $SSH_HOST
。
这就是您需要做的全部。如果您想了解详细信息,请跳过下面。
关于你的第二个问题,即知识产权问题。不,您的 IP 不会改变。您所做的就是通过远程主机创建 SOCKS 代理。除非您指定,否则您的系统不会自动使用此代理。
SSH 解释
启动隧道的参数:
-f
: 告诉 ssh 到后台本身。如果它启动成功,它只会将自己置于后台(与-o
下面的参数配合)。
-o ExitOnForwardFailure=yes
:如果 ssh 无法设置 SOCKS 代理,这将告诉 ssh 退出。
-N
: 不执行命令。我们只想建立隧道,而不是在远程主机上执行任何操作。
-D 9999
:您的 SOCKS 代理。
-M
:这是 -S 参数在这里起作用所必需的。
-S /tmp/ssh_tunnel_%h.sock
:这告诉它使用 /tmp/ssh_tunnel_HOSTNAME.sock 作为其控制套接字。该-M
选项告诉它 ssh 需要设置此套接字,而不是向已侦听该套接字的另一个 ssh 发出命令。在 ssh 运行后,您可以使用此套接字设置其他隧道。使用%h
远程主机的主机名作为文件名的一部分。
停止隧道的参数:
-S /tmp/ssh_tunnel_%h.sock
:这应该是显而易见的。然而,由于我们没有发出 -M,这意味着 ssh 应该连接到已经存在的套接字并告诉它要做什么,而不是自己做任何事情。
-O exit
: 这是 的一部分-S
。我们告诉监听套接字的 ssh 退出。
这里$SSH_HOST
仍然需要。即使您要指定绝对套接字路径,而不%h
在文件名中使用,ssh 仍然需要指定远程主机。这就是为什么我把 放在%h
论点中。如果 ssh 要请求主机,不妨使用它,并且它可以使事情井井有条。
答案2
这种类型的隧道不会更改您的 IP 地址信息。它所做的只是告诉您的计算机打开端口 9999,并通过 ssh 连接将该端口的连接转发到远程计算机 (tim@server)。测试连接是否已建立的最简单方法是远程登录到已创建转发的端口(在示例中为 9999):
$ telnet localhost 9999
正在尝试服务器...
已连接到服务器。
转义字符是“^]”。
如果您收到“已连接到服务器”。消息,这意味着您的隧道已启动。相反,如果您收到:“无法连接到远程主机:连接被拒绝”,则您的隧道未启动。
至于你的第二个问题,对于你的浏览器,你的浏览器不会使用隧道,除非你告诉它。在浏览器网络设置中,您可以配置代理设置,并将 localhost:9999 指定为socks5 代理,然后您的Web 连接应使用ssh 隧道并显示为来自服务器的IP 地址。
答案3
就我而言(Ubuntu 14.10 上的 Google Chrome),我的外部地址确实发生了变化,至少在浏览器内是这样。只需谷歌“我的 IP 地址是什么?”有和没有代理连接。
另外,设置代理后,尝试破坏隧道并查看是否仍然可以获得流量。当我这样做时,chrome 返回错误“无法连接到代理服务器”。
另一种方法:通过隧道连接到远程主机后,创建一个新的 ssh 会话并运行tcpdump -A dst port 80
.然后浏览到某个页面,您应该在终端中看到相关流量。
答案4
这是最好的解决方案:
#!/bin/bash
export SSH_HOST=
export SSH_PORT=
if ps -lef | grep ssh | grep $SSH_PORT
then
echo "Starting SSH tunnel"
ssh -f -N -D $SSH_PORT -M -S /tmp/ssh_tunnel_%h.sock -o ExitOnForwardFailure=yes $SSH_HOST && \
echo "ssh tunnel started successfully" || \
echo "ssh tunnel failed to start"
else
echo "Stopping SSH tunnel"
ssh -S /tmp/ssh_tunnel_%h.sock -O exit $SSH_HOST
fi
exit
它检查隧道是否正在运行并将其打开或关闭。