FRP内网穿透

1.概述

简单地说,FRP就是一个反向代理软件,体积轻量但功能很强大,使用 Go 语言开发,可以让外网访问到你的本地应用,将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。支持TCP、UDP、HTTP、HTTPS 等众多协议。
image.png

1.1 工作原理:

服务端运行,监听一个主端口,等待客户端的连接;
客户端连接到服务端的主端口,同时告诉服务端要监听的端口和转发类型;
服务端fork新的进程监听客户端指定的端口;
外网用户连接到客户端指定的端口,服务端通过和客户端的连接将数据转发到客户端;
客户端进程再将数据转发到本地服务,从而实现内网对外暴露服务的能力。

1.2 使用场景

现实环境中我们大部分的电脑都是在局域网的环境里,要想连接互联网都是需要路由器的公网ip来进行转发的,所以如果我在本地部署了一个服务,如果没有公网ip的话,别人是访问不到的,因为本地的服务只能在内网的环境中被访问到。这个时候如果两台主机要通信,只能由内网部署服务的主机向目标主机发送信息,但是目标主机无法主动的向处于内网的主机回信。
这个时候就需要用到内网穿透或者端口映射了,内网穿透也叫TCP打洞,这个了解的不是太多。
这里说一下端口映射,实现端口映射的软件工具有很多,比如花生壳、frp等,其实本质上都是端口的映射。frp的实现方式是需要有一台有公网ip的主机,将frp的服务端和客户端安装好进行连通后,在配置中将本地服务的端口(比如80),映射到有公网ip的主机上(比如30001),那么这台有公网ip的主机就会监听这个端口,只要有客户端通过这个公网ip+30001的端口访问,请求就会被转发到本地服务的80端口上,就实现了内网的服务可以被外网访问到。


名词解释:端口映射&端口转发
端口映射与端口转发实现的功能类似,但又不完全一样。

  • 端口映射是将外网的一个端口完全映射给内网一个地址的指定端口,可以实现外网到内网和内网到外网双向的通信。
  • 端口转发是将发往外网的一个端口的通信完全转发给内网一个地址的指定端口,只能实现外网到内网的单向通信。

2.部署安装

前提条件:要部署frp,首先必须需要有一台能被公网访问到,有公网 ip 的服务器,这里使用的是阿里云的ECS。

2.1.下载解压安装包

在github中下载最新版的frp安装包。
https://github.com/fatedier/frp/releases
将安装包导入到阿里云的ECS中并解压,可以看到有如下的文件。
image.png

2.2 编辑frps配置,启动服务端

2.2.1 编辑frps.ini
[common]   #标题
bind_port = 7000   #服务端监听端口:接收 frpc 的连接
dashboard_user = admin   #frp网页端控制面板登录用户名	
dashboard_pwd = admin   #frp网页端控制面板登录密码	
dashboard_port = 7500   #启用 Dashboard 监听的本地端口
enable_prometheus = true   #是否提供 Prometheus 监控接口:需要同时启用了 Dashboard 才会生效
token = rthrth1541gege54545   #鉴权使用的 token 值:客户端需要设置一样的值才能鉴权通过

2.2.2 启动frps服务端

配置完成后,启动frps,出现类似下图的内容即说明服务端启动成功。
./frps -c frps.ini

在这里插入图片描述

2.3 编辑frpc配置,启动客户端

2.3.1 解压编辑frpc.ini

将安装包导入到内网的本地主机中并解压,编辑frpc.ini,frp client的配置文件。

[common]   #标题
server_addr = 47.97.177.130   #连接服务端的ip地址
server_port = 7000   #连接服务端的端口
token = rthrth1541gege54545   #鉴权使用的 token 值

[web]   #标明以下是什么的配置,标题名唯一,一个配置文件中不能重复
type = tcp   #连接类型:tcp
local_ip = 127.0.0.1   #本地服务ip:需要被代理的本地服务的ip地址,可以为所在frpc能访问到的任意 ip地址;
local_port = 80   #本地服务端口:配合 local_ip
remote_port = 30001   #远程端口:ECS服务器监听的端口,接收到请求后会通过frp转发到内网服务器的80端口;

2.3.2 启动frpc客户端

配置完成后,启动frpc,出现类似下图的内容即说明客户端启动成功。
./frpc -c frpc.ini
image.png

2.4 设置frp后台自动运行

由于 frps 和 frpc 一关闭xshell的页面就会停止,所以还需要做一下frp的后台自动运行。
有三种方法,这里使用supervisor来控制。frps和frpc都需要做。


名词解释:宝塔supervisor管理器
Supervisor是用Python开发的一套进程管理器程序,它可以将一个命令变成后台daemon ,可以监控这个程序的进程运行状态,如果异常退出可以自动重新开启所监控的程序;
supervisor可以监控某个程序的运行状态而自动执行某操作命令;


2.4.1 安装supervisor

sudo apt install supervisor

2.4.2 在/etc/supervisor/conf.d 目录中创建 supervisor frp 的配置文件 frp.conf

输入一下内容,command 后要输入frp文件所在的绝对路径

[program:frp]
command = /opt/frp_0.44.0_linux_amd64/frps -c /opt/frp_0.44.0_linux_amd64/frps.ini
autostart = true

2.4.3 重新加载supervisor

重启supervisor sudo systemctl restart supervisor
查看supervisor运行状态 sudo supervisorctl status

2.5 查看frp仪表盘

打开frp dashboard仪表盘查看 在浏览器输入47.97.177.130:7500/,输入用户名和密码后,可以看到连通成功。
image.png

2.6 访问测试

之前已经在内网的本地主机中部署好了harbor服务,在浏览器中输入47.97.177.130:30001/
可以看到已经能够成功访问了!
image.png

为了便于理解,可以参考下图:
image.png

参考文档:
frp官方文档
https://gofrp.org/docs/overview/
frp后台启动运行
https://www.cnblogs.com/ministep/p/15499768.html

3.FAQ

在实际的部署操作过程中,由于对frp配置文件的不熟悉,以及对原理理解的不够彻底,所以在部署好frp并且连通之后,迟迟没有成功访问到本地内网的harbor服务。

首先,我想到了会不会是frp服务没有启动成功,于是登录 frp dashboard 查看,发现没有问题;
之后猜想那会不会是端口的问题,于是又去阿里云的控制台,查看安全组有没有打开需要的端口,也没有问题。
这两个问题排除后,我又想到那会不会是frp的配置出错了呢?于是又去检查了frps和frpc的配置文件,当时在frpc配置的是6000端口。
之后在主管的帮助,才排查到了真正的问题原因所在。

在排查问题之前,要明确三点

  • 先分析,看请求流链路通不通,按顺序排查,不断缩小范围;
  • 关注报错信息:根据报错信息来思考,确定排查方向;
  • 在经验不足的情况下不要随意的瞎猜原因及可能性,漫无目的的找寻答案,很可能白白浪费了时间精力而抓不住重点;

这三点也适用于排查其他问题。

3.1 验证 frp 是否连通

无法访问到本地的服务,我们首先要想到 frp 是否成功连通。
验证方法:
① 登录 frp dashboard,查看端口是否打开,是否连通。
② 在服务端查看映射的端口有没有被监听netstat -tpln
③ 因为frp做了后台自动运行,需要查看下日志,看有没有问题。
cat /var/log/supervisor/supervisord.log
cat /var/log/supervisor/frp-stdout---supervisor-qrxw5wkn.log

3.2 查看本地服务访问及运行情况

发现 frp 的连通没有问题之后在思考,frp已经连通,说明两个主机之间的通道已经建立,但是服务依然访问不到,是不是部署在本地的服务挂掉了?
检查 harbor 服务是否在运行中docker ps,发现没有问题,同时使用本地路径10.66.55.132:80也是可以正常访问的。

3.3 验证服务端内网连通

再思考,既然本地服务没有问题,frp 也已经连通,那在服务端的内网中能不能连通呢?
验证:
curl http://172.20.169.14:6000
发现也是无法连通。

3.4 验证其他服务和其他端口

继续分析
frp 连通正常,在 frp客户端中已经配置映射6000:80端口,本地服务也运行正常,理论上来说应该是可以成功访问的,这个时候在做一个操作验证:
① 在本地主机中用 docker 启动一个 nginx 服务,将 nginx 监听端口改为81。
② 在 frpc 中将映射端口也改为 81:30001,将阿里云ECS安全组中的30001端口开放。
③ 在浏览器访问 10.66.55.132:81 和 47.97.177.130:30001,可以成功访问到 nginx。
④ 在ECS阿里云服务器中也是可以访问 curl 47.97.177.130:30001 curl 172.20.169.14:30001

3.5 测试浏览器问题

这些都没有问题,那就只能是浏览器或者是端口的问题了。
使用其他浏览器访问,结果也是OK的。
这个时候将 nginx 服务移除,将 frpc 配置重新改为 80:6000,使用浏览器和服务端 curl 访问,也是不通的。
image.png

3.6 确定问题点

上网查询,发现6000端口是一个特殊的端口,被http协议给禁掉了。
image.png
自此,通过这一步步的排查,不断的缩小范围,才确定了问题的所在。

  • 23
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值