折腾Linux - 1.内网穿透

写在前面

本文只是记录自己在学习和做项目过程中,折腾的一些东西,并非专业,本人也是linux入门的小白,因为任务驱动,而产生了兴趣,遂开始整活。

而且将其记录下来,以后忘记怎么弄了,还可以找出来回顾温习一下。

如有错误或者我理解不深的地方,希望看管们指出来 :D

本小白今年9月也开始了烟酒生(雾)的生活,确实烟酒生和自己想象中的有些出入,有好也有坏。但我们实验室里竟然让我发现了个宝贝,那就是实验室的服务器。不过这个服务器的初衷是用来给学长们跑深度学习的,不过除了要毕业的学长,一般也很少有人用。

这么好的资源竟然没人用?!那不行,那我得整点活。刚开始的时候,基本上完全不太懂linux,也在慢慢看“字典书”(就是那种指令大全类型的,并未涉及到linux内核原理这些的书)。

以前自己搞了个阿里云服务器,用xshell整过一些东西,比如最基础的搭建个博客啊,部属个项目啊啥的。然后我试图用xshell徒手连实验室的服务器。

结果那必然是失败啊,根本ping不通啊。拍查了半天,原来我的电脑是连接的校园网,而实验室的服务器(下面简称服务器)在另外一个网络内,这怎么可能访问嘛。

查了很多资料,发现有两种种解决方法,分别是路由器端口映射和内网穿透。这就是本篇博客的内容了。

为什么两个内网下的设备无法连通?

解答这个问题,需要了解网络模型、公网内网

网络模型

OSI 七层网络模型由国际标准化组织进行制定,它是正统意义上的国际标准。但其实现过于复杂,且制定周期过长,在其整套标准推出之前,TCP/IP 模型已经在全球范围内被广泛使用,所以 TCP/IP 模型才是事实上的国际标准。TCP/IP 模型定义了应用层、传输层、网际层、网络接口层这四层网络结构,但并没有给出网络接口层的具体内容,因此在学习和开发中,通常将网络接口层替换为 OSI 七层模型中的数据链路层和物理层来进行理解。

网络接口层的知识就比较偏向底层硬件。我们平常的做的应用,基本上是在网际层IP以及传输层的基础上,进行连接,同时在应用层进行各种应用。

公网与内网

  1. 公有IP地址

一般称公网中的IP地址为公有地址。公有地址由Inter NIC(因特网信息中心)负责,这些IP地址分配给注册并向Inter NIC提出申请的组织机构。公有地址是全球唯一的,公网中不可能存在两个相同的IP地址

范围:除了私有地址以外的地址,都属于公有地址

  1. 私有IP地址

一般称内网(即局域网)中的IP地址为私有地址。私有地址是非注册地址,用于组织机构内部使用。私有地址的范围如下:

  • A类IP地址中:10.0.0.0–10.255.255.255
  • B类IP地址中:172.16.0.0–172.31.255.255
  • C类IP地址中:192.168.0.0–192.168.255.255

私有地址与公有地址不同,并不是由Internet分配的,是不允许出现在Internet中的,我们在公网中是看不到私有IP地址的,并且公有地址也不会使用上述的三类地址。所以,私有地址是不能直接与Internet连接的。

而如果想用私有地址与Internet连接来访问公网,那该怎么做?这就需要将私有IP地址转换成公网IP地址,与外部连接。所以,我们平时使用的路由器中会装有一个叫做 NAT(网络地址转换) 的软件,我们的路由器中会至少会有一个有效的公网IPNAT会将我们的私有地址转成路由器中的公网IP与外部Internet连接。而同样的,因为使用的是路由器中的公共的公网IP来连接Internet,所以这个内网中的PC在Internet中显示的都是路由器的公共IP,这样做不仅提供了一定程度的安全,也可以有效的减缓可用的IP地址空间的枯竭问题。

比较典型的例子就是,我们学校的校园网,就是一个很大的内网,我们在内网中连接wifi,并上网,实际上仍然通过的是 **NAT(网络地址转换)**转换为公网IP来建立连接。

解决疑惑

两个设备之间建立连接,相互传送数据,数据会被由多个协议进行封装,即 应用层 - 传输层 - 网络层 - 网络接口层。

我们的设备是连接了路由器的,路由器下的所有设备都连接在该路由器的子网下,简言之,我们的设备都躲在路由器后。

我们访问一个网站,或建立一个连接,最终都是以路由器的IP发送出去。

但因为我们的设备A是主动访问一个公网服务器,路由器在建立连接后,是可以根据我们主动的访问时,网络协议中的信息,而将公网服务器发回来的信息,正确地发送给我们的设备A。

可是如果另外一个设备B,想要主动地来访问我们的设备A,这个时候,设备B访问的是路由器的IP。而路由器其实也不明白,设备B到底是想和内网下哪一个设备进行连接,因为内网下的设备对外暴露出来的,都是路由器的IP。

解决方案

1.路由器端口映射

路由器端口映射,原理就是指定路由器的一个固定端口(比如6000),使所有访问路由器IP(121.40.XXX.XXX:6000)的数据或信息,都转发到指定设备A的指定端口(例如22端口,用于SSH)。

那么最终的效果就是我直接访问 121.40.XXX.XXX:6000,路由器知道是转发给设备A的22端口,那我就可以访问到内网中,设备A的22端口了。

但是设备A除了我设置好的22端口,其他端口仍然还是无法访问,如果想要访问另一个端口,需要在路由器的端口映射中加入响应的映射配置即可。

可惜的是,我们实验室服务器网络连接的路由器,我不知道管理密码 :( 。这种方案只能舍弃

2.内网穿透

搜索了一些关于内网穿透的工具,比如花生壳、frp以及很多专门做内网穿透的软件,最后发现,除了frp,其他基本上都是收费,就算有免费的,也基本上是半残废。

但是frp唯一一个要求就是你需要有个自己的云服务器,并且云服务器有公网IP。

这不,我正好有个阿里云学生机,虽然学生机啥都不行,但它便宜啊!而且还带公网IP,要什么自行车?!

frp的具体原理图如下:

下面就开始我们的配置

2.1 frp服务端安装配置

这里服务端,就是我们的阿里云服务器,使其作为frp的server端,接收client的连接

首先我们在终端依次输入下面的命令

1
2
3
4
# 获取github上frp打包好的release包
wget https://github.com/fatedier/frp/releases/download/v0.22.0/frp_0.22.0_linux_amd64.tar.gz
# 解压下载的.tar.gz压缩文件
tar -zxvf frp_0.22.0_linux_amd64.tar.gz

这里注意一点,由于服务器使用的是centos,因此一定要选的linux,其次amd64代表了设备的架构,一般都是amd64。如果选择错误的平台类型,自然下载下来的文件是无法运行的。

解压之后的文件目录如下图

其中 frpc_remote_ftp.ini 以及 nohup.out 是后续加进来的,如果解压后目录里没有是正常的。

此时,我们输入:

1
2
3
vim frps.ini
# 如果提示没有权限,则在命令前加上 sudo ,并输入root的密码即可
# 例如:sudo vim frps.ini

其初始化配置文件:

1
2
[common]
bind_port = 7000

bind_port 代表了 frps 作为 server 监听的是 7000 端口,这个设置可以自定义。

然后我们在非插入模式下输入 :wq ,并点击回车退出vim。(具体vim的操作,自行百度。当然如果为了省事,可以使用 gedit 指令来打开文件)

此时,我们在当前 frp 文件的目录下输入:

1
./frps -c ./frps.ini

如果命令行出现上述输出,则表示启动成功,接下来就是内网设备启动 frpc 连接到 frps

2.2 frp客户端配置

在我们的内网设备中,仍然需要下载 frp。下载以及解压的方式同 [2.1frp服务器端配置](#2.1 frp服务端安装配置) 一样。

解压后,进入目录,因为内网设备是作为 client ,连接到 server,因此我们启动的是 frpc。

接下来我们配置 frpc.ini,命令行中输入:

1
2
vim frpc.ini
# 如果提示没有权限,则在命令前加上 sudo ,并输入root的密码即可

其初始化配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
[common]
# 此处需要修改为公网设备的IP
server_addr = 121.XXX.XXX.XXX
# 注意此处的server_port需要与服务器端配置中的bind_port相同
server_port = 7000

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
# 此处配置的端口就是后续用ssh访问时,预设的端口
remote_port = 6000

修改完毕并退出后,我们在命令行中输入:

1
./frpc -c ./frpc.ini

如果没有黄色报错,那么久启动成功了

2.3连接测试

此时我们打开自己电脑的 xshell,创建一个新的连接:

其中 “名称” 可以随便填,“主机” 填的就是我们公网IP设备的IP地址(例如 121.XXX.XXX.XXX),端口号一定要与frp客户端配置中的 remote_port 相同。

配置好之后,点击确定,然后连接即可。

当然这一步作者只简单描述了步骤,关于具体xshell的操作,可以自行谷歌。

至此,我们的frp内网穿透就完成了。

写在最后

我们完成了内网穿透,可以通过转发,来访问到内网服务器的22端口,以此建立起ssh连接。

但是仍然有些许问题:

  1. 我们运行 frpc 或者 frps 程序后,此时终端会等待 frpc 与 frps 程序运行完毕,才可以运行其他指令。那为了保证连接,难道必须一直打开终端吗?
  2. 每次关机之后,frpc 与 frps 就会关闭。对于公网IP设备,本来就是云服务器,一直开着还没啥问题。但是内网设备有时是需要重启的,那怎么才能让 frp 程序随开机自启动呢?

上面两个问题也是我之前的疑问,不过后来查询各种资料与博客,才解决掉,总的来说算是处理的比较不错,基本上只要内网设备开着机,我就能连上。

具体的做法,由于篇幅限制,就不在这篇博客里赘述了,下一篇博客会写关于这方面的内容。

当然由于人之初,性本懒 ( : P ),更新还是随缘。

最后还是感谢读者看完这篇文章,谢谢支持

参考: