众所周知,局域网内部机器由于没有公网IP,因此无法被局域网外部的客户端直接访问。FRP就是这样一个用于内网穿透的应用,它需要一台拥有公网IP的服务器作为中转,实现访问内网机器的目的。
1、基本原理:
如图所示,现有公网服务器一台(220.181.38.251),
局域网主机两台,局域网地址分别是:
192.168.0.2
192.168.0.3
frp下载之后包含两端,frps是安装在公网服务器上的,frpc是安装在局域网内部机器里的。
一个服务器端可以带N台局域网机器,在同一个公网IP下,通过不同的端口区分不同的局域网内部机器以及不同的服务。如上图的,6001和6002端口,就区分了局域网内部的192.168.0.2和192.168.0.3这两台机器的22端口。
对访问者看起来,地址就只有一个,即中转服务器的公网IP,不同的端口对应着不同的局域网内部机器,访问:
220.181.38.251:6001 相当于访问 192.168.0.2:22
220.181.38.251:6002 相当于访问 192.168.0.3:22
局域网机器统一通过7000端口与服务器进行数据交换。
2、配置:
中转服务器 220.181.38.251
运行frps (即frp-server)
配置文件:frps.ini
[common] bind_port = 7000服务器端比较简单,仅监听本机(即220.181.38.251) 的 7000 端口
局域网分机设置(以192.168.0.2为例):
运行frpc (即frp-client)
配置文件:frpc.ini
[common] server_addr = 220.181.38.251 server_port = 7000 [ssh] type = tcp local_ip = 192.168.0.2 local_port = 22 remote_port = 6001在局域网分机上多了一些选项,[common] 一栏注明了中转服务器的地址和7000端口 [ssh] 一栏则具体设置了ssh服务的映射关系:
局域网内部IP : 192.168.0.2 (以此区分局域网内部不同的主机)
本机端口:22
远程端口:6001
也就是:将192.168.0.234 这台主机的 22 端口,映射到服务器的 6001端口。
现在,192.168.0.2 这台局域网分机的设置就已经完成了,另一台机器(192.168.0.3)设置方法完全一样,这里不再赘述。
接下来回到公网服务器(220.181.38.251)上,进行防火墙设置:
开放 7000 端口 (这是服务器与各个局域网分机交互的总通道)
开放 6001 端口 (将服务器的6001映射到192.168.0.2:22)
开放 6002 端口 (将服务器的6002映射到192.168.0.3:22)
配置文件修改完毕后,我们就可以启动frp了,frps和frpc需要同时运行才能生效。
使用方法:
服务器端(frps):
frps -c frps.ini如果需要后台运行:
nohup frps -c frps.ini >/dev/null 2>&1 &局域网端(frpc):
frpc -c frpc.ini后台运行:
nohup frpc -c frpc.ini >/dev/null 2>&1 &3、WEB设置
上面的例子演示了如何将局域网的SSH (22端口) 通过FRP穿透到公网,下面介绍一下如何在局域网上假设一台WEB(80端口) 服务器,然后通过FRP暴露到公网,以让局域网外部用户访问。
第一步:访问你的域名DNS管理界面,添加一个子域名
点 [ 新增一条A记录 ]
主机记录填: www (即www.8gws.com)
记录值填写服务器IP (如我们之前的公网服务器IP:220.181.38.251)
保存退出
第二步:在公网服务器上设置
编辑:frps.ini (找到common一栏,添加一行)
[common] vhost_http_port = 8000第三步:在局域网机器上设置
编辑:frpc.ini (添加web栏,内容如下)
[web] type = http local_port = 80 custom_domains = www.8gws.com现在,打开浏览器,输入:http://www.8gws.com:8000
就可以访问你在局域网上设置的WEB网站了。
API设置
通过上面的步骤,静态网站这边就已经没有问题了,但是如果网站是具有交互性的,还需要对API接口再进行一些额外的设置:
回到局域网机器,假设现在我们的配置如下:
采用 nginx 为WEB服务器方案
API后台服务程序端口:5050
修改nginx配置文件:/usr/local/nginx/conf/nginx.conf
在http { } 这一节里添加以下内容:
location ~ /api/(.*) { proxy_pass http://127.0.0.1:5050/$1; }回到我们的前端代码,假设我们现在用axios来做ajax后台通信,那么baseURL需要设置成这样:
axios.defaults.baseURL = 'http://www.8gws.com:8000/api/'没有域名的情况下如何设置:
服务器端 frps.ini :
[common] bind_port = 7000局域网分机 frpc.ini :
[common] server_addr = 服务器ip server_port = 7000 [tcp_port] type = tcp local_ip = 192.168.0.2 local_port = 80 remote_port = 8080防火墙设置:
服务器:开放7000和8080端口,
局域网机器:开放80端口
然后在浏览器输入:http://服务器ip:8080
就可以访问运行在局域网机器上的网站了。
经测试,在 IE 和 curl 命令下都能正常访问,但是在Chrome和Edge这些所谓 “现代浏览器“ 下面,还是经常会报错,这个坑和frp无关,需要自行研究。