frp 的工作基础
1. 两个进程
frp 由两个进程组成:
- frps:跑在节点上,有公网地址
- frpc:跑在您自己的电脑上,主动向节点发起连接
一条隧道就是「节点上的一个入口」到「您本地的服务」之间的映射。流量最终都要由 frpc 送到您本地的服务上,节点本身不提供任何服务。
2. 和正向代理的区别
正向代理是客户端被配置成走代理,代理替客户端去访问外部;对外部服务器来说请求来自代理,客户端被隐藏。
frp 正好相反:
| 正向代理 | frp | |
|---|---|---|
| 谁发起连接 | 客户端主动连代理 | frpc 主动连节点 |
| 替谁访问 | 替客户端访问外部 | 替访客访问您本地的服务 |
| 谁被隐藏 | 客户端地址 | 您的内网地址 |
| 典型用途 | 访问受限资源、隐藏来源 | 让外网访问内网服务 |
访客不需要做任何配置,直接连节点即可;被隐藏的是您的内网,被暴露的是您的服务。
3. 控制连接
frpc 启动后会主动向节点发起一条连接,这条叫控制连接,它负责:
- 认证,确认这条隧道属于哪个账号
- 注册隧道,告诉 frps 这条隧道监听哪个远程端口、对应哪个域名
- 心跳保活,默认 30 秒一次,90 秒收不到回应即判定断线并自动重连
- 接收 frps 下发的指令
这条连接的方向是出站,所以您不需要公网 IP,也不需要在家里的路由器上做端口映射或开启 UPnP。控制连接断了,隧道就不可用。
4. 工作连接
有访客连进来时,frps 通过控制连接通知 frpc,frpc 再向 frps 发起一条新连接来承载这次访问的数据,这条叫工作连接。
所以数据通道同样是从内网往外建立的,frps 只负责把两头对接起来。
一次访问通常对应一条工作连接;开启多路复用时,多条访问可以共用一条连接,各自是独立的流。
5. 转发发生在哪一层
| 层级 | 按什么转发 | 能否看到内容 | 典型实现 |
|---|---|---|---|
| L3 | IP 地址 | 否 | 路由器、VPN、IP 隧道 |
| L4 | IP + 端口 | 否,只有地址和端口 | frp 的 TCP/UDP 隧道、iptables DNAT、nginx stream、LVS |
| L7 | 协议内容(Host、URL、Header、SNI) | 是(未加密时) | nginx 的 proxy_pass、CDN、frp 的 HTTP 隧道 |
6. 几种转发方式的区别
| 方式 | 层级 | 是否重建连接 | 后端看到的来源 |
|---|---|---|---|
| iptables DNAT | 网关转发,L3/L4 | 否,同一条连接 | 只做 DNAT 时是访客 IP;配了 SNAT 后是网关 IP |
nginx stream | 用户态 L4 | 是 | nginx 的 IP(需 PROXY protocol 补) |
nginx proxy_pass | 用户态 L7 | 是 | nginx 的 IP(靠 X-Forwarded-For 补) |
frp TCP/UDP | 用户态 L4,经隧道 | 是 | frpc 的 IP,通常 127.0.0.1 |
frp HTTP | 用户态 L7,经隧道 | 是 | frpc 的 IP,但会自动追加 X-Forwarded-For |
| VPN | 封装 IP 包,L3 | 否 | 访客 IP |
网关转发与断链重建
iptables 的 NAT 是网关功能:这台机器要作为流量必经的网关,按预设规则把流量转发出去,改写地址只是让转发成立的手段(DNAT 改目的、SNAT 改源,两者一般配合使用)。连接本身不重建,所以它看不到也改不了应用层内容——不能按 Host 选后端、不能终止 TLS。
来源地址取决于配了什么:只做 DNAT 时源地址不变,内网服务能看到访客真实 IP(家用路由器的端口映射就是这样);但回程流量必须回到这台网关,实际部署里通常会同时做 SNAT 或 MASQUERADE,这时内网服务看到的就是网关地址。
nginx 和 frp 是另一种做法:断开连接、再向目标重建一条,所以能做 L7 的事(按 Host 选后端、改请求头、终止 TLS),代价是来源 IP 丢了,必须靠 X-Forwarded-For 或 PROXY protocol 带外补回来——这就是获取访客真实IP 那两套方案的由来。
在不在流量路径上
NAT 要求这台机器是流量必经的网关(有公网地址,且流量真的流经它);frp 不要求,因为连接是 frpc 从内网主动建出去的。这是两者最根本的差别,也是 frp 存在的意义。
另外,HTTPS 隧道是「选路在 L7、转发在 L4」:frps 读 ClientHello 里的 SNI 决定交给谁,但不解密、不改写,所以真实 IP 仍然只能走 PROXY protocol。frp 也不做 L3,不会给您一个虚拟网卡。
7. 按端口还是按域名
TCP/UDP隧道按远程端口区分:访客连到节点:远程端口,frps 就知道该交给哪条隧道,一条隧道占用一个端口。HTTP/HTTPS隧道按域名区分:多条隧道共用节点的 80/443,frps 按请求的 Host(HTTPS 按 ClientHello 里的 SNI)决定转给谁。
8. 一次访问的完整链路
访客 ──► 节点:远程端口 ──► frps ──► 工作连接 ──► frpc ──► 127.0.0.1:本地端口
9. 由此得到的结论
- frpc 不在线,隧道就不可用。frps 不会替您缓存请求,访客只会看到连接失败。
- 本地服务必须在 frpc 所在的机器上可达,默认是
127.0.0.1;改了本地服务的端口,隧道也要同步改。 - 速度取决于您家宽带的上行、节点带宽和您与节点之间的线路,延迟 = 访客到节点 + 节点到您。
- 流量经节点中转,不是点对点,也不是 VPN 或虚拟组网,不会改变您的公网 IP。