【Linux】内网穿透原理
- 一、前言
-
- [1.1 内网穿透](#1.1 内网穿透)
- [1.2 应用场景](#1.2 应用场景)
- 二、内网穿透的核心原理
-
- [2.1 角色简介](#2.1 角色简介)
- [2.2 内网穿透的工作流程](#2.2 内网穿透的工作流程)
- [2.3 内网穿透的主流实现模式](#2.3 内网穿透的主流实现模式)
- [三、FRP 内网穿透工具](#三、FRP 内网穿透工具)
-
- [3.1 frp 工作原理](#3.1 frp 工作原理)
- [3.2 frp 配置](#3.2 frp 配置)
-
- [3.2.1 服务端配置](#3.2.1 服务端配置)
- [3.2.2 客户端配置](#3.2.2 客户端配置)
- [3.3 连接验证](#3.3 连接验证)
- [四、frp 点对点内网穿透【p2p 模式】和 stcp](#四、frp 点对点内网穿透【p2p 模式】和 stcp)
-
- [4.1 原理讲解](#4.1 原理讲解)
- [4.2 配置步骤](#4.2 配置步骤)
- [4.3 xtcp 打洞失败自动回退到stcp](#4.3 xtcp 打洞失败自动回退到stcp)
- 五、内网穿透【应用】
-
- [5.1 本地 Web 服务(tcp 模式通用)](#5.1 本地 Web 服务(tcp 模式通用))
- [5.2 我的世界联机(xtcp 点对点模式)](#5.2 我的世界联机(xtcp 点对点模式))
- [5.3 关闭 Windows11 防火墙](#5.3 关闭 Windows11 防火墙)
- 六、进阶配置【可选】
-
- [6.1 配置为 service 文件](#6.1 配置为 service 文件)
- [6.2 新增日志](#6.2 新增日志)
- [6.3 安全性增强](#6.3 安全性增强)
一、前言
1.1 内网穿透
内网穿透: 也叫 NAT 穿透,是一种打破网络隔离的专业网络技术,能够让公网环境中的设备,直接访问到处于局域网(内网)环境中、无独立公网 IP 的设备或服务,实现公网到内网的双向通信。
公网 IP: 互联网上全球唯一、可直接路由的 IP 地址,能被任意公网设备直接寻址和访问,是互联网通信的基础地址。
内网 IP: 局域网内的私有 IP 地址(标准网段为 192.168.x.x 、10.x.x.x 、172.16.x.x - 172.31.x.x ),仅在当前局域网内有效,无法被公网设备直接识别和访问。
NAT: (Network Address Translation,网络地址转换)是家用路由器、企业网关的核心功能,核心目的是解决 IPv4 公网地址枯竭的问题,实现局域网内多设备共享同一个公网 IP 访问互联网。其核心工作逻辑是:在网关建立 「内网 IP: 端口 <-> 公网 IP: 端口」 的动态映射表,只有内网设备主动向外网发起连接时,才会生成对应的映射条目;外网设备无法主动向内网设备发起连接,因为网关没有对应的映射规则,会直接拦截请求。
NAT 的 4 种常见类型(按穿透难度从低到高):
- 完全锥形 NAT: 内网设备一旦建立对外的映射,任何公网 IP 和端口都可以通过该公网映射地址访问内网设备,穿透难度最低。
- 地址受限锥形 NAT: 只有内网设备主动访问过的公网 IP,才能通过映射地址访问内网,端口无限制,穿透难度较低。
- 端口受限锥形 NAT: 只有内网设备主动访问过的公网 IP + 端口组合,才能通过映射地址访问内网,限制更严格,穿透难度中等。
- 对称型 NAT: 内网设备对不同的目标 IP / 端口,会生成完全不同的公网映射端口,无法提前预测映射规则,常规 P2P 穿透几乎无法实现,穿透难度最高。
核心壁垒: 绝大多数家庭、办公场景的设备,都通过路由器共享同一个公网 IP 上网,内网设备无法直接被公网访问,这也是内网穿透技术要解决的核心问题。
1.2 应用场景
- 家庭 NAS、私有云、监控设备的远程公网访问
- 本地开发的 Web / 接口项目的外网调试与演示
- 企业办公内网系统、数据库的远程办公访问
- 物联网设备、嵌入式设备的远程管控与调试
- 游戏私服、局域网游戏的跨网络联机
文章最后将给出两种情况做演示:(1)使用tcp内网穿透,实现外网访问本地开发的 Web 网站。(2)使用点对点内网穿透,实现我的世界联机
二、内网穿透的核心原理
2.1 角色简介
内网客户端: 部署在内网环境中,运行在承载内网服务的设备上(比如:本地 windows 电脑),核心职责是主动向公网服务端发起连接,维持持久通信隧道,转发内网服务的请求与响应。
公网服务端: 部署在拥有独立公网 IP 的云服务器 / 设备上,核心职责是监听端口,接收内网客户端的隧道连接,同时接收公网访问端的请求,完成数据的中转转发。
内网服务: 最终要对外暴露的内网资源,如本地 Web 服务、SSH 远程终端、NAS 文件服务、数据库等。
公网访问端: 公网环境中,需要访问内网服务的用户设备(如手机、笔记本、远程服务器),是请求的发起方。
内网穿透的核心通信链路: 所有的内网穿透都是由内网客户端 主动 向公网服务端发起请求连接,公网服务端接收到请求后,双方建立一条 「内网客户端 <-> 公网服务端」的持久长连接隧道 。所有公网访问请求都通过公网服务端接收,经由隧道转发给内网客户端,再由内网客户端转发给内网服务;服务的响应数据则沿原路反向回传,最终送达公网访问端,完成完整的通信闭环。
2.2 内网穿透的工作流程
隧道建立阶段
- 内网客户端主动向公网服务端发起 TCP 连接请求,请求经过内网 NAT 网关时,网关会生成对应的 「内网 IP: 端口 <-> 公网 IP: 端口」 映射条目,并长期保留。
- 公网服务端响应连接请求,完成 TCP 三次握手、身份校验与隧道协议协商,双方建立一条持久的 TCP 长连接隧道。
- 客户端与服务端定期发送心跳保活包,维持隧道连接,避免 NAT 网关因长时间无数据传输回收映射条目,导致隧道断开。
公网请求转发阶段
- 公网访问端向公网服务端的指定端口发起访问请求(如 HTTP、SSH、TCP 请求)。
- 公网服务端接收到请求后,根据端口、域名、协议等配置规则,匹配到对应的内网客户端隧道。
- 公网服务端将请求数据进行封装,通过已建立的长连接隧道,转发给对应的内网客户端。
内网响应回传阶段
- 内网客户端接收到隧道转发的请求数据后,完成解封装,将原始请求转发给对应的内网服务。
- 内网服务处理请求,生成响应数据,返回给内网客户端。
- 内网客户端将响应数据封装,通过隧道回传给公网服务端。
- 公网服务端解封装响应数据,转发给对应的公网访问端,完成一次完整的请求 - 响应通信。
2.3 内网穿透的主流实现模式
中继转发模式(最通用、最稳定): 中继转发模式是目前行业最主流的内网穿透实现方案,核心逻辑是通过公网中转服务器完成全量数据的转发,隧道建立、请求传输、响应回传全流程都经过公网服务端中转,无需依赖 NAT 类型的兼容性。
- 代表工具: frp、ngrok、花生壳、内网通等。
- 优点: 兼容性极强,支持所有 NAT 类型,包括最难穿透的对称型 NAT;配置简单,运维门槛低,连接稳定性高,支持 TCP、UDP、HTTP、HTTPS 等全协议。
- 缺点: 数据转发完全依赖公网服务器,访问带宽受限于服务器的带宽上限,存在一定的转发延迟,服务器成本与带宽成本正相关。
P2P 点对点穿透模式(无中转、低延迟): P2P 穿透也叫 "打洞技术",核心逻辑是仅借助公网辅助服务器完成两端的握手协调与地址交换,不参与数据转发。两端设备通过辅助服务器获取对方的公网映射地址,分别向对方的公网地址发起连接,在 NAT 网关生成对应的映射条目,最终建立点对点的直接通信隧道,数据直接在两端之间传输。
- 代表工具: frp P2P 模块、n2n、ZeroTier、Tailscale 等。
- 优点: 无中转服务器带宽瓶颈,访问延迟极低,节省服务器带宽成本,数据传输私密性更强。
- 缺点: 兼容性有限,仅支持锥形 NAT,对称型 NAT 几乎无法完成穿透;网络环境变化时,连接容易断开,稳定性弱于中继模式;配置与运维门槛更高。
七层反向代理模式(HTTP/HTTPS 专属): 七层反向代理模式是基于 HTTP/HTTPS 协议的专属穿透方案,工作在 OSI 七层模型的应用层。公网服务端根据请求的域名、路径、请求头等信息,将不同的公网请求,转发到对应的内网客户端隧道,最终映射到不同的内网 Web 服务,实现多个内网服务共用同一个公网 IP 和端口。
- 模式适用场景: 该模式专为 Web 服务场景设计,典型应用包括本地开发的前后端项目外网调试、多站点内网服务对外暴露、小程序 / 公众号的本地接口调试,是开发场景中使用最广泛的穿透模式。
三、FRP 内网穿透工具
frp 工具下载
市面上内网穿透的工具由很多,比如:frp、ngrok, nps,rathole,ZeroTier、Tailscale等。也有对新手比较友好的,带有图形化界面的:SakuraFrp樱花穿透,花生壳等。文章以 GitHub 开源项目 frp 为例,进行演示。
选择最新版下载。 github FRP 官方地址

根据自己电脑架构,选择对应版本:

3.1 frp 工作原理
FRP(Fast Reverse Proxy) 是一款基于C/S(客户端 / 服务端)架构的高性能内网穿透工具,核心通过公网中转服务器实现内网服务的公网可访问。它支持多种协议,包括 TCP、UDP、HTTP、HTTPS 等,并且具备 P2P 通信功能。使用 frp 可以安全、便捷地将内网服务暴露到公网,通过拥有公网 IP 的节点进行中转。
frp 主要由两个组件组成:客户端(frpc) 和 服务端(frps)。通常情况下,服务端部署在具有公网 IP 地址的机器上,而客户端部署在需要穿透的内网服务所在的机器上。由于内网服务缺乏公网 IP 地址,因此无法直接被非局域网内的用户访问。用户通过访问服务端的 frps,frp 负责根据请求的端口或其他信息将请求路由到相应的内网机器,从而实现通信。 永远是客户端(frpc)发起请求访问服务端(frps)。
| 组件 | 部署位置 | 核心职责 |
|---|---|---|
| 服务端(frps) | 拥有独立公网 IP 地址的服务器 / 设备 | 持续监听端口,接收内网客户端的连接请求并建立通信隧道;接收公网用户的访问请求,按规则完成请求的路由与转发 |
| 客户端(frpc) | 无公网 IP 的内网环境目标设备 | 主动向公网 frps 发起连接,建立并维持持久通信隧道;将公网请求转发至内网服务,同时回传内网服务的响应数据 |
frp 通信原理
frp 内网穿透的核心原理是利用一台具有公网IP的服务器作为中介,来转发外网请求与内网服务之间的通信。当内网设备运行穿透客户端时,它会主动与公网服务器建立连接,外网请求则通过该服务器转发到内网服务。这种方式可以有效绕过防火墙和NAT(网络地址转换)设备的限制。
- 服务端 frps 和 客户端 frpc 完成部署搭建。
- 由内网客户端 frpc 主动向公网服务端 frps 发起连接,完成身份校验与隧道协商后,建立并维持一条持久的通信隧道。
- 公网用户向 frps 服务端发起访问请求。
- frps 接收到请求后,根据端口、协议等配置规则,匹配对应的内网隧道,将请求转发给目标 frpc。
- frpc 解封装请求,转发给内网目标服务;内网服务处理完成后,将响应数据回传给 frpc。
- frpc 将响应数据通过隧道回传给 frps,frps 最终转发给公网用户,完成一次完整的通信。
3.2 frp 配置
3.2.1 服务端配置
服务端配置,一般是带有 公网IP 的设备,即云服务器。更多使用教程请查看 frp 官方文档

将下载的 linux 版本的压缩包上传至服务器,解压后进入文件夹。

文件介绍
解压后里面由5个文件。
frpc是客户可执行文件,frpc.toml是客户端配置文件。frps是服务端可执行文件,frps.toml是服务端配置文件。LICENSE是许可证信息。- 服务端配置,我们只看
frps和frps.toml。
中继转发模式文件配置(最通用、最稳定): 文章以:将本地 ollama 服务暴露在公网访问为例,进行示例演示。
编辑 frps.toml 文件,粘贴以下内容:
bash
# frp 服务端监听端口(frpc 连接用)。通过这个端口搭建隧道,并维持隧道的长连接。
bindPort = 7000
# 身份验证,必须和客户端一致(强烈建议开启,防止未授权访问)
auth.method = "token"
auth.token = "my_password"
# 安全增强:强制 TLS 加密传输,只接受 TLS 加密的客户端连接,保障数据安全
transport.tls.force = true
# 可选:仪表盘面板,用于监控连接状态
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "admin"
- bindPort: frp 服务端监听端口(frpc 连接用)。通过这个端口搭建隧道,并维持隧道的长连接。
- auth.token: 服务端(frps)和客户端(frpc)建立隧道的身份验证,保障数据的安全,且必须和客户端保持一致。
- TLS加密: 显示指定 TLS 加密,只接受TLS 加密的客户端连接,保障数据安全
- web 管理面板: 主要用于查看连接信息【可选参数】。
开启防火墙/放行安全组:
bash
# 7000 frp 通信端口
ufw allow 7000/tcp
# 服务端 web 面板端口(非必须)
ufw allow 7500/tcp
# 本地 ollama 服务,穿透端口:11434
ufw allow 11434/tcp
服务端启动指令:
bash
./frps -c frps.toml

面板访问地址(可选,主要用于查看连接信息),访问后输入上面配置文件中的账号和密码(admin, admin)。
bash
<你的云服务器IP>:7500
能看到这个界面就说明服务端部署成功。

3.2.2 客户端配置
客户端配置,一般是希望被访问的内网设备,即本地 Windows 电脑。
将下载的 Windows 端的压缩包放在一个没有中文路径的文件夹下,解压后进入文件夹。

编辑 frpc.toml 文件,修改为你自己的服务器IP:
bash
# 服务器公网 IP
serverAddr = "修改为你的公网服务器IP"
# 远程服务器的 frps 通信端口(与服务端保持一致)
serverPort = 7000
# 身份验证,必须和服务端一致(强烈建议开启,防止未授权访问)
auth.method = "token"
auth.token = "my_password"
# 安全增强:开启 TLS 加密传输,客户端 frpc 默认已开启
transport.tls.enable = true
# 代理规则:转发 Ollama
[[proxies]]
name = "ollama"
type = "tcp"
localIP = "127.0.0.1"
# 你本地 Ollama 端口
localPort = 11434
# 服务器对外端口。你在服务端(Linux)访问的11434端口,流量会通过隧道,访问你客户端(windows)上的11434端口
remotePort = 11434
serverAddr: 客户端 frpc 主动发起请求连接的服务端 frps 的公网 IP 地址。
serverPort: frp 服务端监听端口(frpc 连接用)。通过这个端口搭建隧道,并维持隧道的长连接。
auth.token: 客户端(frpc)和服务端(frps)建立隧道的身份验证,保障数据的安全,且必须和服务端保持一致。
TLS 加密: 从 v0.50.0 开始,transport.tls.enable 的默认值将会为 true,默认开启 TLS 协议加密,无需手动设置。
[[proxies]]: 代理转发的规则。有两个 [[]] 表示可以配置多个转发规则。
name: 对代理转发的服务起个名字。
type: 代理转发的类型。frp 支持多种代理类型,以适应不同的使用场景。以下是一些常见的代理类型:
- TCP :提供纯粹的 TCP 端口映射,使服务端能够根据不同的端口将请求路由到不同的内网服务( 最通用、最稳定 )。
- UDP :提供纯粹的 UDP 端口映射,与 TCP 代理类似,但用于 UDP 流量( 适合直播/视频通话等,低延迟、高流畅 )。
- HTTP:专为 HTTP 应用设计,支持修改 Host Header 和增加鉴权等额外功能。
- HTTPS:类似于 HTTP 代理,但专门用于处理 HTTPS 流量。
- STCP:提供安全的 TCP 内网代理,要求在被访问者和访问者的机器上都部署 frpc,不需要在服务端暴露端口。
- SUDP:提供安全的 UDP 内网代理,与 STCP 类似,需要在被访问者和访问者的机器上都部署 frpc,不需要在服务端暴露端口。
- XTCP :点对点内网穿透代理,与 STCP 类似,流量不需要经过服务器中转(适合P2P连接,低延迟、但不稳,可能无法连接成功)。
- TCPMUX:支持服务端 TCP 端口的多路复用,允许通过同一端口访问不同的内网服务。
localIP: 需要从公网访问的内网服务的地址,一般配置为本机地址。
localPort: 需要从公网访问的内网服务的端口。一般配置为本机内网服务的端口。
remotePort: 表示在 frp 服务端监听的端口,访问此端口的流量将被转发到本地服务的相应端口(需要在防火墙/安全组放行)。
第一个 localPort=11434 表示的是你windows内网的11434端口,第二个 remotePort = 11434 表示你远程云服务器的 11434 端口。
【访问:云服务器 123.45.67.89:11434 等价于访问内网设备的: 127.0.0.1:11434 。】
客户端启动指令:
bash
.\frpc.exe -c frpc.toml

3.3 连接验证
访问这个地址,验证是否连接成功。如果无法访问,请先查看你本地的 ollama 是否正在运行?先让本地 ollama 服务跑起来,再进行内网穿透。
bash
<你的云服务器IP>:11434

访问这个地址,可以查看到你本地已经下载的大模型。
bash
<你的云服务器IP>:11434/api/tags
流量走向
bash
【公网用户】
↓ 访问 云IP:11434
【frps】
↓ 11434被frps监听,frps将流量送入【隧道】
【隧道:frpc ↔ frps:7000】
↓
【本地frpc】
↓ 转发到 127.0.0.1:11434
【Ollama】
↓ 处理完返回
【原路全部返回】
四、frp 点对点内网穿透【p2p 模式】和 stcp
4.1 原理讲解
xtcp 介绍:
frp 的 P2P 模式也叫 xtcp ,核心是绕过 frp 服务器中转,让客户端与访问端直接建立连接,大幅降低延迟、提升速度,同时减轻服务器带宽压力。服务器只在两台设备搭建隧道的时候参与,当两台设备成功连接后,服务器不再参数流量的转发,而是两台设备直接进行通信。永远是客户端发起请求访问服务端。
p2p 工作流程:
- 两台设备部署客户端 frpc,服务器部署服务端 frps。
- frpc 客户端(内网设备1)连接 frps 服务器,告知要开启 P2P 穿透(内网设备1需要对外提供服务,又被称作"服务端")。
- frpc 访问端(内网2/外网设备)也连接 frps 服务器,请求访问该 P2P 服务(即访问内网设备1)。
- 双方都把自己的 公网 IP + 端口 上报给服务器。
- frp 服务器将双方的网络信息交换给彼此。客户端收到访问者的外网地址,访问者收到客户端的外网地址,双方 同时向对方的公网地址主动发起连接 ,打通一条直连通道。
- 打洞成功后,流量不再经过 frp 服务器,而是直接在内网客户端和内网/外网访问端之间 P2P 传输 ,速度接近真实物理带宽,延迟极低。
- 注意: 有两个服务端,一个是frp软件的服务端(frps),一个是内网设备(frpc)对外提供服务的服务端。
4.2 配置步骤
步骤一:服务端配置(frps): 部署在公网服务器,仅负责信令转发与打洞协商,不承载业务流量。
编辑 frps.toml 文件:
bash
# TCP 控制端口,客户端连接用
bindPort = 7000
# 身份验证,必须和客户端一致(强烈建议开启,防止未授权访问)
auth.method = "token"
auth.token = "你的自定义强密码Token"
# 安全增强:强制 TLS 加密传输,只接受 TLS 加密的客户端连接,保障数据安全
transport.tls.force = true
# 可选:仪表盘面板,用于监控连接状态
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "admin"
服务端启动指令:
bash
./frps -c frps.toml
步骤二:客户端配置(frpc内网设备1): 部署在需要暴露到外网的机器上(比如家里的 NAS、电脑、服务器)
编辑 frpc.toml 文件:
bash
# 连接公网 frps 服务端
serverAddr = "修改为你的公网服务器IP"
serverPort = 7000
# 身份验证必须与服务端一致
auth.method = "token"
auth.token = "你的自定义强密码Token"
# 安全增强:开启 TLS 加密传输,客户端 frpc 默认已开启
transport.tls.enable = true
# 【可选】自定义 STUN 服务器,默认使用 frp 内置公共STUN,不可用时替换
# natHoleStunServer = "stun.l.google.com:19302"
# natHoleStunServer = "stun.qq.com:3478"
# p2p 代理配置
[[proxies]]
# 代理名称,访问端必须完全对应
name = "p2p_ssh"
# 核心:指定xtcp点对点模式
type = "xtcp"
# 只有共享密钥 (secretKey) 与服务器端一致的用户才能访问该服务
secretKey = "你的自定义强密码P2P密钥"
# 内网要暴露的服务IP
localIP = "127.0.0.1"
# 内网要暴露的服务端口,示例为SSH 22端口,可替换为3389(远程桌面)、80(网页)等
localPort = 22
客户端启动指令:
bash
.\frpc.exe -c frpc.toml
步骤三:访问端配置(frpc内网2/外网设备): 部署在要访问内网服务的机器上(比如公司电脑、外出的笔记本)
编辑 frpc.toml 文件:
bash
# 连接同一个公网 frps 服务端
serverAddr = "修改为你的公网服务器IP"
serverPort = 7000
# 身份验证必须与服务端一致
auth.method = "token"
auth.token = "你的自定义强密码Token"
# 安全增强:开启 TLS 加密传输,客户端 frpc 默认已开启
transport.tls.enable = true
# 【可选】与被访问端保持一致的 STUN 服务器
# natHoleStunServer = "stun.l.google.com:19302"
# natHoleStunServer = "stun.qq.com:3478"
# P2P 访客
[[visitors]]
# 访问者名称,唯一即可
name = "p2p_ssh_visitor"
# 核心:指定xtcp点对点模式
type = "xtcp"
# 要访问的 P2P 代理的名称(必须和被访问端的proxy name完全一致)
serverName = "p2p_ssh"
# 【必填】与被访问端的 secretKey 完全一致
secretKey = "你的自定义强密码P2P密钥"
# 本地绑定IP,默认127.0.0.1仅本机访问,0.0.0.0可局域网内其他设备访问
bindAddr = "127.0.0.1"
# 本地监听端口,访问此端口即可穿透到内网服务,本地访问:127.0.0.1:6000 即可
bindPort = 6000
# 可选:如果需要自动保持隧道打开,将其设置为 true,默认为false
# keepTunnelOpen = true
访问端启动指令:
bash
.\frpc.exe -c frpc.toml
隧道打通后。访问者( 内网2/外网设备 )访问: localhost:6000 等于访问被访问者( frpc内网设备1 )的: localhost:22 。
和普通中转模式对比
| 对比项 | 普通中转 (tcp) | P2P 穿透 (xtcp) |
|---|---|---|
| 流量路径 | 经过 frp 服务器中转 | 客户端 ↔ 访问端直连 |
| 速度与延迟 | 慢、高延迟 | 快、低延迟 |
| 服务器压力 | 大 | 极小 |
| 适用网络 | 所有网络 | 依赖 NAT 打洞成功率 |
| 使用复杂度 | 简单 | 需两端都配置 frp |
4.3 xtcp 打洞失败自动回退到stcp
stcp 介绍:
p2p 模式可能受限于路由器NAT,校园网,公司内网等导致无法穿透成功,所以我们可以配置p2p 打洞失败自动降级为stcp。打洞失败后自动使用stcp 连接,在用户层面无感知,用户只知道已经内网穿透成功了,可以正常访问。
stcp(Secure TCP) 与 xtcp 的底层架构是一样的,都是需要两台设备部署客户端 frpc ,同时设置访问密钥 secretKey 。所有配置都一样,只需要将 type = "xtcp" 修改为 type = "stcp" 即可。注意:xtcp 不能降级为 tcp ,因为底层架构不一样。
步骤一:服务端frps保持不变:
bash
# TCP 控制端口,客户端连接用
bindPort = 7000
# 身份验证,必须和客户端一致(强烈建议开启,防止未授权访问)
auth.method = "token"
auth.token = "你的自定义强密码Token"
# 安全增强:强制 TLS 加密传输,只接受 TLS 加密的客户端连接,保障数据安全
transport.tls.force = true
# 可选:仪表盘面板,用于监控连接状态
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "admin"
步骤二:客户端配置(frpc内网设备1):
bash
# 连接公网 frps 服务端
serverAddr = "修改为你的公网服务器IP"
serverPort = 7000
# 身份验证必须与服务端一致
auth.method = "token"
auth.token = "你的自定义强密码Token"
# 安全增强:开启 TLS 加密传输,客户端 frpc 默认已开启
transport.tls.enable = true
# 【可选】自定义 STUN 服务器,默认使用 frp 内置公共STUN,不可用时替换
# natHoleStunServer = "stun.l.google.com:19302"
# natHoleStunServer = "stun.qq.com:3478"
# ----------------------------
# P2P 主配置(xtcp)
# ----------------------------
[[proxies]]
# 代理名称,访问端必须完全对应
name = "p2p_ssh"
# 核心:指定xtcp点对点模式
type = "xtcp"
# 只有共享密钥 (secretKey) 与服务器端一致的用户才能访问该服务
secretKey = "你的自定义强密码P2P密钥"
# 内网要暴露的服务IP
localIP = "127.0.0.1"
# 内网要暴露的服务端口,示例为SSH 22端口,可替换为3389(远程桌面)、80(网页)等
localPort = 22
# ----------------------------
# xtcp 自动回退配置(stcp)
# ----------------------------
[[proxies]]
name = "stcp_ssh"
type = "stcp"
secretKey = "你的自定义强密码P2P密钥"
localIP = "127.0.0.1"
localPort = 22
步骤三:访问端配置(frpc内网2/外网设备):
bash
# 连接同一个公网 frps 服务端
serverAddr = "修改为你的公网服务器IP"
serverPort = 7000
# 身份验证必须与服务端一致
auth.method = "token"
auth.token = "你的自定义强密码Token"
# 安全增强:开启 TLS 加密传输,客户端 frpc 默认已开启
transport.tls.enable = true
# 【可选】与被访问端保持一致的 STUN 服务器
# natHoleStunServer = "stun.l.google.com:19302"
# natHoleStunServer = "stun.qq.com:3478"
# ----------------------------
# P2P 访客(带自动降级)
# ----------------------------
[[visitors]]
# 访问者名称,唯一即可
name = "p2p_ssh_visitor"
# 核心:指定xtcp点对点模式
type = "xtcp"
# 要访问的 P2P 代理的名称(必须和被访问端的proxy name完全一致)
serverName = "p2p_ssh"
# 【必填】与被访问端的 secretKey 完全一致
secretKey = "你的自定义强密码P2P密钥"
# 本地绑定IP,默认127.0.0.1仅本机访问,0.0.0.0可局域网内其他设备访问
bindAddr = "127.0.0.1"
# 本地监听端口,访问此端口即可穿透到内网服务,本地访问:127.0.0.1:6000 即可
bindPort = 6000
# 可选:如果需要自动保持隧道打开,将其设置为 true,默认为false
# keepTunnelOpen = true
# 自动降级配置(P2P 失败自动切 stcp)
fallbackTo = "stcp_fallback"
fallbackTimeoutMs = 300
# ----------------------------
# 降级用 stcp 访客
# ----------------------------
[[visitors]]
name = "stcp_fallback"
type = "stcp"
serverName = "stcp_ssh"
secretKey = "你的自定义强密码P2P密钥"
bindPort = -1 # 不占用本地端口,仅内部使用
五、内网穿透【应用】
5.1 本地 Web 服务(tcp 模式通用)
我在本地Windows启动了一个 java-web 网页,使用内网穿透,使得可以让外网访问我本地的 web 页面。
服务端配置(frps):
bash
# frp 服务端监听端口(frpc 连接用)。通过这个端口搭建隧道,并维持隧道的长连接。
bindPort = 7000
auth.method = "token"
auth.token = "my_password"
transport.tls.force = true
# 可选:仪表盘面板,用于监控连接状态
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "admin"
开启防火墙/放行安全组:
bash
# 开启端口
ufw allow 7000/tcp
ufw allow 7500/tcp
ufw allow 11434/tcp
服务端启动指令:
bash
./frps -c frps.toml
客户端配置(frpc):
bash
# 服务器公网 IP (修改为你自己的服务器IP)
serverAddr = "123.45.67.89"
serverPort = 7000
auth.method = "token"
auth.token = "my_password"
transport.tls.enable = true
# 代理规则:转发 java-web
[[proxies]]
name = "java-web"
type = "tcp"
localIP = "127.0.0.1"
localPort = 8080
remotePort = 8080
客户端启动指令:
bash
.\frpc.exe -c frpc.toml
界面展示:

5.2 我的世界联机(xtcp 点对点模式)
场景: 你正在玩我的世界,你想让你的朋友加入进来一起联机。此时,你正在玩的电脑是 客户端A ,你的朋友的电脑是 客户端B 。你还需要有一台云服务器 (服务器端 )。
Tips: 使用 xtcp 打洞失败的几率较高。你大概率会 fallback 到 stcp。如果还是无法连接,请将客户端A(腐竹)电脑的防火墙临时关闭,然后再次尝试。玩我的世界还是建议使用普通 tcp 内网穿透,不建议P2P,因为受Nat网络相关问题,穿透难度大,失败率极高(别问我是咋知道的,呜呜呜~)。
服务器端(frps):
编辑 frps.toml 配置文件:
bash
# 基础配置
bindPort = 7000
auth.method = "token"
auth.token = "my_password"
transport.tls.force = true
# 可选:仪表盘面板,用于监控连接状态
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "admin"
服务端启动指令:
bash
./frps -c frps.toml
客户端A(frpc): 提供我的世界服务的电脑(比如:服主的电脑)
编辑 frpc.toml 配置文件:
bash
# 基础配置
serverAddr = "修改为你的公网服务器IP"
serverPort = 7000
auth.method = "token"
auth.token = "my_password"
transport.tls.enable = true
# p2p 配置
[[proxies]]
name = "p2p_minecraft"
type = "xtcp"
secretKey = "my-secret-key"
localIP = "127.0.0.1"
localPort = 25565
# 降级 stcp 配置
[[proxies]]
name = "stcp_minecraft"
type = "stcp"
secretKey = "my-secret-key"
localIP = "127.0.0.1"
localPort = 25565
客户端启动指令:
bash
.\frpc.exe -c frpc.toml
客户端B(frpc): 需要连接我的世界服务的电脑(你的朋友的电脑)
编辑 frpc.toml 配置文件:
bash
# 基础配置
serverAddr = "修改为你的公网服务器IP"
serverPort = 7000
auth.method = "token"
auth.token = "my_password"
transport.tls.enable = true
# 访客配置
[[visitors]]
name = "p2p_minecraft_visitor"
type = "xtcp"
serverName = "p2p_minecraft"
secretKey = "my-secret-key"
bindAddr = "127.0.0.1"
bindPort = 25565
fallbackTo = "stcp_fallback"
fallbackTimeoutMs = 300
# 回退 stcp 配置
[[visitors]]
name = "stcp_fallback"
type = "stcp"
serverName = "stcp_minecraft"
secretKey = "my-secret-key"
bindPort = -1
客户端启动指令:
bash
.\frpc.exe -c frpc.toml
5.3 关闭 Windows11 防火墙
Win+R ,输入: control 打开控制面板,点击系统和安全:

点击 Windows Defender 防火墙:

点击启动或关闭 Windows Defender 防火墙:

点击关闭 Windows Defender 防火墙,然后点击确定即可。

六、进阶配置【可选】
6.1 配置为 service 文件
如果你不想让服务端frps在前端控制台运行(前台有输出,占用窗口,关闭窗口,服务端frps立即关闭),你可以设置frps在后台运行(关闭窗口服务端frps依然正常运行)。将服务端frps的启动方式设置成 systemd。
编写 service 文件:
bash
sudo vim /etc/systemd/system/frps.service
frps.service 文件内容:
bash
[Unit]
Description=frp server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
# 修改为你自己的用户名
User=ubuntu
# 请修改为你的 frp 解压目录
WorkingDirectory=/usr/local/frp
# 请修改为你服务器上 frps 二进制文件和配置文件的绝对路径
ExecStart=/usr/local/frp/frps -c /usr/local/frp/frps.toml
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
systemd 启动服务的指令:
| 操作 | 指令 |
|---|---|
| 启动服务 | sudo systemctl start frps |
| 停止服务 | sudo systemctl stop frps |
| 重启服务 | sudo systemctl restart frps |
| 查看状态 | sudo systemctl status frps |
| 开启开机自启 | sudo systemctl enable frps |
| 关闭开机自启 | sudo systemctl disable frps |
| 查看实时日志 | sudo journalctl -u frps -f |
6.2 新增日志
设置 systemd 启动 service 服务之后,最好搭配日志使用,方便排查问题,否则,当你运行服务端 frps 当前窗口会显示空白,类似于卡住一样,没有输出。实际上 frps 正常运行。
修改服务端 frps.toml 文件,在文末添加以下内容:
bash
# 日志的输出文件
log.to = "./frps.log"
# 日志等级trace,debug,info(默认),warn,error
log.level = "info"
# 只保留最近 30 天的日志,超过 30 天的日志自动删除
log.maxDays = 30
服务端 frps 添加在文件末尾即可,客户端 frpc 需要添加在 [[proxies]] 或者 [[visitors]] 上面。
6.3 安全性增强
TLS 默认开启方式:
从 v0.50.0 开始,transport.tls.enable 的默认值将会为 true,默认开启 TLS 协议加密。如果 frps 端没有配置证书,则会使用随机生成的证书来加密流量。默认情况下,frpc 开启 TLS 加密功能,但是不校验 frps 的证书。当 frps.toml 中 transport.tls.force = true 时,表示 server 端只接受 TLS 连接的客户端,这也是 frps 验证 frpc 身份的前提条件。如果 frps.toml 中 transport.tls.trustedCaFile 内容是有效的话,那么默认就会开启 transport.tls.force = true 。 注意:启用此功能后除 xtcp ,可以不用再设置 use_encryption 重复加密。
在服务端frps 执行以下指令获取证书:
bash
openssl req -x509 -newkey rsa:2048 -days 3650 -nodes -keyout server.key -out server.crt -subj "/CN=frp"
此时,当前目录会生成两个文件,server.crt (证书)和 server.key (私钥)。将将证书配置在服务端 frps.toml ,客户端frpc可不配置。更多安全配置,请查看 官方文档:frp-自定义 TLS 协议加密
bash
transport.tls.force = true
transport.tls.certFile = "server.crt"
transport.tls.keyFile = "server.key"
End
你好,少年,未来可期~