news 2026/10/16 3:42:09

闲置旧笔记本别扔!用frp内网穿透搭建个人服务器,低成本实现外网访问

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
闲置旧笔记本别扔!用frp内网穿透搭建个人服务器,低成本实现外网访问

1. 从一台吃灰的旧笔记本说起:我为什么要在家里搭一套内网穿透

家里那台用了五年的旧笔记本,卖掉不值几个钱,扔了又可惜。某天我盯着它想了半天——8GB内存、256GB固态、i5处理器,这配置跑个轻量级服务绰绰有余,为什么不让它发挥点余热?于是我开始琢磨:能不能把家里的这台机器变成一台随时可以访问的服务器?

问题很快就来了。家里的宽带分配的是内网地址,外网根本访问不进来。运营商给的那个地址每隔几天就变一次,就算把服务跑起来,出门在外也连不上。我试过打电话问运营商要固定地址,对方说个人宽带不给办。也考虑过把服务部署到云服务器上,但云服务器配置稍微像样点的,一年下来少说也要大几百块,而且数据放在别人那里,心里总归不太踏实。

这时候内网穿透就派上用场了。简单说,内网穿透就是让外网的请求能够“穿透”层层路由和防火墙,到达你家里那台处于内网环境的机器上。实现内网穿透的方案有好几种,我前后折腾过不少,最后稳定用下来的是一套叫frp的工具组合。它由两部分组成:一个跑在具有公网地址的机器上的服务端,一个跑在你家里内网机器上的客户端。客户端主动向服务端建立一条长连接,外部的访问请求先到服务端,服务端再通过这条已经建立好的通道把流量转发到内网机器上。

这套方案的好处很明显:你不需要动家里的路由器配置,不需要向运营商申请任何东西,只要有一台具备公网访问能力的机器作为中转就够了。这台中转机器可以是一台最低配的云主机,成本压得很低。整条链路是加密的,安全性也有基本保障。

这篇文章适合几类人看:手里有闲置电脑想废物利用的、想在家里搭个人网盘或代码仓库的、做开发需要临时把本地服务暴露出去联调的、以及对网络转发原理感兴趣想动手实践的朋友。我会从整体架构讲起,把服务端和客户端的配置一步步拆开,再补充我自己踩过的坑和调优经验。整个过程不需要你具备专业的网络工程背景,跟着做就能跑通。

2. 动手之前先把架构想清楚:frp 到底是怎么把请求送进你家的

2.1 服务端与客户端的分工

frp 的工作模式可以用一个生活场景来类比。假设你住在一个管理严格的小区里,外卖员不能直接进小区送到你家门口。这时候小区门口有个快递代收点,外卖员把东西放到代收点,代收点的工作人员再根据地址送到你手上。这里的“代收点”就是服务端,它有一个对外公开的地址,任何人都能找到它;“你家”就是内网机器,外面的人直接找不到;而“代收点工作人员”就是那条由客户端主动建立并维持的长连接。

具体来说,服务端跑在一台有公网地址的机器上,它监听一个端口,等待客户端来连接。客户端跑在你家里的内网机器上,启动后主动去连接服务端,连接建立后这条通道就一直保持着。当外部用户想要访问你家里的服务时,他访问的是服务端的地址和端口,服务端收到请求后,通过之前建立的那条通道把请求转发给客户端,客户端再把它交给本地的服务进程。响应则沿着相反的路径返回。

这个设计最巧妙的地方在于:连接的方向始终是内网主动向外发起的。因为内网机器访问外网通常不受限制,所以这条通道很容易建立起来,而且不需要在路由器上做任何端口映射。这也是 frp 相比其他方案更容易上手的原因。

2.2 需要准备哪些东西

在正式动手之前,先把需要的资源列清楚,免得做到一半发现缺东西。

资源用途说明
一台具有公网访问能力的机器跑 frp 服务端最低配即可,1核1G足够
家里的内网机器跑 frp 客户端和实际服务旧笔记本、迷你主机、树莓派都行
服务端和客户端的 frp 程序核心转发工具从官方仓库获取对应架构的版本
一个域名(可选)方便记忆和访问不买域名直接用地址加端口也能跑

关于服务端机器的选择,我个人的经验是:不需要追求高配置,因为 frp 本身非常轻量,转发过程几乎不消耗什么计算资源,真正吃资源的是你跑在后面的实际服务。带宽方面,如果你只是用来做远程开发联调、访问个人文件,1Mbps到5Mbps的带宽就够用了;如果要传大文件或者做媒体串流,那就得看带宽上限了。

2.3 网络拓扑与端口规划

在配置之前,先在纸上画一下端口规划,这个习惯能帮你省掉很多排查时间。我一般会这样规划:

  • 服务端监听端口:用于接收客户端连接,比如 7000
  • 服务端仪表盘端口:用于查看连接状态,比如 7500
  • 对外暴露端口:外部用户实际访问的端口,比如 6000
  • 内网服务端口:你家里机器上实际服务监听的端口,比如 8080

这样规划的好处是每个端口职责清晰,出问题的时候能快速定位是哪一段出了岔子。比如外部访问不通,先看对外暴露端口有没有被占用,再看服务端有没有收到请求,最后看内网服务本身是否正常。

注意:服务端机器上如果有防火墙或安全组规则,需要放行上述端口的入站流量。这一步经常被忽略,导致配置看起来都对但就是连不上。

3. 服务端部署:把那台中转机器先跑起来

3.1 获取程序与目录规划

frp 的程序包在官方发布渠道可以直接下载,根据服务端机器的处理器架构选择对应的压缩包。下载完成后解压,你会看到两个可执行文件:一个是服务端程序,一个是客户端程序。服务端机器上只需要用到服务端那个。

我习惯把程序放在一个固定的目录下,比如/opt/frp,配置文件放在同目录的conf子目录里。这样做的原因是后续升级版本时,只需要替换可执行文件,配置文件不用动。目录结构大概长这样:

/opt/frp/ ├── frps ├── frpc └── conf/ └── frps.toml

配置文件格式方面,新版本的 frp 已经全面转向 TOML 格式,比早期的 INI 格式更清晰,也更好维护。如果你在网上看到的是旧版 INI 格式的教程,注意区分,不要混用。

3.2 服务端配置文件逐项拆解

下面是我实际使用的一份服务端配置,每一项都加上说明:

# 服务端监听端口,客户端通过这个端口来连接 bindPort = 7000 # 仪表盘配置,用于查看当前连接状态和流量统计 webServer.addr = "0.0.0.0" webServer.port = 7500 webServer.user = "admin" webServer.password = "换成你自己的强密码" # 认证配置,客户端必须提供相同的令牌才能连接 auth.method = "token" auth.token = "换成一串足够长的随机字符串" # 日志配置,排查问题时非常有用 log.to = "/opt/frp/frps.log" log.level = "info" log.maxDays = 7

这里有几个点值得展开说。认证令牌一定要改掉默认值,而且长度要够。我见过有人图省事用默认配置,结果服务端被扫描到之后,任何人都能往上面挂服务。令牌相当于服务端和客户端之间的暗号,对不上就不让连。仪表盘建议开启,它能让你直观地看到当前有哪些客户端连着、每个隧道转发了多少流量,排查问题时比翻日志快得多。日志级别平时用 info 就够了,遇到疑难杂症再临时调到 debug,不然日志文件会涨得很快。

3.3 让服务端稳定运行

配置写好后,直接运行服务端程序并指定配置文件路径即可。但如果你希望它在后台稳定运行、开机自启、意外退出后自动拉起,那就需要把它注册成一个系统服务。在大多数 Linux 发行版上,用系统自带的服务管理器来托管是最省心的做法。

创建一个服务单元文件,内容大致如下:

[Unit] Description=frp server After=network.target [Service] Type=simple ExecStart=/opt/frp/frps -c /opt/frp/conf/frps.toml Restart=always RestartSec=5 [Install] WantedBy=multi-user.target

Restart=always这一行很关键,它保证程序意外退出后会自动重启。我遇到过半夜服务端进程因为内存波动被系统回收的情况,有了这个配置,几秒钟后它就自己恢复了,第二天看日志才发现曾经断过。

服务启动后,用查看服务状态的命令确认它处于运行中,然后打开浏览器访问仪表盘地址,看看页面能不能正常打开。能打开就说明服务端这一侧基本就绪了。

4. 客户端配置:把家里的服务“挂”出去

4.1 客户端配置的整体思路

客户端要做的事情比服务端稍微复杂一点,因为它需要描述清楚“把哪个本地服务,通过哪条隧道,映射到服务端的哪个端口上”。一条完整的隧道配置包含几个要素:隧道名称、类型、本地地址和端口、远程端口。隧道名称是你自己起的标识,类型决定了转发方式,本地地址和端口指向你家里实际跑着的服务,远程端口是外部用户访问时用的端口。

frp 支持多种隧道类型,最常用的是TCP 类型,适用于绝大多数场景,比如网页服务、远程桌面、数据库连接等。如果你要暴露的是网页服务并且希望通过域名来区分不同的站点,那可以用HTTP 类型,它能根据请求中的域名信息把流量分发到不同的后端。还有一种UDP 类型,用于游戏联机、语音通话这类场景。

4.2 一份可直接参考的客户端配置

下面这份配置同时包含了 TCP 和 HTTP 两种隧道,你可以根据自己的需求删减:

# 服务端地址和端口 serverAddr = "你的服务端地址" serverPort = 7000 # 认证令牌,必须和服务端一致 auth.method = "token" auth.token = "和服务端相同的令牌" # 日志配置 log.to = "/opt/frp/frpc.log" log.level = "info" log.maxDays = 7 # 隧道一:把本地的网页服务暴露出去 [[proxies]] name = "web-service" type = "tcp" localIP = "127.0.0.1" localPort = 8080 remotePort = 6000 # 隧道二:通过域名访问,适合有多个站点的情况 [[proxies]] name = "blog-site" type = "http" localIP = "127.0.0.1" localPort = 8081 customDomains = ["blog.你的域名.com"]

第一段隧道把本地的 8080 端口映射到了服务端的 6000 端口。外部用户访问“服务端地址:6000”时,请求就会被转发到你家机器的 8080 端口上。第二段隧道用了 HTTP 类型,它不需要指定远程端口,而是通过域名来区分。当请求的域名匹配到配置中的域名时,流量才会被转发过来。

4.3 客户端侧同样需要托管运行

和服务端一样,客户端也需要长期稳定运行。在 Windows 上可以把它注册成计划任务,在 Linux 上同样用服务管理器托管。配置方式和服务端几乎一样,只是可执行文件和配置文件路径不同。

这里有一个我踩过的坑:客户端启动顺序。如果你的本地服务启动比较慢,而 frp 客户端启动很快,可能会出现隧道已经建立但后端服务还没就绪的情况,外部访问会报错。解决办法是给客户端服务加上依赖关系,让它在本地服务启动之后再启动,或者在客户端配置里加上健康检查相关的设置。我后来养成的习惯是,本地服务用服务管理器托管并设置好启动顺序,frp 客户端排在它后面。

5. 实测中遇到的那些坑:从连不上到跑得稳

5.1 隧道显示在线但访问不通

这是最常见的一类问题。仪表盘上明明显示隧道是在线的,但外部访问就是没反应。遇到这种情况,我一般按下面的顺序排查:

第一步,确认本地服务本身是正常的。在跑客户端的机器上直接用本地地址访问一下,比如curl 127.0.0.1:8080,看看有没有正常响应。如果本地都不通,那问题出在服务本身,跟 frp 没关系。

第二步,检查服务端机器的防火墙和安全组。很多人配置完 frp 就忘了这一步,服务端所在机器的防火墙把外部访问端口给拦了。用查看防火墙规则的命令确认一下,该放行的端口有没有放行。

第三步,确认远程端口没有被占用。服务端上如果已经有别的程序占用了你配置的远程端口,隧道虽然能建立,但流量到不了正确的地方。换一个端口试试就能验证。

第四步,看服务端日志。日志里会记录每一次连接尝试和转发情况,如果请求根本没到服务端,那问题在更前面;如果到了服务端但转发失败,日志里会有相应提示。

5.2 连接频繁断开又重连

有一段时间我发现隧道每隔十几分钟就断一次,然后自动重连,虽然能恢复,但正在进行的连接会中断,体验很差。排查下来发现是网络环境的问题:家里的宽带在某些时段会出现短暂的地址变化,导致已建立的连接失效。

frp 本身有断线重连机制,客户端检测到连接断开后会自动尝试重新连接。但如果断开太频繁,就需要从根源上找原因。我后来在客户端配置里加了心跳相关的参数,让连接保持得更稳定。另外,如果服务端和客户端之间的网络质量本身就不太好,可以考虑调整传输协议相关的设置,在稳定性和速度之间找一个平衡点。

5.3 传输大文件时速度不理想

用 frp 传大文件时,速度往往达不到带宽上限。这里面有几个影响因素:一是服务端机器的带宽本身有限,这是硬瓶颈;二是 frp 的转发过程会带来一定的额外开销;三是如果开启了加密,加解密也会消耗一些性能。

我的优化思路是这样的:如果服务端机器配置比较低,可以适当调整 frp 的传输相关参数,比如调整缓冲区大小;如果对安全性要求不是特别高,可以在确认链路本身安全的前提下,选择开销更小的传输方式。但说实话,如果经常需要传大文件,更好的做法是直接用对象存储或者文件同步工具,而不是让 frp 来扛这个活。frp 的定位是打通连接,不是做高速文件传输。

5.4 安全性方面不能偷懒

把内网服务暴露到公网,安全性是必须认真对待的事情。我总结了几条底线:

  • 认证令牌必须改,而且要用足够长的随机字符串,不要用有意义的单词。
  • 仪表盘不要对公网开放,或者至少设置强密码。仪表盘里能看到所有隧道信息,泄露出去风险很大。
  • 只暴露必要的端口,不要图省事把所有端口都映射出去。用不到的隧道及时关掉。
  • 定期看日志,关注有没有异常的连接尝试。如果发现某个地址在频繁尝试连接,可以考虑在服务端加上访问控制规则。
  • 保持 frp 版本更新,新版本通常会修复已知的安全问题。

提示:如果你的服务端机器有多个地址,建议把仪表盘和客户端连接端口绑定到不同的地址上,进一步缩小暴露面。

6. 让这套方案真正好用:几个提升体验的配置技巧

6.1 用域名代替地址加端口

直接用地址加端口访问虽然能跑通,但记起来麻烦,而且很多场景下不方便。如果你有自己的域名,可以把域名解析到服务端地址上,然后在 frp 里配置 HTTP 类型的隧道,用域名来区分不同的服务。这样一来,访问blog.你的域名.com就能到你家里的博客服务,访问git.你的域名.com就能到代码仓库,清清爽爽。

配置的时候注意,HTTP 类型的隧道需要服务端也做相应配置,指定用于接收 HTTP 请求的端口。这个端口和客户端连接端口是分开的,不要搞混。

6.2 给隧道加上访问控制

不是所有隧道都希望被所有人访问。frp 支持在服务端配置访问控制规则,可以限制哪些地址能访问哪些端口。比如你可以设置只允许特定范围的地址访问某个隧道,其他地址一律拒绝。这个功能在服务端配置文件的访问控制部分添加规则即可,语法不复杂,但能显著提升安全性。

另外,如果某个隧道只是临时用一下,用完就关,那最好的安全措施就是不用的时候把它关掉。我现在的习惯是,临时联调用的隧道单独放在一个配置文件里,需要的时候启动,用完就停,不常驻。

6.3 监控与告警的简单做法

服务跑起来了,怎么知道它是不是一直健康?我的做法是利用 frp 自带的仪表盘接口,写一个简单的脚本定期去拉取状态信息,如果发现隧道数量不对或者连接异常,就发个通知给自己。这个脚本不需要多复杂,几十行代码就能搞定,但能让你在问题发生的第一时间知道,而不是等自己要用的时候才发现连不上。

如果你不想写脚本,也可以用一个更土但有效的办法:在服务端机器上设置一个定时任务,定期用外部地址访问一下自己的服务,访问失败就记录一条日志。虽然笨,但管用。

6.4 多台内网机器怎么管理

当你不止一台内网机器需要暴露服务时,有两种组织方式。一种是在每台机器上都跑一个 frp 客户端,各自连接服务端,互不干扰。另一种是在一台机器上跑客户端,通过配置多条隧道指向不同的内网地址。两种方式各有优劣:前者管理分散但隔离性好,一台出问题不影响其他;后者管理集中但单点风险高。

我目前用的是第一种方式,每台需要暴露服务的机器上跑一个客户端,用不同的令牌或者不同的隧道名称前缀来区分。这样任何一台机器重启或者出问题,都不会影响其他机器的隧道。服务端的仪表盘上也能清楚地看到每个客户端的连接状态。

7. 这套方案还能怎么扩展

跑通基础的内网穿透之后,我陆续在这套架构上叠加了一些别的用法。比如把家里的旧机器变成了一个私人的代码仓库,出门在外也能提交和拉取代码;比如在上面跑了一个轻量的笔记服务,所有设备都能同步;再比如把家里的监控摄像头的画面通过 frp 转发出来,在外面也能查看。

这些扩展用到的核心机制都是一样的:本地跑服务,frp 负责把连接打通。区别只在于本地跑的是什么服务、需要暴露哪些端口、对带宽和延迟有什么要求。理解了 frp 的工作方式之后,剩下的就是根据具体需求去调整配置。

有一点需要提醒的是,随着暴露的服务越来越多,安全管理的复杂度也会上升。我的建议是定期梳理一遍所有隧道,把不再使用的及时清理掉,保持配置的简洁。配置越简单,出问题的概率就越低,排查起来也越容易。

最后分享一个我在实际使用中体会很深的心得:不要追求一步到位。我一开始就想把所有东西都配好,结果遇到问题的时候不知道是哪一步出了错。后来改成一次只加一条隧道,跑通了再加下一条,每一步都确认无误再继续。这样虽然看起来慢,但实际上是最快的路径,因为每一步都是可控的,出了问题也能立刻定位。这套方法不仅适用于 frp,折腾任何网络相关的配置都通用。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 3:41:47

log4net 1.2.10 老项目日志配置实战:从接入到避坑

简介:log4net-1.2.10 是 Apache 软件基金会推出的经典 .NET 日志记录框架,面向需要在开发、调试、运维阶段记录运行信息的 .NET 开发者。该版本同时提供源码与 DLL 文件,既能直接引用到项目中,也便于阅读源码理解其配置、Appender…

作者头像 李华
网站建设 2026/10/16 3:41:33

Java不支持多继承的背后:菱形问题、接口设计与JVM机制

如果你问一个刚学Java的人,Java最让人不习惯的规则是什么,“Java不支持多继承”一定排得上号。很多人从C转过来,第一反应是:为什么不行?别的语言能一个类继承多个父类,Java非要阉割成一个?这个问…

作者头像 李华
网站建设 2026/10/16 3:41:33

Java调用扫描仪:JNI桥接TWAIN协议与jtwain库实战解析

简介:一套由 Java 编写、通过 JNI 调用 C 动态库的扫描仪控制程序,面向需要在工程中集成扫描功能的开发者;它使用 C 封装底层扫描驱动并生成 jtwain.dll,由 Java 层完成调用,支持中文且不弹出扫描对话框,适…

作者头像 李华
网站建设 2026/10/16 3:40:12

Windows磁盘空间不足?从诊断到预防的C盘清理全流程

又是"磁盘空间不足"的红框警告。这句话对用Windows的人来说,熟悉程度不亚于开机蓝屏。我这两年帮朋友收拾电脑,几乎每个月都有人拿这个问题来求助。大部分人的第一反应是打开C盘,看到什么删什么,删完发现空出来几个G&am…

作者头像 李华
网站建设 2026/10/16 3:39:21

个人网站期末大作业实战指南:HTML+CSS+JS从规划到答辩

每年期末季,我的私信里都会收到一批“救急”请求,最典型的一句就是:学长,我的HTMLCSSJavaScript个人网站怎么看起来还是像上个世纪的页面?问到细节,多半卡在同几个问题上:结构没规划、样式写死、…

作者头像 李华