利用ssh反向代理和autossh实现从外网连接内网服务器

回复
jvip_chen
帖子: 76
注册时间: 2019年 1月 5日 13:36 星期六

利用ssh反向代理和autossh实现从外网连接内网服务器

帖子 jvip_chen » 2019年 3月 28日 17:52 星期四

利用ssh反向代理和autossh实现从外网连接内网服务器
前言
由于近期放假回家,实验室有一台工作用的服务器A常年需要维护,由于服务器A位于实验室的内网,所以无法用家里的主机C访问到。这时能不能有一个办法可以使得通过外网连接到内网的服务器呢?答案是有的,不过这里需要一个条件:有一台能够访问的位于公网(地址非私有地址和保留地址)的服务器B。

一、准备条件

代码: 全选

机器	IP	用户名	主机名	备注
A	10.39.27.128	root	netlab	位于内网的目标服务器
B	123.123.123.123	root	VAliCloud	位于公网的服务器,充当桥梁的作用
C	192.168.0.101	*	*	家里的一台Windows机器
注:123.123.123.123只是随便举例的一个公网地址,请勿攻击他人服务器.

二、方案
通俗地说:在机器A上面做到机器B上的反向代理;然后在机器B上做正向代理供机器C访问机器A.

1. 前提
机器A和机器B上面安装好ssh客户端和服务器,机器C上安装好ssh客户端(比如Xshell).

2. 需使用的ssh参数
​ 反向代理 ssh -fCNR

​ 正向代理 ssh -fCNL

代码: 全选

-f 后台执行ssh指令
-C 允许压缩数据
-N 不执行远程指令
-R 将远程主机(服务器)的某个端口转发到本地主机指定的端口
-L 将本地机(客户机)的某个端口转发到远端指定机器的指定端口
-p 指定远程主机的端口
3. 建立A到B的反向代理

代码: 全选

ssh -fCNR [B机器IP或省略]:[B机器端口]:[A机器的IP]:[A机器的sshd端口] [登录B机器的用户名@B机器的IP] -p [B机器的sshd端口]
在这里我使用B机器的4515端口,A机器的22号端口,具体在A机器上操作如下:

代码: 全选

[root@netlab ~]# ssh -fCNR 4515:localhost:22 -o ServerAliveInterval=60 root@123.123.123.123 -p 22
注:-o ServerAliveInterval=60表示服务器B每隔60秒发送一次数据给服务器A,以便ssh连接不会因为超时而断开连接.

然后输入root@123.123.123.123的密码回车确认.

检查是否成功建立了从A机器到B机器的反向代理,可以在A机器上面使用ps aux | grep ssh指令来查看,若有一条上述的ssh -fCNR 4515:localhost:22 -o ServerAliveInterval=60 root@123.123.123.123 -p 22命令进程,则说明反向连接建立成功。我们还可以在B机器上面使用netstat -antpul | grep '127.0.0.1:4515'指令来进一步确认从机器A到机器B的反向连接是否建立成功,若成功则输入该指令会有相应的输出,否则没有输出.

成功建立A机器到B机器的反向代理之后,在B机器上输入如下命令,即可成功地从外网B机器上ssh到内网的A机器上:

代码: 全选

[root@VAliCloud ~]# ssh -p 4515 登陆A机器的用户名@localhost
4. 建立B到A的正向代理
其实按照上面的一步,成功建立A到B的反向代理之后,便可从机器B上面ssh到机器A。但是如果外网的某个小伙伴也想ssh到机器A,我们总不能先让他登录到我们的公网服务器B之后,再从机器B上面ssh到机器A吧。这个时候我们就需要在机器B上面建立到机器A的正向代理,用来做转发,以便其他人(比如机器C)可以直接ssh到机器A。

B到A正向代理

代码: 全选

ssh -fCNL [*或省略]:[A机器端口]:[B机器的IP]:[B机器端口] [登录B机器的用户名@B机器的IP] -p [B机器的sshd端口]
具体在B机器上面输入如下指令:

代码: 全选

[root@VAliCloud ~]# ssh -fCNL *:4514:localhost:4515 -o ServerAliveInterval=60 root@localhost -p 22
说明:这里的B机器的4515端口和上面一步中的B机器的端口是一致的,端口4514既是A机器的端口又是B机器的端口。在此4514端口为本地转发端口(既代表A的端口也代表B的端口),用于和外网进行通信,以将任何其他主机发送至B机器的4514端口的数据转发到4515这个端口,实现了可以从任意机器访问A机器的功能。这里,*号表示可以接受任何IP的访问。

检查是否成功建立B到A的正向代理,可以在A机器或者B机器上面输入netstat -antpul | grep ':4514'来看是否有相应的输出,若有则建立成功,否则失败.

5. 用机器C连接机器A
至此我们都配置好了AB机器,那么我们就可以从任意的一台电脑登录到内网的A机器里面去啦。用家里的C机器在Xshell中配置如下指令,便可ssh到机器A:

代码: 全选

ssh -p 4514   A机器上面的某个用户@123.123.123.123
6. 用autossh建立稳定的反向代理
不幸的是这种ssh反向连接会因为超时或NAT地址映射的转变而关闭,如果关闭了那从外网连通内网的通道就无法维持了,为此我们需要另外的方法来提供稳定的ssh反向代理隧道。

ssh每次重连都需要键入密码,故在此首先设置从机器A免密码登录到机器B

设置ssh免密码登录的方式:http://blog.csdn.net/u012843189/article ... s/79492178

用autossh建立稳定隧道

centos7上默认没有安装autossh,所以在机器A上使用如下命令安装

代码: 全选

[root@netlab ~]# yum install autossh
autossh与ssh的功能基本上是相同的,不同的是在隧道断开的时候,autossh会自动重新连接而ssh不会。具体的autossh的指令为:

代码: 全选

[root@netlab ~]# autossh -M 4516  -fCNR 4515:localhost:22 -o ServerAliveInterval=60 root@123.123.123.123 -p 22
autossh的参数与ssh的参数基本上是一致的,另外不同的是我们需要指出的-M参数,这个参数指定一个端口,这个端口用于内网的A机器和公网的B机器互相发送状态信息的,如果反向隧道不正常,则A会重新建立与B的反向连接。

我们可以在机器A或机器B上面用如下命令来检查autossh建立的反向代理是否成功:

代码: 全选

[root@netlab ~]# netstat -antpul | grep ':4516'
若建立成功则有相应的输出,否则无输出.

回复