【Linux】内网穿透原理

【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.x10.x.x.x172.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 应用场景

  1. 家庭 NAS、私有云、监控设备的远程公网访问
  2. 本地开发的 Web / 接口项目的外网调试与演示
  3. 企业办公内网系统、数据库的远程办公访问
  4. 物联网设备、嵌入式设备的远程管控与调试
  5. 游戏私服、局域网游戏的跨网络联机

文章最后将给出两种情况做演示:(1)使用tcp内网穿透,实现外网访问本地开发的 Web 网站。(2)使用点对点内网穿透,实现我的世界联机

二、内网穿透的核心原理

2.1 角色简介

内网客户端: 部署在内网环境中,运行在承载内网服务的设备上(比如:本地 windows 电脑),核心职责是主动向公网服务端发起连接,维持持久通信隧道,转发内网服务的请求与响应。

公网服务端: 部署在拥有独立公网 IP 的云服务器 / 设备上,核心职责是监听端口,接收内网客户端的隧道连接,同时接收公网访问端的请求,完成数据的中转转发。

内网服务: 最终要对外暴露的内网资源,如本地 Web 服务、SSH 远程终端、NAS 文件服务、数据库等。

公网访问端: 公网环境中,需要访问内网服务的用户设备(如手机、笔记本、远程服务器),是请求的发起方。

内网穿透的核心通信链路: 所有的内网穿透都是由内网客户端 主动 向公网服务端发起请求连接,公网服务端接收到请求后,双方建立一条 「内网客户端 <-> 公网服务端」的持久长连接隧道 。所有公网访问请求都通过公网服务端接收,经由隧道转发给内网客户端,再由内网客户端转发给内网服务;服务的响应数据则沿原路反向回传,最终送达公网访问端,完成完整的通信闭环。

2.2 内网穿透的工作流程

隧道建立阶段

  1. 内网客户端主动向公网服务端发起 TCP 连接请求,请求经过内网 NAT 网关时,网关会生成对应的 「内网 IP: 端口 <-> 公网 IP: 端口」 映射条目,并长期保留。
  2. 公网服务端响应连接请求,完成 TCP 三次握手、身份校验与隧道协议协商,双方建立一条持久的 TCP 长连接隧道。
  3. 客户端与服务端定期发送心跳保活包,维持隧道连接,避免 NAT 网关因长时间无数据传输回收映射条目,导致隧道断开。

公网请求转发阶段

  1. 公网访问端向公网服务端的指定端口发起访问请求(如 HTTP、SSH、TCP 请求)。
  2. 公网服务端接收到请求后,根据端口、域名、协议等配置规则,匹配到对应的内网客户端隧道。
  3. 公网服务端将请求数据进行封装,通过已建立的长连接隧道,转发给对应的内网客户端。

内网响应回传阶段

  1. 内网客户端接收到隧道转发的请求数据后,完成解封装,将原始请求转发给对应的内网服务。
  2. 内网服务处理请求,生成响应数据,返回给内网客户端。
  3. 内网客户端将响应数据封装,通过隧道回传给公网服务端。
  4. 公网服务端解封装响应数据,转发给对应的公网访问端,完成一次完整的请求 - 响应通信。

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(网络地址转换)设备的限制。

  1. 服务端 frps 和 客户端 frpc 完成部署搭建。
  2. 由内网客户端 frpc 主动向公网服务端 frps 发起连接,完成身份校验与隧道协商后,建立并维持一条持久的通信隧道。
  3. 公网用户向 frps 服务端发起访问请求。
  4. frps 接收到请求后,根据端口、协议等配置规则,匹配对应的内网隧道,将请求转发给目标 frpc。
  5. frpc 解封装请求,转发给内网目标服务;内网服务处理完成后,将响应数据回传给 frpc。
  6. 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 工作流程:

  1. 两台设备部署客户端 frpc,服务器部署服务端 frps。
  2. frpc 客户端(内网设备1)连接 frps 服务器,告知要开启 P2P 穿透(内网设备1需要对外提供服务,又被称作"服务端")。
  3. frpc 访问端(内网2/外网设备)也连接 frps 服务器,请求访问该 P2P 服务(即访问内网设备1)。
  4. 双方都把自己的 公网 IP + 端口 上报给服务器。
  5. frp 服务器将双方的网络信息交换给彼此。客户端收到访问者的外网地址,访问者收到客户端的外网地址,双方 同时向对方的公网地址主动发起连接 ,打通一条直连通道。
  6. 打洞成功后,流量不再经过 frp 服务器,而是直接在内网客户端和内网/外网访问端之间 P2P 传输 ,速度接近真实物理带宽,延迟极低。
  7. 注意: 有两个服务端,一个是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

更多使用教程请查看 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.tomltransport.tls.force = true 时,表示 server 端只接受 TLS 连接的客户端,这也是 frps 验证 frpc 身份的前提条件。如果 frps.tomltransport.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

你好,少年,未来可期~

相关推荐
tianyuanwo2 小时前
服务器OS多架构CI流水线架构设计:单架构隔离与多架构融合的权衡之道
服务器·ci/cd·架构
薛定谔的码*2 小时前
双机热备份MSTP+VRRP+负载均衡
运维·网络·负载均衡
wbs_scy2 小时前
Linux 进程信号深度解析(下):信号的保存、阻塞与捕捉
运维·服务器
无巧不成书02182 小时前
Calibre 全系统安装配置教程|新手零门槛+命令行进阶+AI功能+内容服务器全解析
运维·服务器·人工智能·calibre·电子书管理·calibre命令行·电子书格式转换
欲盖弥彰13142 小时前
Linux设备驱动 -- TMP75AIDR驱动移植
linux·驱动开发·驱动·驱动移植·嵌入式linux驱动·tmp75aidr
辰痕~2 小时前
数据结构-算法
linux
努力搬砖的鱼2 小时前
校园网SSH连接超时故障深度排查:从TCP重传到物理链路MTU限制
网络·tcp/ip·ssh
桦02 小时前
【Linux复习】:基础指令/常用工具
linux