如何在Windows平台使用FRP


本文着重介绍了如何在Windows平台上使用FRP客户端进行内网穿透。

0. 前言

虽然此前已撰写文章:如何在Linux云上部署Frp和N2N服务

但是很显然,关于frp的安装已稍显落后,主要是原教程过于简单丧失基本安全性,且配置文件语法进行过更改,随后将会追加发布新版关于安装的详细教程。

遂本文着重讨论如何在Windows系统上使用frp客户端。

且配置文件按照新版toml语法格式编写,老版ini格式不再讨论。

其余系统暂时未更新,但逻辑大差不差,如有需要会酌情更新。

1. 下载程序包

为避免版权和病毒问题,程序包需自行前往Github下载,项目开源,荣获近100k的Star(当之无愧这一块)。

仓库地址:GitHub - fatedier/frp: A fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet.

进入仓库后,点击Releases,进入发布页,找到需要的发布版本,然后找到对应操作系统的包。

这里可能并没有Windows版本的包,请点击列表最后一行的「Show all xx assets」:

在展开的列表里,应该可以找到「frp_x.xx.x_windows_amd64.zip」的zip压缩文件,点击下载即可。

(ps. 应该没有人用arm架构的Windows吧...

千万别下载成darwin的版本,这是苹果的!!!

如果真的找不到,请复制以下链接,将版本号替换成最新版或者就使用v0.64.0,打开浏览器粘贴后回车即可下载:

https://github.com/fatedier/frp/releases/download/v0.64.0/frp_0.64.0_windows_amd64.zip

若因为各种原因无法访问GitHub,可联系站长获取,无风险但不担责 : )

2. 杀毒软件白名单

由于软件相关代码涉及反代,极有可能引发安全软件报毒或直接删除。

代码本身无风险,可查阅开源仓库,看不懂还介意者无话可说 : (

若被杀毒软件误删除,请加入白名单,否则后续软件运行时有可能再次被误删。

3. 解压程序包

解压缩。

这步应该不用解释了吧,Windows10原生支持zip,10以下的win系统自行使用解压软件。

解压后应该会出现以下五个文件,附文件介绍:

frpc.exe     ---    客户端程序
frpc.toml     ---    客户端配置文件
frps.exe     ---    服务端程序
frps.toml     ---    服务端配置文件
LICENSE         ---    许可证

很显然,本文讨论的使用,只需要使用其中的两个文件即可,分别是frpc.exefrpc.toml,其余的保留或删除均可。

4. 修改配置文件

这一步才是重点!

与所有基于frp套壳的软件(如樱花frp1、免费frp2等)一样,

需要知道所需隧道的协议、IP和端口,以及frp服务端的IP、监听端口,和可能有的认证。

具体填写需参照frp项目的文档并结合服务端的配置,或联系frp服务商获取配置文件。

这是一个简洁配置范例:

serverAddr = "xxx.xxx.xxx.xxx"        #frp服务端的IP或域名
serverPort = 7000                #frp服务端监听的端口,默认为7000
auth.method = "token"            #frp服务端认证方式
auth.token = "xxxxxxxx"            #token认证方式的口令

[[proxies]]
name = "test"                    #隧道名称,不可重复,重复造成报错无法启动请修改
type = "tcp"                    #隧道使用的协议,常用TCP/UDP、HTTP/HTTPS、XTCP
localIP = "127.0.0.1"                #本机服务使用的地址,一般为localhost
localPort = 25565                #本机服务使用的端口,Minecraft服务端默认为25565
remotePort = 25565                #映射后使用的端口,Minecraft地址默认为25565

其中,1-4行的内容需根据服务端提供的内容修改,7-11行可根据实际需要修改。

5. 启动客户端

  1. 通过cmd启动(不推荐使用)

    Win + R打开运行,输入cmd后回车,运行cmd。

    使用cd命令进入frp所在文件夹,例如:

    cd Helper\frp_0.64.0_windows_amd64

    或直接在文件资源管理器上方地址栏选中地址后(不要删除),直接输入cmd回车,即可在当前路径打开cmd。

    在cmd中输入代码并回车执行:

    frpc.exe -c ./frpc.toml
  2. 创建bat脚本启动(推荐使用)

    在当前目录下,新建一个文本文件,并改名为start.bat(需要打开文件扩展名)。

    右键文件,选择:编辑(E)。

    编写脚本如下:

    @echo off
    frpc.exe -c ./frpc.toml
    pause

    保存文件后双击启动。

若出现类似以下文本,则表明已成功创建隧道:

[I] [sub/root.go:149] start frpc service for config file [./frpc.toml]
[I] [client/service.go:314] try to connect to server...
[I] [client/service.go:306] [fe667e46c29f0574] login to server success, get run id [fe667e46c29f0574]
[I] [proxy/proxy_manager.go:177] [fe667e46c29f0574] proxy added: [test]
[I] [client/control.go:172] [fe667e46c29f0574] [test] start proxy success

注意,穿透过程中须全程保持cmd运行,不可关闭!如需关闭,请参照进阶教程1。

6. 修改防火墙策略

不可遗漏的一步。

若嫌麻烦直接关闭整个防火墙即可。

若不放心则手动在防火墙中修改策略:按Win+R键打开运行,输入wf.msc,打开「高级安全Windows Defender防火墙」,在入站和出站规则中分别添加对应规则,推荐使用程序,将frpc.exe加入规则,或使用端口手动指定均可。

基础使用教程到此结束,使用frp服务端的IP+映射后的端口(即配置文件第1行和第11行的参数)即可访问服务。如需更多信息请继续浏览~

7. 进阶教程1 - 注册服务

Windows系统最佳保活方案就是注册成服务。

但该方案适用于不需要经常改动参数的场景,例如mc服务端。

步骤很简单,下载nssm工具,解压后选择所需版本放入同一目录下,随后按图操作即可:

其中,第二步的启动指令,最后一项为服务名字,按需填写,也可在软件左下修改,更多指令双击软件会跳出介绍弹窗。

不出意外应该可以在系统服务中找到创建的服务。

8. 进阶教程2 - 常用协议的配置示例

serverAddr = "xxx.xxx.xxx.xxx"
serverPort = 7000
auth.method = "token"
auth.token = "xxxxxxxx"

# http示例
[[proxies]]
name = "yourname_http"
type = "http"
localIP = "192.168.0.2"
localPort = 5000
customDomains = ["nas.yourdomain.com"]
locations = ["/"]

# https示例
[[proxies]]
name = "yourname_https"
type = "https"
localIP = "192.168.0.2"
localPort = 5001
customDomains = ["nas.yourdomain.com"]

# ssh示例
[[proxies]]
name = "yourname_linux_ssh"
type = "tcp"
localIP = "192.168.0.3"
localPort = 22
remotePort = 22222

# 远程桌面示例
[[proxies]]
name = "yourname_windows10_rdp"
type = "tcp"
localIP = "192.168.0.4"
localPort = 3389
remotePort = 33333

# XTCP协议样例(基于p2p打洞穿透,利用fallback机制在打洞超时情况下回退stcp连接)
[[visitors]]
name = "stcp-visitor"
type = "stcp"
serverName = "stcp-test"
secretKey = "abc"
bindPort = -1
[[visitors]]
name = "xtcp-visitor"
type = "xtcp"
serverName = "xtcp-test"
secretKey = "abc"
bindAddr = "127.0.0.1"
bindPort = 9002
keepTunnelOpen = true
fallbackTo = "stcp-visitor"
fallbackTimeoutMs = 200

9. 进阶教程3 - 完整配置文件

配置文件来自CSDN博主「我可是森森呢」的文章:【全网最全】FRP内网穿透参数配置+服务器与客户端的简易配置+完整配置详解(Windows)_frp配置-CSDN博客

user = "user" #用户名,设置此参数后,代理名称会被修改为 {user}.{代理的name},避免代理名称和其他用户冲突。
serverAddr = "xxx.xxx.xxx.xxx" #【必填】连接服务端的地址。
serverPort = 7000 #【必填】连接服务端的端口,默认为 7000。
natHoleStunServer = "stun.easyvoip.com:3478" #xtcp 打洞所需的 stun 服务器地址,默认为 stun.easyvoip.com:3478。
dnsServer = "255.5.5.5" #使用 DNS 服务器地址,默认使用系统配置的 DNS 服务器,指定此参数可以强制替换为自定义的 DNS 服务器地址。
loginFailExit = true #第一次登陆失败后是否退出,默认为 true。
start = ["代理的name1", "代理的name2"] #指定启用部分代理,当配置了较多代理,但是只希望启用其中部分时可以通过此参数指定,默认为全部启用。
udpPacketSize = 1500 #代理 UDP 服务时支持的最大包长度,默认为 1500,服务端和客户端需要保持配置一致。
includes = ["配置2.toml", "配置3.toml"] #指定额外的配置文件目录,其中的 proxy 和 visitor 配置会被读取加载。

[metadatas] #附加元数据,会传递给服务端插件,提供附加能力,键值对格式,下面2行是样例
Key1 = "value1"
Key2 = "value2"

proxies = [ #代理配置样例,其他参数详见下方,此写法用于批量添加,遵循Json格式,注意逗号
    {name = "ssh", type = "tcp", localIP = "127.0.0.1", localPort = 22, remotePort = 6000},
    {name = "ssh", type = "tcp", localIP = "127.0.0.1", localPort = 22, remotePort = 6000}
]
[[proxies]] #代理配置的第二种写法与上面选其一,此写法用于单一添加
name = "支持中文" #【必填】代理名称。
type = "tcp" #【必填】代理类型,可选值为 tcp, udp, http, https, tcpmux, stcp, sudp, xtcp。
[proxies.transport] #代理网络层配置。
useEncryption = false #是否启用加密功能,启用后该代理和服务端之间的通信内容都会被加密传输,如果 frpc 启用了全局 TLS(即[transport.tls]内参数),则不需要再启用此参数。
useCompression = false #是否启用压缩功能,启用后该代理和服务端之间的通信内容都会被压缩传输。
bandwidthLimit = "10MB" #设置单个 proxy 的带宽限流,单位为 MB 或 KB,0 表示不限制,如果启用,默认会作用于对应的 frpc。
bandwidthLimitMode = "client" #限流类型,客户端限流或服务端限流,可选值为 client 和 server,默认为客户端限流。
proxyProtocolVersion = "v2" #代理协议的版本,可选值为 v1 和 v2。如果启用,则 frpc 和本地服务建立连接后会发送 proxy protocol 的协议,包含了原请求的 IP 地址和端口等内容。
[proxies.loadBalancer] #负载均衡配置,给代理分组。
group = "名称1" #【必填】负载均衡分组名称,用户请求会以轮询的方式发送给同一个 group 中的代理。
groupKey = "xx" #负载均衡分组密钥,用于对负载均衡分组进行鉴权,groupKey 相同的代理才会被加入到同一个分组中。
[proxies.healthCheck] #健康检查配置。
type = "tcp" #【必填】健康检查类型,可选值为 tcp 和 http,配置后启用健康检查功能,tcp 是连接成功则认为服务健康,http 要求接口返回 2xx 的状态码则认为服务健康。
timeoutSeconds = 3 #健康检查超时时间(秒),默认为 3s。
maxFailed = 1 #健康检查连续错误次数,连续检查错误多少次认为服务不健康,默认为 1。
intervalSeconds = 10 #健康检查周期(秒),每隔多长时间进行一次健康检查,默认为 10s。
path = "/health" #健康检查的 HTTP 接口,如果健康检查类型是 http,则需要配置此参数,指定发送 http 请求的 path,例如 /health。
httpHeaders = [ #http的请求头,遵循Json格式,注意逗号
    {name = "【必填】Header的name", value = "【必填】Header的value"},
    {name = "【必填】Header的name", value = "【必填】Header的value"}
]
#根据[[proxies]]的代理类型(type),有额外的参数可选,额外参数之间不可混用
#tcp和udp
remotePort = 6000 #服务端绑定的端口,用户访问服务端此端口的流量会被转发到对应的本地服务,默认值6000。
#http
customDomains = ["xx", "xx"] #【与下面必填其一】自定义域名列表
subdomain = "xx" #【与上面必填其一】子域名
locations = ["xx", "xx"] #URL 路由配置。
httpUser = "xx" #HTTP Basic Auth 用户名。
httpPassword = "xx" #HTTP Basic Auth 密码。
hostHeaderRewrite = "xx" #替换 Host Header。
[proxies.requestHeaders.set] #http协议下,对请求 Header 的操作配置,键值对格式,下面2行是样例
Key1 = "value1"
Key2 = "value2"
[proxies.responseHeaders.set] #http协议下,对响应 Header 的操作配置,键值对格式,下面2行是样例
Key1 = "value1"
Key2 = "value2"
routeByHTTPUser = "xx" #根据 HTTP Basic Auth user 路由。
#https
customDomains = ["xx", "xx"] #【与下面必填其一】自定义域名列表
subdomain = "xx" #【与上面必填其一】子域名
#tcpmux
customDomains = ["xx", "xx"] #【与下面必填其一】自定义域名列表
subdomain = "xx" #【与上面必填其一】子域名
httpUser = "xx" #用户名,如果配置此参数,通过 HTTP CONNECT 建立连接时需要通过 Proxy-Authorization 附加上正确的身份信息。
httpPassword = "xx" #密码。
routeByHTTPUser = "xx" #根据 HTTP Basic Auth user 路由。
multiplexer = "xx" #复用器类型,目前仅支持 httpconnect。
#stcp和sudp,和xtcp。
secretKey = "xx" #密钥,服务端和访问端的密钥需要一致,访问端才能访问到服务端。
allowUsers = ["*", "xx"] #允许访问的 visitor 用户列表,默认只允许同一用户下的访问者访问,配置为 * 则允许任何访问者访问。

[proxies.plugin] #客户端插件配置,如果启用了客户端插件,则不需要配置 localIP 和 localPort,流量会由客户端插件接管。不同的插件类型对应不同的配置。
#以下配置选其一,配置下方的参数不可混用
#HTTPProxyPluginOptions配置
type = "http_proxy"
httpUser = "xx" #HTTP 代理用户名。
httpPassword = "xx" #HTTP 代理密码。
#Socks5PluginOptions配置
type = "socks5"
username = "xx" #用户名
password = "xx" #密码
#StaticFilePluginOptions配置
type = "static_file"
localPath = "xx" #【必填】静态文件所在本地路径。
stripPrefix = "xx" #去除用户 HTTP 请求 Path 的特定前缀。
httpUser = "xx" #HTTP Basic Auth 用户名。
httpPassword = "xx" #HTTP Basic Auth 密码。
#UnixDomainSocketPluginOptions
type = "unix_domain_socket"
unixPath = "xx" #【必填】UNIX 域套接字的地址。
#HTTP2HTTPSPluginOptions配置
type = "http2https"
localAddr = "xx" #【必填】本地 HTTPS 服务地址。
hostHeaderRewrite = "xx" #替换 Host header。
#HTTPS2HTTPPluginOptions配置
type = "https2http"
localAddr = "xx" #【必填】本地 HTTPS 服务地址。
hostHeaderRewrite = "xx" #替换 Host header。
enableHTTP2 = true #是否启用 HTTP/2,默认启用。
crtPath = "xxx.pen" #TLS 证书文件路径。
keyPath = "xxx.key" #TLS 密钥文件路径。
#HTTPS2HTTPSPluginOptions配置
type = "https2https"
localAddr = "xx" #【必填】本地 HTTPS 服务地址。
hostHeaderRewrite = "xx" #替换 Host header。
enableHTTP2 = true #是否启用 HTTP/2,默认启用。
crtPath = "xxx.pen" #TLS 证书文件路径。
keyPath = "xxx.key" #TLS 密钥文件路径。
[proxies.plugin.requestHeaders.set] #用于3个http(s)2http(s)的配置中对请求 Header 的操作配置。键值对格式,下面2行是样例
Key1 = "value1"
Key2 = "value2"
#TLS2RawPluginOptions配置
type = "tls2raw"
localAddr = "xx" #【必填】本地 HTTPS 服务地址。
crtPath = "xxx.pen" #TLS 证书文件路径。
keyPath = "xxx.key" #TLS 密钥文件路径。

[proxies.annotations] #代理的注释信息,会被展示在 server 的 dashboard 中。键值对格式,下面2行是样例
Key1 = "value1"
Key2 = "value2"
[proxies.metadatas] #附加元数据,会传递给服务端插件,提供附加能力。。键值对格式,下面2行是样例
Key1 = "value1"
Key2 = "value2"

visitors = [ #访问者样例,其他参数详见下方,此写法用于批量添加,遵循Json格式,注意逗号
    {}
]
[[visitors]] #访问者配置的第二种写法与上面选其一,此写法用于单一添加
name = "xx" #【必填】访问者名称。
type = "stcp" #【必填】访问者类型,可选值为 stcp, sudp, xtcp。
secretKey = "xx" #密钥,服务端和访问端的密钥需要一致,访问端才能访问到服务端。
serverUser = "xx" #要访问的 proxy 所属的用户名,如果为空,则默认为当前用户。
serverName = "xx" #【必填】要访问的 proxy 名称。
bindAddr = "127.0.0.1" #访问者监听的本地地址,通过访问监听的地址和端口,连接到远端代理的服务。
bindPort = 22 #【必填】访问者监听的本地端口,如果为 -1,表示不需要监听物理端口,通常可以用于作为其他 visitor 的 fallback。
[visitors.transport] #访问者网络层配置。
useEncryption = false #是否启用加密功能,启用后该代理和服务端之间的通信内容都会被加密传输,如果 frpc 启用了全局 TLS(即[transport.tls]内参数),则不需要再启用此参数。
useCompression = false #是否启用压缩功能,启用后该代理和服务端之间的通信内容都会被压缩传输。
#xtcp的额外可选参数
protocol = "quic" #隧道底层通信协议,可选 quic 和 kcp,默认为 quic。
keepTunnelOpen = false #是否保持隧道打开,如果开启,会定期检查隧道状态并尝试保持打开。
maxRetriesAnHour = 8 #每小时尝试打开隧道的次数,默认值为 8。
minRetryInterval = 90 #重试打开隧道的最小间隔时间,单位: 秒,默认为 90s。
fallbackTo = "xx" #回退到的其他 visitor 名称。
fallbackTimeoutMs = 2000 #连接建立超过多长时间(ms) 后回退到其他 visitor。

[auth] #鉴权配置
method = "token" #鉴权方式,可选值为 token 或 oidc,默认为 token。
additionalScopes = ["xx", "xx"] #鉴权信息附加范围,可选值为 HeartBeats 和 NewWorkConns
token = "xx" #在 method 为 token 时生效,客户端需要设置一样的值才能鉴权通过。
[auth.oidc] #oidc 鉴权配置
clientID = "xx"
clientSecret = "xx"
audience = "xx"
scope = "xx"
tokenEndpointURL = "xx"
[auth.oidc.additionalEndpointParams] #键值对格式,下面2行是样例
Key1 = "value1"
Key2 = "value2"

[transport] #全局网络层配置。
protocol = "tcp" #和 frps 之间的通信协议,可选值为 tcp, kcp, quic, websocket, wss。默认为 tcp。
dialServerTimeout = 10 #连接服务端的超时时间,默认为 10s。
dialServerKeepalive = 10 #和服务端底层 TCP 连接的 keepalive 间隔时间,单位秒。
connectServerLocalIP = "127.0.0.1" #连接服务端时所绑定的本地 IP。
proxyURL = "xx://user:pwd@host:port" #连接服务端使用的代理地址,格式为 {protocol}://user:passwd@192.168.1.128:8080 protocol 目前支持 http、socks5、ntlm。
poolCount = 100 #连接池大小。
tcpMux = true #TCP 多路复用,默认启用。
tcpMuxKeepaliveInterval = 10 #tc复用的心跳检查间隔时间。
heartbeatInterval = 30 #向服务端发送心跳包的间隔时间,默认为 30s。建议启用 tcp_mux_keepalive_interval,将此值设置为 -1。
heartbeatTimeout = 90 #和服务端心跳的超时时间,默认为 90s。
[transport.quic] #全局QUIC协议配置参数
keepalivePeriod = 10 #QUIC保活探测间隔默认值为 10 秒。
maxIdleTimeout = 30 #QUIC超时时间,默认值为 30 秒。
maxIncomingStreams = 100000 #QUIC最大输入流大小,单位字节,默认值为 100000。
[transport.tls] #全局TLS 协议配置。
enable = true #是否和服务端之间启用 TLS 连接,默认启用。
disableCustomTLSFirstByte = true #启用 TLS 连接时,不发送 0x17 特殊字节。默认为 true。当配置为 true 时,无法和 vhostHTTPSPort 端口复用。
certFile = "xx.cert" #【必填】TLS 证书文件路径。
keyFile = "xx.key" #【必填】TLS 密钥文件路径。
trustedCaFile = "xx" #CA 证书文件路径。
serverName = "" #TLS 服务名称。

10. 退阶教程 - 懒人GUI法

  1. 开源项目:FRP 管理器

    仓库地址:GitHub - koho/frpmgr: A user-friendly desktop GUI client for FRP on Windows.

    简要介绍:FRP 管理器是一个多节点、图形化反向代理工具,专为 Windows 上的 FRP 设计。它允许用户轻松设置反向代理,而无需编写配置文件。FRP 管理器提供了一套完整的解决方案,包括编辑器、启动器、状态跟踪和热重载。

  2. 公益项目:Frpee-Gui

    官网地址:Frpee-Gui-frp客户端-内网穿透软件-免费内网穿透

    简要介绍:Frpee-Gui 是一款基于frp的可视化应用,目的为自建frp服务的开发者免费提供操作方便的可视化客户端 。

  3. 开源项目:FRP 桌面

    仓库地址:GitHub - luckjiawei/frpc-desktop: frp跨平台桌面客户端,可视化配置,轻松实现内网穿透! 支持所有frp版本

    简要介绍:FRP跨平台桌面客户端,可视化配置,轻松实现内网穿透!支持所有frp版本 / 开机自启 / 可视化配置 / 免费开源

11. 资料 - 部分游戏默认

以下收集了部分游戏联机功能使用的默认端口及协议:

  • Minecraft Java(我的世界Java版):25565 = TCP(对局域网开放为随机端口,此处为服务端默认端口)
  • Minecraft Bedrock(我的世界基岩版):19132 = UDP
  • Unturned(未转变者):27015/27015+1 = UDP(端口及端口+1,双开隧道)
  • Arma III(武装突袭3):2302 = UDP
  • Palworld(幻兽帕鲁):8211 = UDP
  • Stardew Valley(星露谷物语):24642 = UDP
  • Dyson Sphere Program(戴森球计划+Nebula MOD):8469 = TCP
  • Terraria(泰拉瑞亚):7777 = TCP
  • 7 Days to Die(7日杀):26900 = TCP、26900 = UDP、26900+1 = UDP、26900+2 = UDP(四开隧道)
  • Project Zomboid(僵尸毁灭工程):16261/16261+1 = UDP
  • Don't Starve Together(饥荒:联机版):10999/10999-1 = UDP
  • DDraceNetwork(DDNet):8303 = UDP
  • Rust(腐蚀):28015 = UDP、28016 = TCP

如有补充欢迎联系站长~

12. 常见问题

  1. connect to local service error:

    描述:连接本地服务失败。

    原因:通常是服务未提前启动,frp与本地服务使用的端口通信失败,例如mc对局域网开放,需要先对局域网开放后在修改frp配置文件后再启动frp。

    解决:通常会自恢复,不过重启frp也可以解决。

  2. 等待反馈ing...

13. 公益FRP站点

关于该篇将会新开一篇文章,预计会不定期更新,敬请关注~

另外,站长也有公益frp节点,系阿里云200M宽带轻量,不过阿里有名的超开,200M共享宽带高峰估计也够呛,有需要可联系站长~

14. 后记

拖了蛮久了,本来老早就要写了,咕咕咕~

其实是不想把安装和使用分开的,毕竟使用真的不麻烦,但是发现使用比安装的场景多很多很多倍,遂还是单独写一篇。

又觉得单写教程好像太少了,遂塞了不少内容,但愿没有影响观感Orz

如果有什么欠妥、遗漏、谬误等欢迎联系站长修改捏~

玩的愉快~

声明:ItsNotch_404|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - 如何在Windows平台使用FRP


Despite The Regrets, But Never Regret.