访问家庭内网
背景
我在老家有一台家用 PC 作为家庭内网的服务器,上面用 Kubernetes 运行着一些服务:
- Vaultwarden
- Karakeep (Hoarder)
- Emby
- Gitea
- n8n
- immich
日常生活中,我极其依赖这些自己搭建的服务,比如通过 Vaultwarden 管理密码和 SSH 密钥,通过 immich 管理照片,通过 Gitea 管理代码,通过 n8n 管理自动化任务。
其中 Gitea 等服务偶尔需要暴露到公网,供朋友访问。
出于显而易见的安全因素,我无法把端口一开,将这些服务直接暴露到公网。
因此需要一些方案,让我和朋友能在任何地方访问家庭内网。
私有访问
内网的服务存了不少隐私信息,在内网都是与某些不受信任的设备隔离的。我自己访问内网的时候,当然也要尽可能保障安全。
DDNS + 代理服务器 (或 VPN)
大部分宽带现在都提供了动态公网 IP(仅 IPv6),可通过 DDNS 映射到域名。
某些路由器内置的 DDNS 服务安全性存疑,不建议使用。
可以使用自建的 OpenWRT 路由系统,安装 DDNS Go 等工具,配合权威 DNS 提供商和域名实现 DDNS。如果担心第三方软件安全性,可编写脚本接入 DNS 提供商 API 实现。
然后在路由器上开一个 VPN 服务和对应的端口,配置好就能在任何地方通过 VPN 访问内网。
之前我使用的是 SoftEther VPN。存在不少问题,比如在手机上只能连一个 VPN;又比如 Arm Mac 上没有对应的 Server Manager。
加上当时用的 OpenWRT 版本不太稳定,某次崩溃重装后,我就懒得再配置了。
Wireguard 也是一个不错的选择,配置比传统 VPN 简单多了。但这个世界上是存在 UDP QoS 的,Wireguard 在某些地区内部可用,可想跨地区就不好使了。UDP over TCP 的方案有,延迟会高一些,我并没有测试过,不知其稳定性。
因此,目前使用代理服务器方案。在 OpenWRT 上部署任意协议的代理服务器,在客户端配置规则,访问家庭内网段时走代理路径。某些 iOS 软件还支持基于 SSID 匹配,可实现在家庭 Wi-Fi 下直连,出门后自动走代理。
然而,这么做仍有一些不足:
- 宽带的 IPv4 被我所在地区的运营商收回,可 IPv6 仍未出现在所有网络环境中。
- OpenWRT 和运行在上面的服务不一定稳定。(幸好我的 OpenWRT 运行在 Proxmox VE 上,可以随时重启,不然已经炸了好几回了。)
- 配置错了或者服务没启动成功,也会导致没法访问内网了。
ZeroTier、Tailscale
此时就需要 ZeroTier 和 Tailscale 作为备用方案了。
它们具有以下特点:
- 无需自备域名和 DDNS
- 无需公网 IP 即可工作
- 配置简单,一个 ID 或登录链接即可完成
- 依赖第三方服务
虽然服务提供商故障会影响使用,但配合上述方案,同时出现问题的概率较低。
在手机上,由于 ZeroTier 和 Tailscale 都使用 VPN 接口,会占用 VPN 槽位,作为主要方案在多数情况下不够方便。
在 Android 平台上,存在 Magisk-Tailscaled 这样的项目,但一看名字你也知道,这需要 Root 权限。(现在连打着发烧旗号的某牌子都对 Root 百般阻挠了,还有几个品牌的手机是能 Root?)
除此之外,如果是团队需要访问内网的私密服务,相比上面的草台做法,这两种提供 ACL 的软件显然是更加合适的。
客观来说,Tailscale 的文档和 Dashboard 更加完善,但由于使用 Wireguard 协议,在某些地区连接不好使,相比之下我更倾向于选择 ZeroTier。当然,作为备用,可以选择两种都部署。
无论如何,作为第三方服务,且某些组件不开源,需要考虑隐私问题。对普通用户而言,需要多关注相关信息。
其他方案
不信任 Tailscale 和 ZeroTier,可以考虑自己部署 FRP。这需要有一台能访问的服务器,你又多了个需要维护的东西。
要解决宽带公网 IP 的稳定性(某些地区会无通知回收公网 IP,别问我为什么知道的),买个 CPE 插上 SIM 卡,或者似乎有方案能实现路由器连上随身 WiFi。
如果所有软件服务都不稳定,可考虑购买蒲公英等硬件作为最终备用方案(但隐私性存疑)。
以上方案都失效时,早点回家修复吧。
公开访问
上述的方案也是能实现让其他人访问你的内网服务的:所有人都准备好所需的软件,为他们提供访客账号(配置)即可。
对于亲近朋友或固定团队,这种做法尚可接受。
但对于演示产品或临时访问等场景,这种方式过于繁琐。如果访问者不可信,还需要担心更多安全问题。
还是需要一个(白嫖)方案,将内网服务暴露到公网,以允许他人公开访问。
这里推荐 Cloudflare Tunnel。
Cloudflare Tunnel 通过在内网运行 cloudflared
客户端,主动向 Cloudflare 边缘节点建立连接,将外网请求转发到内网服务。
优势很明显:
- 无需公网 IP 和端口转发
- 自带 DDoS 防护和 CDN 加速
- 配置简单,一条命令搞定
- 支持 HTTP/HTTPS、SSH、RDP 等多种协议
存在一些问题:流量绕行 Cloudflare 会增加延迟;所有流量经过 Cloudflare,隐私需要考量;免费版有并发和带宽限制。
尽管如此,它还是我目前用的最稳定的方案。
安全
最后得承认一个现实:这些方案都不够靠谱。
-
软件质量堪忧
OpenWRT 和相关软件都带有非专业属性。第三方软件包状况尤其复杂:有些几年没更新,有些作者已经弃坑,甚至有些包的来源都不太清楚。你真不知道哪天就会爆出安全问题。 -
第三方方案的风险
蒲公英等硬件厂商行为不透明;Tailscale、ZeroTier 虽然看起来专业,但部分数据仍需经过其服务器;Cloudflare Tunnel 虽然好用,但所有流量都经过 Cloudflare。 -
配置错误的风险
即使软件本身安全,配置不当也会带来巨大风险:防火墙端口配置错误、使用默认密码、权限过于宽松、缺乏网络隔离等。
既然风险无法完全避免,那就尽量降低:定期更新、最小权限原则、多层防护、监控日志、准备备用方案。
说到底,家庭内网的安全就是在便利性和安全性之间找平衡。完全安全是不可能的,但该有的安全意识还是要有,别等出了问题再后悔。