我的需求

家里局域网内有我的一台 mac,上面部署了一个 https 服务,现在外网的一台 windows 主机需要访问我的这个网站。

我有的设备

设备 内网 IP 公网 IP 责任 FRP 角色
Mac 192.168.10.67 部署了 HTTPS 服务,443 端口 frpc
4G-Router 192.168.10.1 无(用的4G上网卡,没有公网IP) 无法使用路由器自带的端口映射
Linux Server 47.xx.xx.xx 反向代理 frps
Windows 通过 Chrome 访问 Mac 的 HTTPS 网站

原方案失败,路由器端口映射

我原本以为解决这个事情很简单,只要在路由器上做个端口映射就好了,其实严谨一点讲叫端口转发(Port Forwarding),这样就可以把外网进来的流量按端口转发到内网的一台机子上。结果我吭哧吭哧操作了一波后却发现怎么测都发现测不通。查了半天(😷咳咳咳,是真的半天),把 Mac 和路由器上的防火墙都关了,还是连不上。我以为通过 ipip.net 查询到的公网 IP 是我的路由器的公网 IP,然鹅并不是这样的!

因为我的设备是 4G 路由器,插的联通的 4G 上网卡,并没有分配到独立的公网 IP,所以我的路由器只是在联通的一个 4G 的局域网内。此处口吐芬芳十分钟!🖕

然后我就转向了 FRP。

FRP 方案测试成功

FRP: A fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet.

其实这个架构很常见:

  1. frps: 服务器程序,安装在具有公网 IP 的服务器上,作为一个反向代理的服务,别人应当来访问这个服务来访问你的资源。
  2. frpc: 客户端程序,安装在你需要被代理的机器上,它可以是和 frps 不在一个网络的另一个网络内的一台机器。

这样数据流就是,用户 -> frps -> frpc,然后 frpc -> frps -> 用户,典型的反代。

我的配置文件

# frps.ini
[common]
bind_port = 7000

# 因为我的服务器的 80 和 443 被 nginx 占用了,临时用这两个端口反代
vhost_http_port = 8080
vhost_https_port = 8443

# frpc.ini
[common]
server_addr = 47.xx.xx.xx
server_port = 7000


[plugin_http2https]
type = http
custom_domains = 47.xx.xx.xx
plugin = http2https
plugin_local_addr = 127.0.0.1:443
plugin_host_header_rewrite = my.example.com
plugin_header_X-From-Where = frp

我这里用了 plugin_http2https 插件,因为我的 Mac 本地是 HTTPS 服务,这样的话,别人来访问的时候会用 HTTP 协议,我的 frpc 会用 HTTPS 协议来访问我本地的服务。至于我为什么不让别人用 HTTPS 协议来访问,我只能说,我也想啊,但是没配置出来啊,老报错!!!

还有 custom_domains 字段我为什么不用域名是因为,我 tmd 也想啊,但是因为我的 Linux 服务器是在阿里云上的,阿里云会因为我的域名没有备案而给我拒绝访问。再次口吐芬芳十分钟。🖕🏻

最终我的 Windows 访问 http://47.xx.xx.xx:8080 就可以看到部署在我的 Mac 上的网站了。

其实我网站上有个 Windows 才能运行的功能,我只是想拿 Windows 测试一下,但是我又没有 Windows 电脑,自己装虚拟机又嫌麻烦,就直接在阿里云上临时租了一台,这样等我测试完这个功能就可以释放了。美汁汁~ 👅