首先说明一下我的需求,一台内网的服务器,一台阿里云服务器,需要通过阿里云服务器的公网ip来访问我的内网服务器部署的网站。

这里选择frp作为穿透工具,搭配openresty做反向代理,将访问域名的http和https请求转发给frps在云服务器上开出的隧道端口,请求经隧道回到内网,由frpc直接交给网站端口。个人觉得内网服务器没有必要再加一层代理。

◆ 整体思路

涉及端口均为举例,建议自行根据情况更换

域名解析到阿里云的公网地址;openresty 监听 80 与 443,将请求转发至本机 7100,请求由此进入隧道;流量经 frpc 与 frps 之间已建立的连接返回内网,由 frpc 转交网站端口 8080。

7000 是 frpc 与 frps 之间的连接端口,由 frpc 主动连出,认证、与全部隧道流量都在这一条连接上;frp 默认启用 tcpMux,多条隧道复用同一条连接,安全组需放行 7000。

7100 是 frps 在云服务器的监听端口,由openresty连接,不产生对外的 frp 连接,请求到达后即并入上述隧道,再由 frpc 转交内网;该端口在 frpc 注册相应代理之后才开始监听,因此 7100 无需对公网放行。

◆ 云服务器 frps

frps 为穿透服务端,负责监听与认证,配置两项:监听端口与密钥。

bindAddr = "0.0.0.0"
bindPort = 7000

auth.method = "token"
auth.token = "自己设的一串密钥"

bindPort 为 frpc 的连接端口,frp 默认 7000,实际部署建议更换为其他端口。auth.token 两端必须一致。

◆ 云服务器 openresty

openresty 负责接收域名请求,并将请求转发至隧道端口。

server {
    listen 80;
    server_name 你的域名;

    location / {
        proxy_pass http://127.0.0.1:7100;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

proxy_pass 指向本机 7100

四条 proxy_set_header 用于向后端传递原始域名、访客地址与协议,缺少时后端只能看到本机来源

https 证书配置在 openresty 一层,内网无需处理。

◆ 内网服务器 frpc

frpc 为隧道客户端,配置指向云服务器并携带同一密钥

serverAddr = "阿里云的公网ip"
serverPort = 7000

auth.method = "token"
auth.token = "和 frps 里填的那串一样"

serverAddr 填云服务器公网地址,serverPort 与 frps 的 bindPort 一致。

frpc 自带面板,默认端口 7400,用于查看连接状态与启停代理。

隧道在面板中建立:类型选 tcp,本地端口填 8080(网站监听端口),远端端口填 7100(云上留给网站的端口),保存后 frps 自动在 7100 上开始监听。

◆ 验证

先在云服务器上请求 7100,取得网站响应即表示隧道连通。

curl -I http://127.0.0.1:7100

无响应排查:frpc 面板中代理是否在线;云上 7000 是否处于监听状态、安全组是否放行;内网 8080 上网站是否运行

至此,内网服务通过一条 frpc 连接经阿里云对外提供访问。后续新增内网服务时,按同一流程增加隧道即可