客户端:
服务端:
原理:
有局域网 A 和局域网 B,希望局域网 A 里面的电脑 a 能访问到局域网 B 里面的电脑 b。常见场景为:家里的电脑想访问到公司的电脑。a 是家里的电脑,b 是公司的电脑。
解决方案:
使用具有公网 IP 的服务器 c 作为中转站,将 a 的请求发给 c,c 转发给 b,b 回复给 c,c 回复给 a。
这个方案是 frp 协议。
这里,a 和 b 都是 frp 的客户端,c 是 frp 的服务端。
首先,c 启动 frps (s 表示 server 服务端):
# frps.toml bindPort = 7000
启动命令:
./frps -c ./frps.toml
然后,a 和 b 分别启动 frpc(c 表示 client 客户端)
a 作为使用方,只用启动:
# frpc.toml serverAddr = "x.x.x.x" # c 的公网地址,ip或者域名都可以 serverPort = 7000 # c 的 bindPort
b 作为提供方,需要额外将自己本地的端口暴露出来给 a 使用(见 proxies 部分的配置):
# frpc.toml serverAddr = "x.x.x.x" # c 的公网地址,ip或者域名都可以 serverPort = 7000 # c 的 bindPort [[proxies]] name = "ssh" type = "tcp" localIP = "127.0.0.1" # 绑定到本地 localPort = 22 # 绑定到本地端口。a 访问 c 的 remotePort 端口的请求都会转发给 b 的此端口,实现 a 对 b 的直接访问(逻辑上) remotePort = 6000 # b 在 c 上注册的的虚拟端口,访问 c 的 remotePort 就是在访问 b 的 localPort。
a 和 b 的启动脚本都是:
./frpc -c ./frpc.toml
解释:
remotePort 是 c 的转发端口,也是 a 和 b 的协议端口,这个端口对应了一个对点通信。
a 访问 serverAddr:remotePort 就是在访问 b 的 localPort。
a 的请求发给 c 的 remotePort,c 通过 frp 协议,知道提供 remotePort 的是 b,从而将所有访问 remotePort 的请求转发给 b。b 会从 c 的 remotePort 端口接受请求进行处理。
所以 b 必须设置 remotePort 才能暴露给 a。
remotePort 端口由 b 采用 tcp 协议,将 b 的内部端口 b.localPort 暴露出来给 remotePort,实现 b 内部端口的虚拟化,从而 a 访问 remotePort 就是在访问 b 的内部端口 b.localPort