近几年家里陆陆续续购入了软路由和群晖 NAS 后,在家中的使用体验还不错,那么出门时又如何能无缝使用家中的服务呢?

如何在外网访问内网

对于外网访问内网的链路,我们通常称之为内网穿透,之所以是穿透,原因是目前大部分 ISP 并不会主动提供公网 IPV4 地址。虽然在部分地区可以与当地 ISP 沟通来获取,但住址变更、内网完全暴露后的安全问题也较为棘手。本人目前手上的宽带就没有提供公网 IPV4 地址,故需要通过一种穿透途径来打通内外网。(值得一提的是,截至 2021 年,很多 ISP 会主动提供公网固定 IPV6 地址,这也是一个可选方案,但据网友测评,目前国内 IPV6 的链路稳定性较差,所以还是实践才能出真知)。 目前常见的穿透方案大概有两类: - 一类是通过公网服务器与内网设备建立 TCP 长连,用户访问外网服务器时穿透程序会将流量通过之前建立的 socket 代理至目标内网设备上,由于是基于基础的 socket ,故每个转发关系都需要进行一次配置,即可以理解为内网 IP 和端口的排列组合,这种方案以 FRP 、NPS 和 Ngrok 为代表。 - 另一类实际上实现了一种虚拟私用网络方案,外网服务器负责维护网关,用户请求时需要先使用客户端连接到对应网络。这类方案由于应用层的逻辑不同有许多种实现,而我们知道大部分企业也是通过这种方式来打通内外网的,下文提到的 Zerotier 也是这种方案的变种。 那么这两类方案应该如何进行选择呢?我的解决方式是两条腿走路: - 借助 FRP 对常用的内网服务进行代理,这样只要有浏览器即可访问这些服务,不要求设备必须装有客户端,非常灵活。 - 另一方面建立基于 Zerotier 的私有网络,这样就不必为各种不常用的内网服务进行繁琐的 FRP 配置,同时像 SSH 、Windows 远程或 Git 服务等敏感、安全风险大的服务也无需直接暴露于外网之上。

内网穿透的前提条件

我们在内网直接访问各类内网服务的网络延迟是低于 1ms 的,但在公网上的耗时可就是几十毫秒起步了,此外,丢包率、带宽等问题也直接影响内网穿透的使用体验。所以选择一个链路稳定、带宽合适的公网服务器是非常有必要的。 这里提供几个选择方向做参考:

  • 购买三网优良线路如 GIA 或终端运营商可直连的非大陆 VPS 进行配置,通常网络耗时可控制在 100~200ms ,丢包率很低,由于这类服务商通常是共享 G 口的带宽,所以整体使用体验非常优秀。
  • 购买国内服务商机器,这种并不是很推荐,首先备案问题就很头疼,不备案的话由于常用端口不可提供 HTTP 服务, FRP 的配置问题重重。而且带宽通常只有 1~2Mbps ,浏览网页倒还好,视频是别想了,性价比很低。
  • 购买非大陆的高性价比 G 口机器,同时搭配国内的 NAT 中转服务解决网络链路差的问题,在 NAT 服务稳定的场景下使用体验不错。

内网穿透的安全性问题

正如前文所说,内网穿透在为我们带来便捷的同时,也为我们带来了一定的安全风险,失去了 NAT 网络的掩护,暴露在公网的服务将直面各类扫描和攻击,因此我们要采取一定的安全措施进行保护。 由于 Zerotier 本身的安全性目前没有明显问题,且内网服务实际上仍被一层 NAT 转换所保护,故不对此种穿透方式进行额外的安全处理。而 FRP 代理的服务则是直接暴露于公网的,我们可以考虑采取以下措施来进行安全加固: - 尽量不暴露老旧、小厂设备,比如路由器的管理界面等。这类服务维护强度低,很容易出现明显漏洞进而被利用。 - 不直接对外暴露 FRP 服务,而是通过 Nginx 反向代理 FRP 后向外暴露,并借助 Letsencrypt 生成 SSL 证书以使用 HTTPS 协议进行访问,同时应将 80 端口的 HTTP 请求重定向至 443 以强制使用 HTTPS 协议。 - 在 Nginx 配置中加入 robots.txt 的配置,在其中明确禁止搜索引擎抓取,同时禁止常见的各类爬虫 UA 访问。 - 如果一定要暴露老旧服务或敏感服务,那么即使服务本身有登录认证机制,也建议加入一层 Nginx 的 BA 认证机制,配合 HTTPS 可极大地提升服务安全性。