写在开头

本文的目标是帮助想要使用frp来进行内网穿透/p2p打洞 但是不知道如何配置的人 如果本篇内容对你有帮助 在评论区留言就好啦 我会很感谢的哦

第一次写这类文章 可能会有疏漏和错误的地方 如有发现请在评论区指正 轻喷 感谢各位的支持

项目地址:https://github.com/fatedier/frp/tree/dev
官方文档:https://gofrp.org/zh-cn/docs/reference/
吐槽一下 这个文档是真的难读懂


frp介绍

frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议,且支持 P2P 通信。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。

frp支持两种工作模式 分别是 Client-Server(即客户端-服务端) 和 Client-Server-Client (即客户端-服务端-客户端)前者较为常用 支持的模式有 tcp udp http https tcpmux 而后者则支持stcp sudp xtcp等模式 具体如何使用后文会讲到


基础配置

首先 frp分为 frpcfrps 其中 frps为服务端 frpc则是客户端
而frp v2使用的配置为toml(好像还兼容ini 本文以toml为例)而具体又可以分为 [common] [[visitors]][[proxies]] 接下来会分别介绍


通用配置

配置这部分内容 需要在toml配置文件里加上[common] 举个栗子

[common]
to = "/var/log/frp/" #日志输出目录
level  = "info" #日志等级
maxDays = 5 #日志保留天数
......

更多参数详见 https://gofrp.org/zh-cn/docs/reference/common/

注意 这部分内容不是必须的 如果你不进行配置 也不会影响你正常使用frp

和他的名字一样 这部分的配置在服务端和客户端都可以使用 你只需要把他加到配置文件中即可


服务端配置-frps

这里就是配置 frps 的地方了 其中一般需要配置的就是 bindAddrbindPort 他们分别是frps绑定的地址和端口 即frps所在机器监听的IP和 对外开放 的端口

一般情况下 bindAddr配置为0.0.0.0即可 bindPort 需要根据机器的实际情况来进行配置 默认为 7000 如果有NAT或其他需求 改为可用端口即可

此外 强烈建议 配置auth字段 特别是在公网的机器 这对你的机器安全十分重要 具体配置方法如下

auth.method = "token" #这里以token验证方式举例
auth.token = "Your_token" #这里填写你希望使用的token 可以理解为密码 与你的frpc所填写的字段要一致

完整配置演示

bindAddr = "0.0.0.0"
bindPort = 7000 #使用时请替换为实际的端口 当然如果7000端口是可用的也可以不修改
auth.method = "token" #这里以token验证方式举例
auth.token = "Your_token" #这里填写你希望使用的token 可以理解为密码

更多参数详见 https://gofrp.org/zh-cn/docs/reference/server-configures/#authserverconfig


客户端配置-frpc

这里是重头戏 也是配置里最难理解的部分 至少对我来说是

客户端配置分为两部分 visitorsproxies 还记得我们说过frp分为两种工作模式吗 当你在使用 Client-Server模式的时候 不需要编写 visitors 部分配置 只需要配置 proxies即可

tcp/udp模式配置

proxies部分在frpc的配置中是最为重要的一部分 这里我们还是举例子来说明

假设你本地的80端口有一个服务 你需要让其他人访问这个服务 这个时候你就可以借助frp实现

serverAddr = "123.45.67.8" #此处需要替换为与你frps服务器所在的ip地址
serverPort = 7000 #此处替换为你frps实际运行的端口
auth.method = "token" 
auth.token = "Your_token" #此处要与frps的token一致

[[proxies]]
name = "NAME" #proxies的名字 具有唯一性 不能重复
type = "tcp/udp" #这里的类型根据你的服务所需要的网络类型来调整
localIP = "127.0.0.1" #默认为127.0.0.1 如有特殊需求可修改该项
localPort = 80 #这里是服务所在端口 即需要转发出去的端口
remotePort = 8080 #这里是你需要在公网/frps侧访问的端口 比如你的公网ip为 123.456.78.9 那么在访问的时候就是123.45.67.8:8080

注意 remotePort字段为tcpudp模式独有 在使用其他模式的时候不用填写该字段

现在 我们还需要启动上文配置好的frps的服务 此时 我们便可以通过访问公网IP:8080来实现访问部署在内网80端口的服务了

stcp/sudp/xtcp模式配置

这三种模式中 所使用的模式为Client-Server-Client 即以服务器作为中转 转发proxiesvisitor之间的流量 前两种使用较少 因为他们需要在两个客户端都开启frpc客户端

第三个比较特殊 xtcp就是人们常说的打洞 如果打洞成功 流量就不再需要经过服务器进行中转了 这里先介绍stcpsudp

再举个栗子 电脑A的80端口运行者一个服务 我需要在电脑B的8080端口访问他 此时

frpc-proxies 侧配置

serverAddr = "123.45.67.8" #此处需要替换为与你frps服务器所在的ip地址
serverPort = 7000 #此处替换为你frps实际运行的端口
auth.method = "token" 
auth.token = "Your_token" #此处要与frps的token一致

[[proxies]]
name = "NAME" #要求同上
type = "stcp/sudp" #根据要求选择
localIP = "127.0.0.1" #同上
localPort = "80" #同上
secretKey = "keys" #可选 stcp/sudp的密钥 如果设置了该值 visitors中密钥需要与此处一致

frpc-visitors 侧配置

serverAddr = "123.45.67.8" #此处需要替换为与你frps服务器所在的ip地址
serverPort = 7000 #此处替换为你frps实际运行的端口
auth.method = "token" 
auth.token = "Your_token" #此处要与frps的token一致

[[visitors]]
name = "NAME" #这里要和 proxies 中的name相同
type = "stcp/sudp" #同上
bindAddr = "127.0.0.1" #如无特殊要求 保持为127.0.0.1即可
bindPort = 8080 #此处为你需要在frpc的visitors端 即访问者使用的端口
secretKey = "Keys" #可选 stcp/sudp的密钥 如果设置了该值 proxies中密钥需要与此处一致

这里visitorsbindPort和上面tcp/udpremotePort有点类似 所指向的端口即为访问者使用的端口 此处为8080

配置完成后 我们分别在电脑A用proxies配置启动frpc再在电脑B启动visitors配置的frpc 然后我们还需要启动一个frps服务 此时 我们可以在电脑B访问8080端口 实现访问电脑A80端口的服务

使用frpc/frps时 可以通过 ./frpc -c 来指定配置文件位置 如./frpc -c ./frpc.toml 即为指定在当前目录下名为 ./frpc.toml的配置文件

xtcp模式配置

xtcp即为我们常说的打洞 通过stun服务器的协助 使得连接双方可以不经过服务器的中转 直接进行连接 即不需要消耗服务器流量 并且延迟相对较低 不过鉴于国内网络环境 xtcp的打洞失败概率较大 需要配合fallback故障转移使用 下面为配置示例

frpc-proxies 侧配置

serverAddr = "123.45.67.8" #此处需要替换为与你frps服务器所在的ip地址
serverPort = 7000 #此处替换为你frps实际运行的端口
auth.method = "token" 
auth.token = "Your_token" #此处要与frps的token一致

[[proxies]]
name = "NAME" #要求同上
type = "xtcp" 
localIP = "127.0.0.1" #同上
localPort = "80" #同上
secretKey = "keys" #可选 xtcp的密钥 如果设置了该值 visitors中密钥需要与此处一致

frpc-visitors 侧配置

serverAddr = "123.45.67.8" #此处需要替换为与你frps服务器所在的ip地址
serverPort = 7000 #此处替换为你frps实际运行的端口
auth.method = "token" 
auth.token = "Your_token" #此处要与frps的token一致

[[visitors]]
name = "NAME" #这里要和 proxies 中的name相同
type = "xtcp"
bindAddr = "127.0.0.1" #如无特殊要求 保持为127.0.0.1即可
bindPort = 8080 #此处为你需要在frpc的visitors端 即访问者使用的端口
secretKey = "Keys" #可选 xtcp的密钥 如果设置了该值 proxies中密钥需要与此处一致
protocol = "quic/kcp" #可选 默认为quic
fallbackTo = "visitors_NAME" #可选 
keepTunnelOpen	= true/false #是否保持隧道打开 建议开启
  1. 如果服务对延迟敏感 可以将protocol切换为kcp 有兴趣可自行了解这两个协议的区别
  2. 使用xtcp模式时 建议填写fallbackTo字段 此时 新建一个非xtcp类型的visitors和对应的proxiestcp/stcp等 配置文件中需要填写的部分按需填写 然后visitors中的bindPort字段填写为-1 即可实现故障转移

更多参数 详见 https://gofrp.org/zh-cn/docs/reference/visitor/#visitortransport

此时 我们便完成了frp基本的配置 这里的部分可以满足大部分用户的需求 至于其他没有讲到的部分 感兴趣可以自行查阅文档 有机会可能还会再写一篇来讲一下 摸了


尾声

写这篇文章的初衷是最近在折腾frp 过程中踩了许多的坑 于是借此机会来写一篇blog 锻炼练手的同时 也希望能帮助到在学习使用frp的时候遇到困难的同学 如果本文对你有帮助 不妨转发给身边有类似需求的朋友 感谢您的分享

同时 如果文中有错误或疏漏的地方 也希望大家能在评论区中指出 感谢各位的支持~

特别鸣谢 @SakuraKooi 对本文的大力支持