CDC

Place to Be & Show Yourself

FRP和内网穿透

问题的提出

家里宽带服务提供商没有给我分配公网IP,在公司想访问家里的照片该怎么办?
公司没有VPN,出差在外想访问公司内部的网络服务该怎么办?
IT运维人员半夜接到电话,需要临时调整公司内网服务器的设置该怎么办?

不必担心,自从FRP横空出世之后,上面这些就都不是什么问题了!

FRP架构

什么是FRP

FRP是Fast Reverse Proxy的缩写,是一个可用于内网穿透的高性能的反向代理应用,将内网的机器暴露给Internet访问,目前支持 tcp, udp, http, https 协议。

FRP能干什么

  • 利用处于内网或防火墙后的机器,对外网环境提供 http 或 https 服务。
  • 利用处于内网或防火墙后的机器,对外网环境提供 tcp 和 udp 服务,例如在家里通过 ssh 访问处于公司内网环境内的主机。

FRP架构

FRP的总体架构图如下所示,包含两个基本组件,FRPS是服务端,部署在有公网IP的服务器上;FRPC是客户端,部署在希望暴露出去的内网机器上。
《FRP和内网穿透》
他的基本原理是FRPC客户端和FRPS服务端指定端口之间建立一个“隧道”,最终用户通过该隧道访问内网服务的时候,隧道进行了一个类似于端口映射的动作,例如将对公网remote_port1端口的访问映射到内网local_port端口的访问。
理解了上面的原理,接下来环境搭建部分的配置文件就非常好理解了。

FRP环境搭建

当然,搭建环境最基本的步骤,就是根据自己的操作系统版本,选择下载对应的安装包。下载地址在[这里],目前最新版本是0.19
下载之后解压即可运行了。不过需要注意的是,FRP各个版本之间的通信协议有一点差别,有的版本是不兼容的,所以server版和client版最好配合使用。

通过 ssh 访问公司内网机器

修改 frps.ini 文件,这里使用了最简化的配置:

启动 frps:

修改 frpc.ini 文件,假设 frps 所在服务器的公网 IP 为 x.x.x.x;

启动 frpc:

通过 ssh 访问内网机器,假设用户名为 test:

上面的例子中,用于建立隧道的端口是3389, 隧道建立之后,将FRPS公网上的6000端口映射到内网的22端口。

注意:可能有的同学会问,为啥例子中bind_port是3389,这个可是Windows远程桌面使用的端口啊。其实这个端口可以是其他值的。前提是FRPS所在的公网服务器是开放了这个端口,而且内网也允许访问该端口。某司的内网,只允许访问3389,22,80,443等少数几个端口。

访问内网的web页面 – 方式一

其实从TCP角度来看,web服务和ssh服务是类似的,只是端口不同而已,通常http的端口是80,https的端口是443,只需要将上面local_port修改为内网的http或者https端口号,则在用户浏览器上访问下面的URL,就可以访问到内网的web服务了

访问内网的web页面 – 方式二

有时想要让其他人通过域名访问或者测试我们在本地搭建的 web 服务,但是由于本地机器没有公网 IP,无法将域名解析到本地的机器,通过 frp 就可以实现这一功能,以下示例为 http 服务,https 服务配置方法相同, vhost_http_port 替换为 vhost_https_port, type 设置为 https 即可。

修改 frps.ini 文件,设置 http 访问端口为 8080:

启动 frps;

修改 frpc.ini 文件,假设 frps 所在的服务器的 IP 为 x.x.x.x,local_port 为本地机器上 web 服务对应的端口, 绑定自定义域名 www.yourdomain.com:

启动 frpc:

将 www.yourdomain.com 的域名 A 记录解析到 IP x.x.x.x,如果服务器已经有对应的域名,也可以将 CNAME 记录解析到服务器原先的域名。

通过浏览器访问 http://www.yourdomain.com:8080 即可访问到处于内网机器上的 web 服务。

自定义二级域名

在多人同时使用一个 frps 时,通过自定义二级域名的方式来使用会更加方便。

通过在 frps 的配置文件中配置 subdomain_host,就可以启用该特性。之后在 frpc 的 http、https 类型的代理中可以不配置 custom_domains,而是配置一个 subdomain 参数。

只需要将 \*.{subdomain_host} 解析到 frps 所在服务器。之后用户可以通过 subdomain 自行指定自己的 web 服务所需要使用的二级域名,通过 {subdomain}.{subdomain_host} 来访问自己的 web 服务。

将泛域名 *.frps.com 解析到 frps 所在服务器的 IP 地址。

frps 和 fprc 都启动成功后,通过 test.frps.com 就可以访问到内网的 web 服务。

需要注意的是如果 frps 配置了 subdomain_host,则 custom_domains 中不能是属于 subdomain_host 的子域名或者泛域名。

同一个 http 或 https 类型的代理中 custom_domains 和 subdomain 可以同时配置。

负载均衡的实现

细心的同学从上面FRP原理的架构图中已经可以看到负载均衡的影子了。如果内网单台web服务器的访问量太大了,就用多台机器提供服务。最终用户访问FRPS服务器的不同端口,就被映射到内网的不同服务器上,达到了流量分担的效果。

但是实际上负载均衡不是这么玩的。真正的负载均衡需要自动根据设定好的比例(缺省是平均)分配用户的流量到每台机器上,而不是由用户决定选择哪台机器提供服务。

目前负责均衡的方案有很多种,包括Nginx,Caddy,HaProxy等都可以实现,本文以Nginx为例来实现内网穿透的负载均衡

以上是Nginx配置文件的一个部分,两个内网机器映射的远端端口分别是6000和6001, FRPS所在的公网IP是X.X.X.X, 对应的域名是myfqdn.com. 则上面配置文件的具体含义是:所有http://myfqdn.com
的访问流量,会按照1:1的比例分发到对x.x.x.x:6000和6001这两个端口的访问

而对6000和6001这两个端口的访问,又经过FRP穿透到内网的web服务,最终实现了自动负载均衡的目的。

当然Nginx可以部署在FRPS所在的机器,也可以分别部署到不同的机器上,只要Nginx的流量能到达FRPS就可以了

案例研究

  1. 现在各位看官看到的这个博客,就是通过FRP穿透到公司内网的。
  2. 有人利用上面的二级域名的方式在网上赚钱了。请参考这个[网站]
点赞

发表评论

电子邮件地址不会被公开。