SSH隧道技术简介
首先看下图, 我们的办公电脑 在右上角, 通过公司带有防火墙功能的路由器接入互联网(当然还可能 有交换机什么的在中间连接着你和路由器, 但是在我们的问题中交换机并不起到什么关键性的作用), 或下脚的部分是一个服务器, 但是公司网络限制了登录, 右上角还有一台机器 , 是另一台可以直接办公内网登录的机器
这条通道可以用很多技术来建立 , 这里我们仅仅介绍如何使用SSH服务器来建立, 称为SSH隧道
- 情景1:
线路A –> B –> D 和 C –> D 是通的, 也就是笔记本可以直接登录d(172.1.2.3), 同时c(10.1.2.3)可以登录 到d(172.1.2.3), 但是A–>C和 D–>C不通, 因此我们可以利用一条已经连接好的C–>D方向的连接来完成 D–>C方向的访问. 通过机器 d建立一个通道 A –> B –> D –> C, 从而登录到c
解决办法是建立远程SSH隧道,
- 创建SSH反向隧道:
- 需要一台跳板服务器,这台服务器的SSH服务可通过公网直接访问
- 通过内网服务器执行SSH命令登录跳板服务器并形成反向隧道
- 使用SSH反向隧道:
- 在外网,SSH登录到跳板服务器
- 在跳板服务器,执行比如
ssh -p1222 localhost
,这里1222是反向隧道在跳板机的端口
与本地SSH一样,我们在建立远程SSH隧道之前要清楚下面几个参数:
- 需要访问内部机器的远程机器的IP地址(这里是123.123.123.123)
- 需要让远程机器能访问的内部机器的IP地址(这里因为是想把本机映射出去,因此IP是127.0.0.1)
- 需要让远程机器能访问的内部机器的端口号(端口:22)
在清楚了上面的参数后,我们在c机器上使用下面的命令来建立一个远程SSH隧道
1.
ssh
-N -f -R 1222:localhost:22 root@172.1.2.3
现在,在IP是172.1.2.3
的d机器上我们用下面的命令就可以登陆IP是10.1.2.3的c机器了。
1.
ssh
-p 1222 localhost
- -N 告诉SSH客户端,这个连接不需要执行任何命令。仅仅做端口转发
- -f 告诉SSH客户端在后台运行
对于参数-R。该参数的三个部分的含义分别是:
- 远程机器使用的端口(
1222
) - 需要映射的内部机器的IP地址(
localhost
) - 需要映射的内部机器的端口(22)
例如:-R X:Y:Z 就是把我们内部的Y机器的Z端口映射到远程机器的X端口上。
上面这种做法有一个问题,就是这个后台运行的SSH反向隧道,可能会失效,或者在内网服务器重启后不再有效。
解决办法是使用autossh,自动后台执行ssh命令。
具体做法是:
- 安装autossh
- 设置免密码在内网服务器登录跳板服务器,因为脚本执行不能通过交互方式输入密码了
- 通过systemd服务脚本,让autossh自动后台执行
安装autossh#
在ubuntu server执行命令:
1 |
sudo apt-get install autossh |
设置免密码登录#
设置从内网服务器到跳板服务器的免密码登录。
可参照Initial Server Setup with Ubuntu 16.04
基本是两步:
- 在内网服务器上创建key
- 使用
ssh-copy-id
将key传到跳板服务器上
创建autossh脚本#
在要被登录的目标机器上创建文件~/autossh.service
:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[Unit] Description=AutoSSH service for a reverse tunnel from some.example.com to localhost After=network-online.target [Service] User=sean #注意更改成自己的用户名 Environment="AUTOSSH_GATETIME=0" ExecStart=/usr/bin/autossh -M 0 -N -T -q -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -R 1222:localhost:22 sean@172.x.x.x Restart=always RestartSec=60 [Install] WantedBy=multi-user.target |
其中:
- 1222是指定的在跳板服务器上的隧道的端口号(自定义,可以是别的),即如想在跳板机上:
ssh -p1222 localhost
连接到隧道的端口 root@172.x.x.x
,root,指代跳板服务器的用户名,172.x.x.x,指代跳板服务器ip/域名- 如果跳板机的ssh登录端口不是默认22, 则可在后面再加上端口:
- /usr/bin/autossh -M 0 -N -T -q -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -R 1222:localhost:4728 sean@172.x.x.x -p 22122
部署autossh脚本#
转移文件:
1 2 3 4 |
sudo mv ~/autossh.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable autossh.service sudo systemctl start autossh.service |
使用反向SSH隧道#
首先,要ssh登录到跳板服务器上。
然后,在跳板服务器执行:
1 |
ssh -p1222 localhost |
另外, 利用ssh隧道, 还可以实现上网功能:
需求: 如何让内网机器通过ssh tunnel 代理http请求,访问internet?
1 2 3 4 5 6 7 |
<span class="token operator">+</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">+</span> <span class="token operator">+</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">-</span><span class="token operator">+</span> <span class="token operator">|</span> <span class="token operator">|</span><span class="token operator">+</span><span class="token operator">--</span><span class="token operator">--</span><span class="token constant">SSH</span><span class="token operator">+</span><span class="token operator">--</span><span class="token operator">></span><span class="token operator">|</span> <span class="token operator">|</span> <span class="token operator">|</span> <span class="token constant">A</span> <span class="token operator">|</span> <span class="token operator">|</span> <span class="token constant">B</span> <span class="token operator">|</span> <span class="token operator">|</span><span class="token operator">+</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">+</span><span class="token operator">|</span> <span class="token operator">|</span> <span class="token operator">|</span> <span class="token constant">Internet</span> <span class="token operator"><</span><span class="token operator">-</span><span class="token operator">++</span><span class="token operator">-</span><span class="token operator">+</span><span class="token constant">PROXY</span><span class="token operator"><</span><span class="token operator">++</span><span class="token operator"><</span><span class="token constant">SSH</span> <span class="token constant">Tunnel</span><span class="token operator">--</span><span class="token operator">+</span> <span class="token operator">|</span> <span class="token operator">|</span><span class="token operator">+</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">+</span><span class="token operator">|</span> <span class="token operator">|</span> <span class="token operator">|</span> <span class="token operator">+</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">+</span> <span class="token operator">+</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">-</span><span class="token operator">+</span> |
方法:
- 在机器A上运行
ssh -R 1082:localhost:1083 user@HostB
此时,B机器会监听1082端口, 所有对B机器1082端口的访问都会转发到A机器的1083端口 - 在机器A上运行
./gost -L=http://:1083
此时, gost http 代理将在A机器的1083端口提供服务 - 在机器B上,配置好http代理地址为
export http_proxy=http://127.0.0.1:1082
此时,系统会讲http请求转发给 B机器的1082端口
由于第一步的操作,相当于请求转给A机器的1083端口
0 Comments