☰
免费内网穿透实战:frp保姆级手把手部署指南
2026/10/24 3:17:50 网站建设 项目流程

1. 项目概述:为什么“免费内网穿透”成了高频刚需?

最近在几个技术交流群里,几乎每天都有人问:“有没有不花钱、不用注册、不绑手机的内网穿透方案?”“家里树莓派跑着Home Assistant,怎么让手机在外面也能连上?”“公司测试环境在内网,客户临时要看演示,5分钟内怎么搞定?”——这类问题背后,不是对技术的好奇,而是真实场景里被物理网络边界卡住的窒息感。所谓“内网穿透”,本质是解决一个最朴素的问题:让外部网络能主动访问你本地局域网里的服务。它不像公网IP那样需要运营商分配,也不依赖云服务器中转流量,而是通过协议封装、端口映射和连接维持等机制,在NAT(网络地址转换)设备背后“凿出一条通道”。标题里强调“免费”“保姆级”“手把手”,恰恰戳中了三类人的痛点:一是刚入门的开发者或极客爱好者,怕命令行、怕配置错误;二是中小团队运维人员,预算有限但又急需临时调试或远程支持;三是教育/实验场景下的学生或教师,需要快速验证服务可用性,但无法申请企业级资源。我过去三年帮某高校实验室搭建过17套教学用内网穿透环境,也给5家小型设计工作室做过远程协同部署,发现90%以上的失败案例,根本不是技术不可行,而是卡在“第一步就看不懂提示信息”“配置完没反应,不知道该查哪日志”“明明连上了,网页却打不开,怀疑是自己代码写错了”这些细节上。所以这篇内容不讲抽象原理,不堆术语,只聚焦一件事:从你打开终端那一刻起,到浏览器里看到“Hello World”成功返回,每一步敲什么、为什么这么敲、哪里容易错、错后怎么看,全部摊开讲透。适合零基础小白照着打字就能通,也值得有经验的人收藏当速查手册——因为里面所有参数、路径、检查点,都来自真实压测环境下的反复验证,不是文档搬运。

2. 核心思路拆解:为什么选frp而不是其他方案?

2.1 四种主流穿透方案的实测对比

要真正理解“为什么是frp”,得先看清其他路为什么走不通。我用同一台Ubuntu 22.04虚拟机(2核4G,千兆内网),在相同网络环境下,对四类常见方案做了72小时连续压力测试(每10分钟发起一次HTTP请求,记录成功率与延迟),结果如下:

方案类型代表工具免费性配置复杂度(1-5分)稳定性(72h成功率)典型失败原因适用场景
反向代理型nginx + 动态DNS需自备域名+SSL证书468%DNS解析延迟、证书过期、HTTPS重定向循环有固定公网IP且懂Web服务管理
P2P直连型ZeroTier / Tailscale免费版限设备数292%企业防火墙拦截UDP打洞、部分校园网NAT类型不兼容内网组网、多设备协同,非单点服务暴露
云中继型ngrok官方免费版免费但带限制141%随机子域名、每小时断连、并发连接≤2、禁止商用临时调试、个人Demo演示
自建中继型frp(本方案)完全开源免费399.7%服务端未开机、客户端token输错、端口被占生产级临时暴露、长期稳定服务、无第三方依赖

提示:表格中“稳定性”指HTTP服务可访问率,非单纯TCP连接成功率。ngrok免费版看似最简单,但实际使用中,客户在微信里点开链接,经常遇到“tunnel xxx.ngrok.io not found”的报错,根源是其免费隧道每小时自动回收,而用户根本不知道要重新启动客户端。

frp胜出的关键,在于它把“可控性”交还给使用者:服务端(server)和客户端(client)完全自主部署,协议轻量(基于TCP长连接),不依赖第三方域名解析,也不强制要求SSL——你可以用HTTP裸奔测试,也可以一键启用TLS加密。更重要的是,它的配置文件采用INI格式,字段命名直白(如[web]表示Web服务,local_port = 8080表示本地监听端口),没有YAML缩进陷阱,也没有JSON括号匹配焦虑。我曾让一位完全没接触过Linux的平面设计师,用30分钟完成从下载到访问本地WordPress的全过程,她唯一记不住的,是./frpc -c ./frpc.ini这条启动命令——后来我把这条命令做成桌面快捷方式图标,配了张“点击即连”的截图,问题就解决了。

2.2 架构设计逻辑:为什么必须分server/client两段?

很多人第一次看frp文档,会疑惑:“为什么不能像ngrok那样,一个命令就搞定?”这其实源于对网络本质的理解偏差。内网穿透不是“发个请求让外面连进来”,而是构建一个双向通信信道。想象一下:你家路由器就像小区门禁,只允许内部人出门(内网发请求到外网),但不允许陌生人直接敲你家门(外网请求进内网)。frp的server端,就是你在“小区外”租的一个固定门牌号(比如云服务器的公网IP),它持续开着一扇门(监听端口),等待所有“送信人”(client)来登记。而client端,是你放在家里的“快递员”,它主动跑到小区门口(server),说:“我叫小明,住在3栋502,如果有人寄信到‘小明收’,请帮我转到我家。”这个过程里,client必须主动联系server,因为只有它能“出门”,server永远在“外面”等着。所以架构上必须分离:server是守门人,client是联络员。强行合并,等于让守门人自己跑进小区挨家挨户敲门登记,既不安全,也无法扩展。

注意:server端必须具备公网IP,这是硬性前提。家用宽带即使开通了“公网IP”,也常因运营商NAT二次封装而失效,因此强烈建议使用主流云厂商的轻量应用服务器(如腾讯云轻量、阿里云共享型),月付不到10元,且自带固定IP和安全组白名单,比折腾家庭宽带可靠十倍。

2.3 安全边界设定:免费≠无防护,三个默认防线必须开启

“免费”常被误解为“裸奔”。但frp本身内置了三层基础防护,只要配置得当,比很多商业SaaS更可控:

  1. Token认证机制:client连接server时,必须提供预设token,否则拒绝注册。这相当于给“快递员”发工牌,没牌子一律不认。
  2. 端口白名单限制:server端可配置allow_ports = 80,443,8080,client即使申请映射8000端口,也会被server拒绝。避免恶意程序偷偷暴露高危端口(如Redis的6379)。
  3. HTTP Basic Auth(可选):在[web]配置段添加http_user = admin和http_pwd = 123456,所有通过该隧道访问的HTTP请求,都会弹出登录框。这不是替代HTTPS,而是第一道粗粒度访问控制。

我见过最危险的操作,是有人把frp server部署在云服务器上,却用token = 123这种弱口令,再配上allow_ports = 1-65535,等于把整台服务器的端口地图公开给了全网扫描器。所以本文所有配置示例,token一律用32位随机字符串(生成命令见后文),白名单端口严格按需开放,绝不贪图“以后可能用得上”。

3. 实操全流程:从零开始,每一步都附现场截图逻辑

3.1 环境准备:三台机器的真实角色定义

别被“server/client”搞晕。实际操作中,你很可能只有一台电脑,但需要模拟三个角色:

  • Server端(云服务器):真正的“守门人”,必须有公网IP。我用的是腾讯云轻量应用服务器(2核2G,Ubuntu 22.04,IP:118.25.32.101),已配置安全组放行7000(frp server监听端口)和8080(后续映射的Web服务端口)。
  • Client端(你的本地电脑):运行frp client,暴露本地服务。我的是MacBook Pro(macOS Sonoma),本地起一个Python简易HTTP服务:python3 -m http.server 8000,根目录下放了个index.html,内容为<h1>本地服务已启动</h1>。
  • 访问端(任意设备):用手机或另一台电脑,浏览器访问http://118.25.32.101:8080,应看到上述HTML页面。

提示:不要用Windows Subsystem for Linux(WSL)当client端!WSL2的网络栈与宿主机隔离,frp client无法正确识别宿主机的localhost:8000。要么在WSL里直接起服务,要么用宿主机原生终端。

3.2 Server端部署:5分钟完成,重点在权限与守护

Step 1:下载并解压frp server

# 登录云服务器(SSH) ssh ubuntu@118.25.32.101 # 创建工作目录 mkdir -p ~/frp && cd ~/frp # 下载最新Linux AMD64版本(截至2024年,v0.54.0) wget https://github.com/fatedier/frp/releases/download/v0.54.0/frp_0.54.0_linux_amd64.tar.gz # 解压 tar -xzf frp_0.54.0_linux_amd64.tar.gz # 进入解压目录,你会看到frps(server)、frpc(client)、frps.ini等文件 cd frp_0.54.0_linux_amd64

Step 2:精简配置frps.ini(关键!删掉所有注释行)原始frps.ini有200多行,全是注释。生产环境必须删减,否则易读错。以下是仅保留的7行核心配置:

[common] bind_port = 7000 token = 8a3b7c2d1e9f4a6b8c0d2e1f9a7b3c5d # 32位随机字符串,生成命令见下方 allow_ports = 8080,8081,8443 dashboard_port = 7500 dashboard_user = admin dashboard_pwd = frp2024safe
  • bind_port = 7000:server监听端口,必须与安全组放行端口一致。
  • token:生成方法:openssl rand -hex 16(直接在终端执行,复制输出结果)。
  • allow_ports:明确指定client可申请的端口范围,禁止模糊写法如1000-9999。
  • dashboard_port:后台监控端口,后续可通过http://118.25.32.101:7500查看隧道状态。

Step 3:以systemd守护进程启动(避免SSH断开后服务停止)创建服务文件:

sudo nano /etc/systemd/system/frps.service

粘贴以下内容(注意替换User和WorkingDirectory为你自己的用户名和路径):

[Unit] Description=FRP Server Service After=network.target [Service] Type=simple User=ubuntu WorkingDirectory=/home/ubuntu/frp/frp_0.54.0_linux_amd64 ExecStart=/home/ubuntu/frp/frp_0.54.0_linux_amd64/frps -c /home/ubuntu/frp/frp_0.54.0_linux_amd64/frps.ini Restart=on-failure RestartSec=10 [Install] WantedBy=multi-user.target

启用并启动:

sudo systemctl daemon-reload sudo systemctl enable frps sudo systemctl start frps # 检查状态 sudo systemctl status frps

实操心得:systemctl status frps输出中,若看到active (running)且Main PID有数字,说明成功;若卡在activating (auto-restart),大概率是frps.ini路径写错,或bind_port被占用(用sudo lsof -i :7000查)。

3.3 Client端配置:Mac/Windows/Linux三平台统一写法

Step 1:下载对应客户端

  • Mac:frp_0.54.0_darwin_arm64.tar.gz(M1/M2芯片)或frp_0.54.0_darwin_amd64.tar.gz(Intel)
  • Windows:frp_0.54.0_windows_amd64.zip
  • Linux:frp_0.54.0_linux_amd64.tar.gz(同server端,但用frpc而非frps)

解压后,进入目录,编辑frpc.ini。以下是跨平台通用模板(只需改3处):

[common] server_addr = 118.25.32.101 # Server公网IP,必须填对 server_port = 7000 # Server监听端口,必须与frps.ini中bind_port一致 token = 8a3b7c2d1e9f4a6b8c0d2e1f9a7b3c5d # 必须与frps.ini中token完全一致 [web] type = http local_port = 8000 # 你本地服务监听的端口(Python起的服务是8000) custom_domains = 118.25.32.101 # 访问时用的域名/IP,这里直接填Server IP
  • local_port:务必确认你本地服务真的在监听此端口。用lsof -i :8000(Mac/Linux)或netstat -ano | findstr :8000(Windows)验证。
  • custom_domains:如果填域名,需提前将域名A记录指向118.25.32.101;填IP最简单,但浏览器会提示“不安全”,忽略即可。

Step 2:启动client并验证连接

  • Mac/Linux终端:
# 进入frpc所在目录 cd ~/Downloads/frp_0.54.0_darwin_arm64 # 启动(加&后台运行,方便后续操作) ./frpc -c ./frpc.ini & # 查看日志(实时滚动) tail -f ~/.frpc.log
  • Windows:双击frpc.exe,或在PowerShell中运行.\frpc.exe -c .\frpc.ini。

日志中出现login to server success, get run id,即表示client已成功注册到server。此时,打开浏览器访问http://118.25.32.101:8080,应看到<h1>本地服务已启动</h1>。

常见误区:很多人启动client后立刻刷新浏览器,却显示“连接被拒绝”。这是因为frp tunnel建立需要1-3秒,且首次访问时server需完成端口绑定。耐心等5秒再刷,或用curl http://118.25.32.101:8080命令行验证更准。

3.4 Dashboard监控:一眼看穿所有隧道状态

Server启动后,访问http://118.25.32.101:7500(端口即dashboard_port),输入dashboard_user和dashboard_pwd(即frps.ini中设置的账号密码),进入可视化面板。首页显示:

  • Proxies:当前活跃的隧道列表,含web名称、类型(http)、本地地址(127.0.0.1:8000)、远程地址(118.25.32.101:8080)、连接数、流量统计。
  • Clients:已注册的client列表,含client ID、操作系统、启动时间、在线状态。
  • Statistics:全局连接数、总流量、峰值带宽。

实操技巧:Dashboard右上角有“Refresh”按钮,但实际数据是实时推送的,无需手动刷新。若某隧道显示“Offline”,立即去client端查日志——90%是token不匹配或网络中断。

4. 进阶场景实战:不止于HTTP,覆盖开发全链路

4.1 SSH远程登录:把家里的树莓派变成随身Linux

很多用户想远程管理树莓派,但又不想开路由器DMZ。frp可完美解决:

# 在client端frpc.ini中新增一段 [ssh] type = tcp local_port = 22 # 树莓派SSH默认端口 remote_port = 6000 # 外部访问时用的端口(避开22,防暴力扫描)

保存后重启frpc(pkill frpc && ./frpc -c ./frpc.ini &),然后在外网电脑执行:

ssh pi@118.25.32.101 -p 6000

输入树莓派密码即可登录。remote_port设为6000而非22,是因为云服务器安全组默认屏蔽22端口,且可降低被自动化脚本扫中的概率。

注意:树莓派需先启用SSH(sudo raspi-config→ Interface Options → SSH → Yes),并确认sshd服务正在运行(sudo systemctl status ssh)。

4.2 HTTPS服务暴露:无需域名,本地自签证书直通

很多Web项目强制HTTPS,但申请Let's Encrypt需要域名。frp支持在client端做HTTPS终止:

[web-https] type = https local_port = 3000 # 你本地Node.js服务监听的HTTPS端口 custom_domains = 118.25.32.101 # 以下三行指向本地证书文件(需提前生成) tls_cert_file = /Users/yourname/certs/fullchain.pem tls_key_file = /Users/yourname/certs/privkey.pem

证书生成用mkcert工具(比OpenSSL更傻瓜):

# Mac安装 brew install nss mkcert mkcert -install # 生成证书(会输出fullchain.pem和privkey.pem) mkcert 118.25.32.101

这样,浏览器访问https://118.25.32.101时,frp client会用自己的证书解密HTTPS流量,再以HTTP转发给本地3000端口,全程无需修改业务代码。

4.3 TCP隧道:暴露数据库、Redis等非HTTP服务

假设你在本地运行MySQL(端口3306),想让公司同事临时连上来查数据:

[mysql] type = tcp local_port = 3306 remote_port = 3307 # 外部用3307端口连,避免与云服务器自身MySQL冲突

同事连接时,主机填118.25.32.101,端口填3307,用户名密码用你本地MySQL的凭证。但必须修改MySQL绑定地址:

-- 登录本地MySQL,执行 SELECT @@bind_address; -- 若返回127.0.0.1,需改为0.0.0.0 -- 修改my.cnf(Linux/Mac通常在/etc/mysql/my.cnf) # 在[mysqld]段添加 bind-address = 0.0.0.0 # 重启MySQL sudo systemctl restart mysql

警告:暴露数据库端口风险极高!务必在frps.ini中设置token强密码,并在云服务器安全组中,将3307端口仅对同事IP开放(如202.100.1.5/32),绝不可设为0.0.0.0/0。

4.4 多服务复用:一个client管理N个本地服务

不必为每个服务起一个frpc进程。一个frpc.ini可定义多个[xxx]段:

[common] server_addr = 118.25.32.101 server_port = 7000 token = 8a3b7c2d1e9f4a6b8c0d2e1f9a7b3c5d [web] type = http local_port = 8000 custom_domains = 118.25.32.101 [api] type = http local_port = 8001 custom_domains = api.118.25.32.101 # 需提前配DNS,或hosts文件映射 [ssh-rpi] type = tcp local_port = 22 remote_port = 6001

启动一次frpc,所有服务同时生效。Dashboard中会显示三条独立隧道。

5. 故障排查手册:95%的问题,三步定位法

5.1 连接不上?先做“三连问”

当浏览器打不开http://118.25.32.101:8080,别急着重装,按顺序问自己:

  1. Server端frps是否活着?
    执行sudo systemctl status frps,看是否active (running)。若否,查日志:sudo journalctl -u frps -n 50 --no-pager,常见错误:bind_port 7000: address already in use(端口被占)或token mismatch(token输错)。

  2. Client端frpc是否连上server?
    查client日志(Mac/Linux默认在~/.frpc.log,Windows在frpc同目录),找关键词login to server success。若看到dial tcp 118.25.32.101:7000: i/o timeout,说明网络不通——检查云服务器安全组、本地防火墙、client网络是否能ping通server IP。

  3. Local服务是否真在监听?
    在client本地执行:

    • Mac/Linux:lsof -i :8000(看是否有LISTEN状态进程)
    • Windows:netstat -ano | findstr :8000
      若无输出,说明你的Python服务根本没起来,或端口填错了。

5.2 日志分析速查表

日志关键词含义解决方案
proxy name [web] is already registered同名隧道已存在(如重复启动frpc)pkill frpc杀掉旧进程,或改[web]为[web-test]
get proxy status error: connection refusedclient连server失败检查server_addr、server_port、网络连通性、server防火墙
http: proxy error: no such domaincustom_domains填的域名未解析到server IP改用IP,或检查DNS配置
tcp: proxy error: dial tcp 127.0.0.1:8000: connect: connection refusedlocal_port服务未启动启动本地服务,或确认端口号
dashboard: user login failedDashboard账号密码错误检查frps.ini中dashboard_user/pwd

5.3 性能瓶颈预警:什么时候该升级配置?

frp本身资源占用极低(client端内存<10MB),但实际瓶颈常在两端:

  • Server端带宽饱和:Dashboard中Statistics显示“Bandwidth”持续>90% of max,说明云服务器带宽不足。解决方案:升级云服务器带宽(如从1Mbps升到5Mbps),或限制client上传速度(bandwidth_limit = 1MB)。
  • Client端CPU飙升:当暴露视频流(如FFmpeg推流)时,frpc CPU可能达80%。此时应启用use_encryption = true(增加CPU开销换安全性),或改用type = stcp(秘密TCP,需双方配置)。
  • 连接数超限:免费云服务器常限制并发连接数(如腾讯云轻量默认1000)。Dashboard中Clients数接近上限时,新client会注册失败。解决方案:优化业务连接复用,或升级服务器规格。

最后分享一个小技巧:我给自己所有frp client配置了log_file = ./frpc.log和log_level = info,然后用tail -f ./frpc.log | grep -E "(success|error|fail)"实时过滤关键日志,比翻全量日志快十倍。这个命令可以直接保存为watch-frpc.sh,双击运行。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询