type
status
date
slug
summary
tags
category
icon
password
Property
Dec 7, 2024 09:05 AM
URL
Notion AI 总结:
本文详细介绍了如何使用 SSH 隧道技术解决服务器无法上网的问题。文章首先阐述了在企业内网或学校集群中常见的网络访问限制问题,然后通过类比"快递员"的方式解释了 SSH 隧道的工作原理。文章对比了 HTTP、HTTPS 和 SOCKS 三种代理类型的特点和应用场景,并重点说明了为什么 SOCKS 代理最适合计算化学领域的需求。最后,文章提供了详细的实操步骤,包括 IP 获取、免密登录配置、SSH 隧道搭建和网络连接验证,为读者提供了完整的解决方案。
1. 问题
如图所示,服务器 A 可以进行上网,而服务器 A 和服务器 B 通过 VPN 或同一个内网中,服务器 B 是没办法上网的,这种情况很常见,比如公司内网,比如学校的集群中。
现在很多时候很多资料都是在互联网上的,如果下来然后再上传到服务器 B 里面这种做法固然可以,但是有些问题:
- 每次都要手动上传下载非常麻烦
- 涉及到 API 交互什么的就搞不了了,比如上传 GitHub 项目什么的
那么有什么好的解决方案呢?这就要用到 SSH 隧道技术了。通过 SSH 隧道,我们可以让服务器 B 借助服务器 A 的网络来实现上网。
2. 技术原理
要理解 SSH 隧道技术的原理,我们先来看一个简单的场景:
假设你在服务器 B 上想访问 GitHub。正常情况下,由于服务器 B 无法上网,这个请求会直接失败。但当我们建立了 SSH 隧道后,整个过程是这样的:
- 你在服务器 B 上发起访问 GitHub 的请求,这个请求会首先发送到本地的 1080 端口(我们设置的 SOCKS 代理端口)
- SSH 隧道会将这个请求通过加密通道转发给服务器 A
- 服务器 A 收到请求后,会使用自己的网络连接去访问 GitHub
- GitHub 返回响应给服务器 A
- 服务器 A 再通过 SSH 隧道将响应转发回服务器 B
其实说简单点就是你要和学校的某个人送东西,你又进不去学校,这个时候,你就可以吧东西给快递员,然后快递员是可以进入学校的,这个时候东西就能送到了。
我们虽然建立了 ssh 隧道,但这个"快递员"也分几种类型,有的只送普通信件,有的专门送加密包裹,有的什么都能送。
下面我们就需要讲到三种类型的代理
代理类型 | 快递员的作用 | 是否加密 | 适用场景 |
HTTP | 只送普通信,信的内容是透明的 | 否 | 浏览普通网页 |
HTTPS | 送加密的信封,只有目标收信人能打开 | 是 | 安全访问加密网页 |
SOCKS | 送信、包裹甚至奇怪的物品(啥都能送) | 取决于寄件人是否加密 | 游戏加速、文件传输等复杂场景 |
类型 | 比喻(现实生活) | 网络内容示例 | 适用场景 |
信封 | 网页浏览,轻便的信件 | 打开网页、发送表单、浏览图片 | 浏览器访问网站,如淘宝、知乎 |
包裹 | 文件传输,大体积的包裹 | 上传照片、下载电影 | 文件上传、下载,如百度网盘 |
数据包 | 游戏数据,小而实时的数据 | 游戏操作、语音通话 | 在线游戏、视频会议 |
按照上面的说明,SOCKS 代理什么都能搞,那么不全部 SOCKS 代理呢?
原因在于,虽然 SOCKS 什么数据都能传,但是对于网页浏览这些,优化不好,如果涉及到高并发什么的那么可能就会很卡,也就是说如果对延时什么的有需求,那么就不好使了,于此同时 SOCKS 没有加密,别人可以随时看到你的数据,不安全,一些老的设备配置配置 SOCKS 可能比较麻烦。
计算化学领域的需求,SOCKS 的缺点基本无关痛痒,反而更方便:
- 延时不重要
我们的计算任务动辄几个小时甚至几天,数据传输的实时性几乎没有要求,延迟完全可以接受。
- 安全性要求低
计算化学的中间数据和结果文件大多是科学数据,即使被截获也无所谓。没有隐私信息,不必担心安全问题。
- 功能强大,支持多种协议
SOCKS 代理可以处理复杂的场景,比如通过 FTP 上传输入文件、用 HTTP 下载依赖库、用 SSH 查看任务状态等,通用性远胜 HTTP/HTTPS 代理。
3. 实操
3.1 获取 IP
我们可以通过
ifconfig
来查看 ip,如下图所示,如果不知道对方的 IP 是哪个,用 ping 命令检测就行了
可以ping 通就说明 ip 是对的(注意这里不要 ping 自己的本地 IP(127.0.0.1))
服务器 A (可以上网)
IP:101.5.255.118
用户名:ubuntu
服务器 B 的 IP(不能上网)
用户名:zhangdd
IP: 166.111.28.115
3.2 配置免密登录
假设服务器 A 的用户名是 ubuntu
隧道流向是:B -> A -> 外网。
即,B 需要通过 SSH 隧道连接到 A,然后由 A 作为代理访问外网。
免密要求:B -> A 必须配置免密登录,因为隧道是从 B 发起 SSH 连接到 A。
- 在 B 上生成 SSH 密钥
下面的红线部分回车就行了
公钥会保存到
~/.ssh/id_rsa.pub
,私钥保存到 ~/.ssh/id_rsa
- 将 B 的公钥复制到 A
需要注意的是如果你后期更换了机器,这里需要先清除原来的密钥
移除旧的主机密钥记录,允许重新接受目标主机的新密钥。
然后新开一个 ssh 终端,进行下面的测试
- 测试免密登录
3.3 搭建 ssh 隧道
- -D 1080:在 B 上本地监听 1080 端口,创建 SOCKS 代理。
- -f:让 SSH 在后台运行。
- -N:不执行任何命令,仅建立隧道。
隧道是否正常运行:用
ps aux | grep "ssh -D" | grep -v grep
查看 SSH 进程是否存在。3.4 上网验证
使用 socks5 代理进行百度的验证
如果你需要代理多个程序(比如
curl
、wget
、pip
等),可以一次性设置所有协议的代理:个人建议:这三个环境变量建议不要写入 .bashrc/.zshrc,需要的时候再临时设置就好
设置好之后,直接使用
就能正常访问了,不需要额外加代理参数
注意:ping 命令天生就不支持代理,别白费劲了~
4. 参考
- 作者:我心永恒
- 链接:https://wxyhgk.com/article/ssh-tunnel
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。