frp搭建内网穿透工具
原创 已于 2025-01-24 23:30:10 修改 · 粉丝可见 · 1.4k 阅读 · 12 · 14 GEO检测 · 编辑
文章链接:https://blog.csdn.net/hacker_51/article/details/143892237
目录
[TOC]
简介
FRP(Fast Reverse Proxy)是一款开源、简洁易用、高性能的内网穿透和反向代理软件,支持TCP、UDP、HTTP、HTTPS等协议。它允许用户将内网服务以安全、便捷的方式通过具有公网IP节点的中转暴露到公网。
中文官网: frp
中文文档: 文档 | frp
功能特点
内网穿透 :FRP支持内网穿透功能,能够实现公网服务访问内网服务器。
通用性 :支持多种协议和服务类型,如HTTP、TCP、UDP等,可用于各种不同场景。
安全性 :支持数据加密、身份验证和IP白名单等安全机制,保障数据和用户信息安全。
高性能 :采用Go语言编写,具有高性能和高并发性能,能够满足大规模并发请求需求。
易用性 :使用简单,配置文件清晰明了,支持多平台部署和使用。
穿透流程
服务端运行在具有公网 IP 的服务器上,并监听某个端口,等待客户端连接。
客户端运行在需要穿透的内网机器上,与服务器建立之后,相当于客户端和服务端之间建立了一条隧道,访问服务端的请求会通过隧道转发给内网主机。
当互联网用户连接/访问服务器监听的端口时,服务器将用户请求转发到内网客户端,实现内网穿透。
搭建方式
准备工作
1、一台具有公网 IP 的主机。
2、下载 frp 软件,下载地址: Releases · fatedier/frp · GitHub

服务端部署
连接自己有公网 IP 的地址之后,查看你的系统架构是ARM还是AMD64(也称为x86_64),根据具体情况下载相应的安装包
执行命令查看系统框架.

我的服务器是 amd64 ,所以这里我选择下载这个版本的安装包。

上传到服务器。并解压。
1
| tar -zxf frp_0.60.0_linux_amd64.tar.gz
|
进入解压后的文件,并打开服务端配置文件
配置文件信息如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| bindPort = 7000 # frp服务的特定端口,防火墙也需放开该端口 # 服务端仪表盘的端口, 可以用浏览器访问查看frp服务状态信息 webServer.addr = "0.0.0.0" # 后台管理地址,默认是127.0.0.1,如果是公网访问则改成0.0.0.0 webServer.port = 7500 # 后台管理端口 webServer.user = "admin" # (可选)后台登录用户名 webServer.password = "admin" # (可选)后台登录密码 #transport.tls.force = true # 服务端将只接受 TLS链接 auth.method = 'token' # 客户端访问验证方式 auth.token = "54321" # 客户端访问验证密码,frpc要与frps一致 # 自定义的监听的端口,所有对服务器该端口访问将被转发到本地内网,做了反向代理可不处理防火墙放行 vhostHTTPPort = 8080 #vhostHTTPSPort = 45443
|
启动frp。并且在云服务的安全组以及防火墙上放行对应端口。
输入地址(公网ip:端口号)可以查看服务端管理页面。

客户端部署
主要配置介绍信息如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| # frpc.toml transport.tls.enable = true # 从 v0.50.0版本开始,transport.tls.enable的默认值为 true serverAddr = "192.168.1.101" # 服务端ip serverPort = 7000 # 服务端端口 auth.method = 'token' # 客户端访问验证方式 auth.token = '54321' # 客户端访问验证密码 [[proxies]] name = "dy_mysql" # 客户端服务名 type = "tcp" # 通讯方式 localIP = "127.0.0.1" # 客户端的ip(固定) localPort = 3306 # 客户端服务端口 remotePort = 13306 # 映射到服务端端口(服务器需放行) [[proxies]] name = "dy_video" # 客户端服务名_一个监控摄像头 type = "tcp" # 通讯方式 localIP = "192.168.6.8" # 客户端的ip(固定) localPort = 5522 # 客户端服务端口 remotePort = 15522 # 映射到服务端端口(服务器需放行) [[proxies]] name = "test-tcp" type = "tcp" localIP = "127.0.0.1" # 需要暴露的服务的IP localPort = 9000 # 将本地9000端口的服务暴露在公网的6060端口 remotePort = 6060 # 暴露服务的公网入口 [[proxies]] name = "ssh" type = "tcp" localIP = "127.0.0.1" localPort = 22 remotePort = 6000 #customDomains = ["xxx.xxx.xxx.xxx"] [[proxies]] name = "web" type = "http" localIP = "127.0.0.1" localPort = 80 customDomains = ["域名或ip"]
|
这里因为我用于跟伙伴们调试项目开发用处,这里我只配置一个http服务。(以若依框架为例子)
配置信息
解压文件后,用文本编辑软件打开 frpc.toml, 修改配置,添加映射关系
1 2 3 4 5 6 7 8 9 10 11 12 13
| # frpc.toml transport.tls.enable = true # 从 v0.50.0版本开始,transport.tls.enable的默认值为 true serverAddr = "192.168.101" # 服务端ip serverPort = 7000 # 服务端端口 auth.method = 'token' # 客户端访问验证方式 auth.token = '54321' # 客户端访问验证密码 [[proxies]] name = "web" type = "http" localIP = "127.0.0.1" localPort = 80 customDomains = ["192.168.101"]
|
本地打开我们的若依框架项目测试是否运行成功

地址栏中输入 cmd 回车打开终端装备启动工具。

终端输入命令启动工具

使用公网IP测试,穿透成功

----------------------------------------------2025/1/21 更新----------------------------------------------
搭建多个端口web服务
无域名方式搭建
由于本人域名转入原因,暂时无法通过域名进行解析穿透访问,其中又因为手底下有多个web服务需求。网上又找了许多优质文章,但是并不是最新版的。于是我换位思考了一下,旧版的可以指定端口访问,是不是新版也是保留的。
服务端配置 frps.toml
因为新版中包括了一个 vhostHTTPPort 指定web端口访问 这个硬生生锁死访问web端口
所以我们需要将它注释掉或者删掉即可,一下是我的配置,可以参考
frps.toml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| bindPort = 7000 # frp服务的特定端口,防火墙也需放开该端口
# 服务面板可查看frp服务状态信息 webServer.addr = "0.0.0.0" # 后台管理地址,默认是127.0.0.1,如果是公网访问则改成0.0.0.0 webServer.port = 7080 # 后台管理端口 webServer.user = "admin" # (可选)后台登录用户名 webServer.password = "admin" # (可选)后台登录密码
#transport.tls.force = true # 服务端将只接受 TLS链接 auth.method = 'token' # 客户端访问验证方式 auth.token = "admin" # 客户端访问验证密码,frpc要与frps一致
# 自定义的监听的端口,所有对服务器该端口访问将被转发到本地内网,做了反向代理可不处理防火墙放行 #vhostHTTPPort = 8081 #vhostHTTPSPort = 45443
|
客户端配置 frpc.toml
我参考 ssh 服务的 tcp 类型,将web 服务的type 也更改为 tcp 即可指定端口了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| # frpc.toml transport.tls.enable = true # 从 v0.50.0版本开始,transport.tls.enable的默认值为 true serverAddr = "192.168.1.101" # 服务端ip serverPort = 7000 # 服务端端口 auth.method = 'token' # 客户端访问验证方式 auth.token = 'admin' # 客户端访问验证密码 [[proxies]] name = "web" type = "tcp" #注意web 服务设定type 为 tcp 即可指定端口 localIP = "127.0.0.1" localPort = 8080 remotePort = 8081
[[proxies]] name = "web2" type = "tcp" #注意web 服务设定type 为 tcp 即可指定端口 localIP = "127.0.0.1" localPort = 7070 remotePort = 7070
[[proxies]] name = "ssh" type = "tcp" localIP = "192.168.76.129" localPort = 22 remotePort = 6060
|
随后测试访问


可以看到成功访问两个指定web服务的端口。
----------------------------------------------2025/1/24 更新----------------------------------------------
域名方式搭建
倒腾了一整天,根据文档终于弄懂了一点。
域名方式的,type 为:http 搭建站点中需要开启 指定 vhostHTTPSPort 端口
随后 加上服务端的 subdomainHost
服务端配置 frps.toml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| bindPort = 7000 # frp服务的特定端口,防火墙也需放开该端口
# 服务面板可查看frp服务状态信息 webServer.addr = "0.0.0.0" # 后台管理地址,默认是127.0.0.1,如果是公网访问则改成0.0.0.0 webServer.port = 7080 # 后台管理端口 webServer.user = "admin" # (可选)后台登录用户名 webServer.password = "admin" # (可选)后台登录密码
#transport.tls.force = true # 服务端将只接受 TLS链接 auth.method = 'token' # 客户端访问验证方式 auth.token = "admin" # 客户端访问验证密码,frpc要与frps一致
# 自定义的监听的端口,所有对服务器该端口访问将被转发到本地内网,做了反向代理可不处理防火墙放行 vhostHTTPPort = 28888 #这里一定要开启 #vhostHTTPSPort = 45443
# 自己购买的主域名 subdomainHost = "example.com"
|
客户端配置 frpc.toml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| # frpc.toml transport.tls.enable = true # 从 v0.50.0版本开始,transport.tls.enable的默认值为 true serverAddr = "你的服务器IP地址" # 服务端ip serverPort = 7000 # 服务端端口 auth.method = 'token' # 客户端访问验证方式 auth.token = 'admin' # 客户端访问验证密码
[[proxies]] name = "web1" type = 'http' localIP = "127.0.0.1" localPort = 9898 subdomain = "test2" # 子域名前缀
[[proxies]] name = "web2" type = "http" localIP = "127.0.0.1" localPort = 7979 subdomain = "test" # 子域名前缀
[[proxies]] name = "web3" type = "http" localIP = "127.0.0.1" localPort = 8081 subdomain = "up" # 子域名前缀
|
随后启动。这里有个小坑。当启动时报错。
1
| [client/service.go:298] [02ca45add03976b7] connect to server error: i/o deadline reached
|
那么有可能自己的网络问题导致的波动,多尝试强制停止frpc程序,重连就行了。
也要注意!!如果输出
1
| [proxy/proxy_manager.go:173] [02ca45add03976b7] proxy added: [web1 web2 web3]
|
这个并不代表成功穿透连上,只能仅仅代表端口添加成功。需要耐心等待,当出现
1 2 3
| [I] [client/control.go:168] [02ca45add03976b7] [web1] start proxy success [I] [client/control.go:168] [02ca45add03976b7] [web3] start proxy success [I] [client/control.go:168] [02ca45add03976b7] [web2] start proxy success
|
表示启动端口成功,这就是穿透成功的例子。
随后测试访问

说明穿透成功了,至于其它页面,也是同理可以成功访问的
由于这里每次访问都要带上 域名:端口 我们可以通过Nginx进行反向代理即可。
Nginx 反向代理服务配置
以下是我借鉴大佬的配置,我们根据模板改成自己需要的即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| server { listen 80; server_name test.example.com;
location / { log_not_found off; access_log off;
proxy_pass http://test.example.com:8082; proxy_http_version 1.1; proxy_connect_timeout 159s; proxy_send_timeout 600; proxy_read_timeout 600; proxy_buffer_size 64k; proxy_buffers 16 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; proxy_pass_header Set-Cookie; proxy_redirect off; proxy_hide_header Vary; proxy_set_header Accept-Encoding ''; add_header Cache-Control no-store; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; 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 Cache-Control no-cache; proxy_set_header Connection Keep-Alive; }
|
通过反向代理后,我们可以直接访问域名即可。