前言:
网上也有很多教程包括官方文档,都需要购买域名,并且把 frpc.ini 中 [web]节配置的 custom_domains 的值解析到外网的服务器,多个web项目需要多个 custom_domains(每个web项目保证唯一),统统把这些 custom_domains 解析到外网服务器,然后就可以使用,使用方式就是 custom_domains:vhost_http_port,就可以实现多个web项目的访问。
下面的方法不需要购买域名和域名解析服务,也可以实现多个web项目内网穿透使用
提出解决方法依据的原理(想快速解决问题,请跳过)
疑问: frp软件尽管配置了 custom_domains,但是统统解析到了同一台外网服务器,那为什么可以实现请求统一端口(frps.ini common 中的vhost_http_port ) 来达到访问不同web项目的需求呢?
1. 首先,我们都知道浏览器输入一个 url 的访问过程,如果是使用域名访问,那么首先需要解析域名获得真实的IP地址然后,通过TCP报文来发送。那么神奇的地方就来了,我们在 frpc.ini 中把所有的 web 项目的 custom_domains 都解析到了同一个 IP地址,并且 frps.ini 提供web访问的端口只有一个(vhost_http_port),按照socket建立连接,我们有了(IP,Port)这个元组就可以唯一确定这个连接了,因此我们可以断定所有配置的内网的web项目全部使用这一个socket完成
2. 那使用一个socket链接如何区分不同的内网web项目呢?
回想 frpc.ini ,我们在这里配置了不同的 custom_domains, 这就是关键,fpr server只有通过这个标识才能分发不同的数据到不同的web项目。因此,在我们通过 custom_domains:vhost_http_port 来访问目的 web项目时候,必要要保证 custom_domains 被传递到了 frp server,这样才能被分发。frp软件采用http中host字段来保证这个事情,当我们使用浏览器请求目标网站,浏览器自动把目的RUL域名填到 http request header 的host字段。因此,当这个请求到达 frp server的时候,只要通过查找与 request header host 对应的 web项目即可,这样就实现了一个端口分发的问题。(类似于Nginx中端口分发,只不过那里使用的 url 前缀进行分发,这里使用的 request header host 字段)
3. 看到这里你就明白该怎么做了
我们只要配置本机的 host 文件,追加每个 custom_domains 到 公网服务器的解析即可
通过这样就可以达到,custom_domains 被顺利放在 请求的header host字段,并且也不需要购买域名实现本地解析。
=========== 实践派 ==============
一、配置 frpc.ini
[common] server_addr = xx.xx.xx.xx server_port = 7000 [ssh_sx] type = tcp local_ip = 127.0.0.1 local_port = 22 remote_port = 6001 [web_9990] type = http local_ip = 127.0.0.1 local_port = 9990 #网站使用的端口 custom_domains = a.free.domain #随便写个域名保证唯一 [web_9991] type = http local_ip = 127.0.0.1 local_port = 9991 #网站使用的端口 custom_domains = b.free.domain #随便写个域名保证唯一
二、配置服务器 frps.ini
[common] bind_port = 7000 vhost_http_port = 8080
二、 重新启动客户端软件 ./frpc -c frpc.ini 重新启动服务端软件 ./frps -c frps.ini
三、配置本地host文件
windows : C:\\Windows\\System32\\drivers\\etc\\hosts linux: /etc/hosts
追加
xx.xx.xx.xx a.free.domain xx.xx.xx.xx b.free.domain
xx.xx.xx.xx 是你的公网服务器IP 地址
刷新 host文件,使得新配置生效:
windows: ipconfig.exe /flushdns linux: systemctl restart nscd
四、打开浏览器
输入: a.free.domain:8080 即可访问 web项目 web_9990
输入: b.free.domain:8080 即可访问 web项目 web_9991