如上图,假设我们想要通过主机A访问主机C(通过SSH登录),但是主机A和主机C在不同的局域网中,绑定的都是私有ip地址,所以它们之间是无法直接进行通信的。要想使得A和C能够进行通信,就需要用到内网穿透的技术。使得局域网内的设备C能够被“穿透”到公网中,被其他设备所访问,这就要用到内网穿透技术。
内网穿透是一种网络技术,通常用于将位于局域网内部的服务、设备、或者应用程序暴露到公共网络(互联网)中,使得外部网络可以访问局域网内的资源。比如上图中,我们把公网中的服务器B作为代理桥梁沟通A和C,由于B是公网ip,因此A和C都可以主动访问到B,那么我们就可以在B和C之间建立通信信道,在A需要访问C时,将访问请求发给B,由B作为代理转发给C,这样就实现了A与C之间的通信,也就实现了C的内网穿透。
现在有多种工具可以提供内网穿透服务,如ngrok,花生壳,frp等,本文将介绍通过frp
实现内网穿透,简单免费、配置方便。
frp 是一款高性能的反向代理应用,专注于内网穿透。它支持多种协议,包括 TCP、UDP、HTTP、HTTPS 等,并且具备 P2P 通信功能。使用 frp,可以安全、便捷地将内网服务暴露到公网,通过拥有公网 IP 的节点进行中转。
通过在具有公网 IP 的节点上部署 frp 服务端,可以轻松地将内网服务穿透到公网,并享受以下专业特性:
代理类型: frp 支持多种代理类型,以适应不同的使用场景。以下是一些常见的代理类型:
frp 采用 Go 语言编写,支持跨平台,只需下载适用于您平台的二进制文件即可执行,无需额外依赖。您可以从 GitHub 的 Release 页面中下载最新版本的客户端和服务器二进制文件。所有文件都打包在一个压缩包中,还包含了一份完整的配置参数说明,我的linux系统下载的是这个版本:
下载并解压之后有如下文件几个文件,其中frpc
和frpc.toml
是客户端的执行程序和配置文件(仅在客户端使用),而frps
和frps.toml
是服务端的执行程序和配置文件(仅在服务端使用);;
frpc
和frpc.toml
复制到内网服务所在的机器上(客户端)。frps
和frps.toml
复制到拥有公网 IP 地址的机器上(服务端),并将它们放在任意目录。 在 Linux 系统下可以使用 systemd
来管理 frps
服务,包括启动、停止、配置后台运行和设置开机自启动功能,非常方便。
1.安装 systemd
如果您的 Linux 服务器上尚未安装 systemd,可以使用包管理器如 yum(适用于 CentOS/RHEL)或 apt(适用于 Debian/Ubuntu)来安装它:
# 使用 apt 安装 systemd(Debian/Ubuntu)
apt install systemd
2.创建 frps.service 文件
使用文本编辑器 (如 vim) 在 /etc/systemd/system
目录下创建一个 frps.service
文件(同理,客户端是frpc.service
),用于配置 frps 服务。
sudo vim /etc/systemd/system/frps.service # 服务端
或
sudo vim /etc/systemd/system/frpc.service # 客户端
3.写入内容(以服务端为例)
[Unit]
# 服务名称,可自定义
Description = frp server
After = network.target syslog.target
Wants = network.target
[Service]
Type = simple
# 启动frps的命令,需修改为您的frps的安装路径
ExecStart = /path/to/frps -c /path/to/frps.toml
[Install]
WantedBy = multi-user.target
4.使用 systemd 命令管理 frps 服务(以服务端为例)
# 启动frps
sudo systemctl start frps
# 停止frps
sudo systemctl stop frps
# 重启frps
sudo systemctl restart frps
# 查看frps状态
sudo systemctl status frps
5.设置 frps 开机自启动
sudo systemctl enable frps
命令执行结果如下,可以看出设置开机启动实际就是在/etc/systemd/system/multi-user.target.wants/
目录下面创建一个符号链接,即可实现开机自启动,不难分析出开机时系统加载会扫描改目录下的服务配置,从而实现开机自启动,实现原理简单,举一反三,对于自己的服务程序也可以封装成systemd管理方式,这样维护起来更加方便高效。
通过遵循上述步骤,您可以轻松地使用 systemd 来管理 frps 服务,实现启动、停止、自动运行和开机自启动。确保替换路径和配置文件名称以匹配您的实际安装。
在客户端和服务器分别部署好frp程序之后,下一步需要修改配置文件,即在服务端修改frps.toml
,客户端修改frpc.toml
。
在公网服务器上部署 frps
并编辑 frps.toml
文件。以下是简化的配置,其中设置了 frp 服务器用于接收客户端连接的端口:
bindPort = 7000 # 用来接收客户端(被代理机器C)连接的端口
默认配置就是7000,不用改动。
在需要被访问的内网机器(客户端C)上部署 frpc
,并编辑 frpc.toml
文件,假设 frps 所在服务器的公网 IP 地址为124.156.15.247
,以下是示例配置:
serverAddr = "124.156.15.247" # 公网服务器(服务端B)ip
serverPort = 7000 # 公网服务器(服务端B)端口,上面设置的
[[proxies]]
name = "ssh"
type = "tcp-test"
localIP = "127.0.0.1" # 客户端C本地ip,不用改,就是localhost地址
localPort = 22 # 客户端C SSH监听端口,默认是22,通常都不用改
remotePort = 6000 # 需要在服务端B上请求开通的监听端口,很关键,这个端口是给登录方A用的
localIP
和localPort
配置为需要从公网访问的内网服务C的地址和端口。remotePort
表示在 frp
服务端B监听的端口,访问此端口的流量将被转发到本地服务的相应端口,一定要注意公网服务端B的端口防火墙是否开启!!!。 一定要先启动公网服务端B,在启动客户端C,不然C的启动会失败(因为连不上B)。
1.通过命令启动服务端Bfrps
服务程序:
# 启动frps
sudo systemctl start frps
2.通过命令查看服务端frps
运行状态:
# 查看frps状态
sudo systemctl status frps
结果如下则表示frps启动成功。
3.通过命令启动客户端Cfrpc
服务程序:
# 启动frpc
sudo systemctl start frpc
4.通过命令查看客户端Cfrpc
运行状态:
# 查看frpc状态
sudo systemctl status frpc
结果如下则表示frpc启动成功。
备注:只要客户端能启动成功,就说明连上了服务端B,就说明B和C之间的通信信道是打通的!!!
在客户端和服务端程序都按照上述步骤启动成功后,就说明客户端C借助服务端B完成了内网穿透功能,接下来就可以在需要访问的机器A上进行远程SSH登录,访问局域网主机C,在A上执行以下程序:
ssh -p 6000 [email protected]
注意,这里的6000
是在frpc.toml
中设置的服务端B监听端口,username
是C的用户名,而不是B的,IP填的是B的公网IP(124.156.15.247)。由此完成B将端口6000的请求转发给C,完成内网穿透下的SSH登录!!!
可以通过一些端口或者网络命令来测试刚刚设置的一些网络端口是否能正常工作(6000,7000),包括:
sudo lsof -i:端口号 # 测试端口是否处在监听状态
netstat -tunlp |grep 端口号 # 用于查看指定的端口号的进程情况
telnet ip 端口号 # 用于测试网络端口是否可达
一些测试实例如下:
通过网络端口测试,可以辅助我们查找哪些端口没打开,方便我们查找问题,一定得学会用哦。