SSH 隧道 - 穷人的 VPN
“如果我们看到隧道尽头的光,那是迎面而来的火车的灯光” ~ 罗伯特·洛威尔。 哦,是的,又一句名言。 这篇文章是关于 SSH 隧道的,或者我喜欢称之为“穷人 VPN”。 与系统管理员普遍的看法相反,SSH 隧道对于技术人员和家庭用户来说实际上都非常有价值。 我之所以说与普遍看法相反,是因为“反向隧道”和通过 SSH 隧道传输 http 流量可以绕过防火墙和内容过滤器。 但本文并非关于如何违反您的公司互联网使用政策,而是关于如何创建 SSH 隧道,让您的生活更轻松一点。
为什么选择 SSH 隧道而不是 VPN? 嗯,实际上我在家两者都用。 如果您关注过我在 jaysonbroughton.com 上的任何帖子,我使用带有 OpenVPN 的 3 因素身份验证(用户名、证书和一次性密码)。 但是,如果我想通过我的 Android 或一台我没有管理权限的计算机(我的自定义便携式 OpenVPN 客户端所需的权限)检查我的服务器之一,或者甚至通过 ssh 隧道传输 vnc 以解决我的另一半的 Linux 笔记本电脑上的问题,那么 SSH 是我使用 VPN 的备用方案。
我今天在这里要介绍的只是您的基础知识:如何创建隧道、语法的含义、反向隧道的示例以及为什么要使用每种隧道。 我将简要介绍 ssh_config,但关于自定义 ssh_config 的更深入的文章将在稍后发布。
所以一如既往,是时候摒弃不必要的麻烦了。 我在虚拟环境中使用 Debian,所以您的结果可能会有所不同。 在本例中,我使用 OpenSSH_5.3p1 作为服务器,并混合使用 OpenSSH 5.X ssh 客户端作为我的示例。 在我深入隧道之前,我要说一句:如果您觉得需要通过 http 或反向 SSH 隧道使用 SSH 隧道来绕过您的公司防火墙,请确保您没有违反贵公司的《互联网可接受使用政策》。 这是不言而喻的,当您的系统管理员发现您正在绕过内容过滤器或设置反向隧道以便隧道返回到公司服务器时,他们会追捕您并将您干掉。 作为一名系统管理员,我非常乐意找到这样的人。 至少与您的网络/系统管理员核实,以免他们措手不及。 LinuxJournal.com 和我本人不对您公然违反公司政策的行为负责 :-) 话虽如此,让我们玩得开心吧?
创建 SSH 隧道实际上非常容易。 弄清楚在学习如何创建隧道后如何使用它可能会稍微困难一些。 因此,在我们深入了解创建隧道的细节之前,我将给您一些用例,让您开动脑筋。 在有孩子之前以及之前在 IT 部门工作时,我经常出差。 当我出差时,我最终会住在最奇怪的酒店房间(你知道的那种),甚至还有更奇怪的无线接入点。 您真的想连接到酒店的 SSID 拼写错误的无线接入点吗? 还是机场似乎有很多开放的 WAP? 当我在外面时,我会通过 ssh 将我的 http 流量隧道传输到我的家用服务器上,通过我已 root 的安卓设备。 如果我在我的笔记本电脑/上网本上,我会打开一个 ssh 隧道并通过 socks5 路由 http 流量,以便我的所有流量都通过 ssh 加密,然后再传回给我。 我不会信任一个开放的 WAP,就像我不会信任扔出去的东西一样。 那么任何其他明文传输的东西呢? 当我去的某些地方阻止出站 SMTP 时,我会在我的计算机上将 SMTP 流量隧道传输回家里。 pop3 也是如此(我最近已将其更改为 imap-s)。 SSH 隧道的其他示例包括通过 SSH 隧道传输的 X11 应用程序和 VNC 会话。 我之前提到过的一件事是反向隧道,它是……嗯,你猜对了,隧道的反向。 在这种情况下,您从位于防火墙后且没有 SSH 服务器的服务器创建到 SSH 服务器的隧道。 然后,当您登录到该 SSH 服务器时,您可以重新建立连接。 你说这有什么好处? 好吧,如果您的公司 VPN 出现故障,或者需要仅限 Windows 的 VPN 客户端,但您真的不想把笔记本电脑拖回家来检查您回家后正在运行的进程,您可以进行反向隧道。 在这种情况下,您将建立从服务器 X 到您家用计算机的连接。 一旦您回到家,您将重新建立与服务器 X 的连接,从而绕过防火墙/VPN 并检查该进程,而无需建立 VPN 连接。 我很少这样做,因为我觉得这是不祥之兆,绕过我防火墙和 VPN 上设置的所有规则通常是最后的手段。
这就是 SSH 隧道的示例,现在让我们向您展示如何“完成它”。
在我们过于沉迷于客户端之前,需要在 sshd.config 的服务器端编辑一些内容。 在 /etc/ssh/sshd_config 中,我倾向于进行以下更改。 在您过于沉迷之前,请制作 /etc/ssh/sshd_config 原始文件的副本,以便您在出现严重错误时可以参考。 cp /etc/ssh/sshd_config /etc/ssh/sshd_config.orig
# Force SSH Protocol 2
Protocol 2
#Turn on Privileged Separation for security
UsePrivilegeSeparation yes
#Deny root login
PermitRootLogin no
#Do not allow empty passwords
PermitEmptyPasswords no
# Forward my X Sessions
X11Forwarding yes
X11DisplayOffset 10
# I hate Motd displays
PrintMotd no
# It's alliivee
TCPKeepAlive yes
不要忘记,如果您对 sshd_config 文件进行了任何更改,您需要重新启动 sshd 服务才能进行必要的更改。
好的,让我们来了解一下开关。 不,不,不是您“爸爸让您从树枝上拉下来的开关,当您打碎妈妈最喜欢的花瓶时”,而是 SSH 开关。
典型的 SSH 隧道(不包括隧道 X)如下所示
ssh -N -p 22 bob@mylinuxserver.xxx -L 2110:localhost:110
- 其中
- -N
- = 不执行远程命令
- -p 22
- = 外部 SSH 端口 22。我倾向于使用其他外部 SSH 端口来防止脚本小子攻击我的家用 SSH 服务器
- bob@mylinuxserver.xxx
- = 用户名@主机名(或 IP 地址)
- -L 2110/localhost/110
- = 绑定信息。 分解如下:客户端端口:主机名:主机端口 - 在此示例中,您将服务器上的 POP3 绑定到您的 localhost 端口 2110
那么来一些例子怎么样?
通过 SSH 转发 pop3 和 smtp
ssh -N -p 2022 bob@mylinuxserver.xxx -L 2110:localhost:110 -L 2025:localhost:25
通过 SSH 转发 google Talk
(-g 允许远程主机连接到本地转发端口)
ssh -g -p 2022 -N bob@mylinuxserver.xxx 5223:talk.google.com:5223
基本上,任何以明文形式发送的内容都可以通过 SSH 隧道进行保护。 建立隧道后,在客户端,您需要将主机名配置为 localhost,并将端口配置为您的“客户端端口”,无论是 2110、2020、5223 还是您选择转发的任何其他端口。
加密您的 HTTP 流量这是另一个不言而喻的。 如果您为一家有“IT 可接受使用政策”的公司工作,请在执行此操作之前进行检查。 这是我在出差或在我不信任 wifi 的地方时使用的。 在安卓设备上,我将使用我的 SSHTunnel 应用程序,但如果我在我的笔记本电脑上,我将使用以下 SSH 命令
ssh -D 5222 bob@mylinuxserver.xxx -N
建立连接后,然后将您选择的浏览器(或任何允许代理的应用程序)设置为 localhost:5222。 这将创建一个动态端口转发,并将所有应用程序流量隧道传输到您的 SSH 服务器,从而加密您的数据并绕过内容过滤器。
隧道传输 X 和 VNC 会话还记得您何时将“X11Forwarding yes”添加到您的 sshd_config 中吗? 这就是隧道传输 X 的用武之地。
ssh -X -p 2022 bob@mylinuxserver.xxx
您猜对了,-X 隧道传输 X。 但请记住,这将隧道传输来自您的远程计算机到运行 Linux 的客户端计算机的 X 应用程序。 如果您发现自己碰巧在使用 Microsoft Windows 机器并且想要隧道传输,只需在您的访客操作系统上安装 Cygwin/X (http://x.cygwin.com/)。 我个人没有尝试过,但据我了解,它为您提供了一个 X 窗口系统,该系统应该允许您在 Windows 中运行您的远程 X 应用程序。
在隧道传输 VNC 会话时,您必须小心。 如果您要隧道传输的客户端在例如 5900 上运行 vnc 服务器,请确保您不要决定将您的本地转发端口设置为 5900,否则您只会连接回自己。 通过 VNC 连接与任何其他服务一样简单直接
ssh -p 2022 bob@mylinuxserver.xxx -L 5900:localhost:5900
在此示例中,您以用户 bob 的身份连接到 mylinuxserver.com 的 ssh 外部端口 2022。 您的本地转发端口是 5900,您要转发的端口是 mylinxuserver.com 的 5900 vnc。 设置转发后,您可以打开您选择的 vnc 客户端并键入:localhost:0,此时您应该通过 vnc 连接到您的远程桌面。 如果您使用 5901,则它将是 localhost:1,依此类推。
反向 SSH 隧道哦,是的,现在是我最喜欢的 SSH 隧道部分。 当然,从 SSH 后面访问服务很好,通过加密的 SSH 隧道隧道传输您的 Web 流量也很好。 但真正的惊喜来自于您可以反转隧道。 正如我之前概述的那样,反向隧道是指您位于没有 SSH 服务器的防火墙后面,但需要在稍后(无论是几分钟/几小时/几天后)访问它,但不想或无法 VPN 连接。 您将从该计算机连接到您的 SSH 服务器,然后通过连接到该开放连接来反转隧道。 我用它来做什么? 有时针对服务器,甚至与朋友和家人一起通过 SSH 隧道进行反向 VNC 会话。 在这种情况下,他们执行一个 putty 保存的会话,该会话以特定用户的身份登录到我的 ssh 服务器,但没有任何权限。 建立隧道后,我可以 vnc 连接到他们的计算机,以便远程连接到他们。 不再需要让他们设置防火墙,或弄清楚 log-me-in 或任何其他网站。
创建反向 SSH 隧道的步骤如下
- 从客户端计算机:
ssh -R 远程端口:localhost:22 用户名@服务器名
例如:ssh -R 2048:localhost:22 bob@mylinuxserver.xxx
- 从服务器端(重新建立隧道):
ssh -p 2048 localhost
就这样,一个反向隧道就完成了。 耶!

对于您这些视觉学习者来说,daddoo 和 nerdboy4200 来自 #linuxjournal 聚在一起,并使用 mscgen (http://www.mcternan.me.uk/mscgen/) 制作了一个消息序列图。 是的,它是开源的,而且非常棒。 我尝试创建本文的 mscgen 图表,但 daddoo 和 nerdboy 在短短几个小时内完成的工作让我的小图像相形见绌。
结论这就是 SSH 隧道的入门指南。 请记住,这只是一个入门指南,您可以对隧道执行的操作仅受您的想象力限制。 稍后我将介绍如何在客户端设置 ssh_config,以便我上面描述的所有这些设置都可以作为客户端 ssh 上的单独设置保存。 但那是另一篇文章的内容了。