如何将 LAN 中设备发往公网指定 domain:port 的 HTTPS 请求重定向到 LAN 中指定设备的 ip:port

2021-02-26 02:30:00 +08:00
 dLvsYgJ8fiP8TGYU

背景: 家中运行一台 NAS,为实现从公网(使用移动数据)访问,已通过一台拥有公网 IP 地址的云服务器配置端口转发服务,并申请了域名及 SSL 证书,目前运行良好。

用 PPT 画了个网络拓扑: https://i.imgur.com/0yGEJ6C.png

在外面使用移动数据连接家里的 NAS,需要访问云服务器的指定端口(示例: https://nas.example.com:12345 ),在这一过程中需要消耗云服务器的流量(废话)。

如果我回到家里,在局域网中访问上述 domain:port,依然可以成功连接 NAS,但还是需要消耗云服务器的流量。这部分流量其实消耗的有点冤,毕竟已经在同一个 LAN 里面了,按理说可以直连的。这样子不但多交钱,延时也增加了。

问题: 是否可以通过某种方式在局域网中重定向发往 nas.example.com:12345 的请求,使其无需经由云服务器中转而直接发往局域网中的 NAS 的指定端口?

  1. 尽可能避免用户在设备端进行操作,如记住不同的 ip:port,在网络环境变化时手动输入(可行,但用户操作不便,排除)

    • 我个人其实无所谓,主要是考虑到家里其他人不太懂计算机 /网络这块,
  2. 已经尝试过以下方案,效果均不好

    • 修改 hosts
      • 在 iOS 设备基本不可行,且离开局域网即失效
    • 在 NAS 上搭建基于 AdGuard 的 DNS 服务器
      • 在网络环境变换时,比如出门 /刚回家,可能是由于 DNS 缓存,不能实现无缝无感切换
      • 改 DNS TTL 有用吗?
  3. 可能可行的其他方案?

    • 路由器设置策略路由或其他某种设置
      • 对现有硬件改动最小。TP-LINK 企业级路由器,不清楚是否支持这样操作
    • 新增一个软路由?
    • 在 iOS 上运行某种支持通过判断当前 SSID 并修改请求的软件?
  4. NAS 用的是群晖,5001 是 HTTPS 端口

  5. 如果能实现 IP 地址重定向,但无法同时实现端口重定向,可妥协

    • 在 NAS 也开启 12345 端口,与云服务器端口号实现同步,并允许相应服务使用此端口
    • 云服务器端口需保持至少 10000+ 高位,以保证安全
4022 次点击
所在节点    NAS
43 条回复
dLvsYgJ8fiP8TGYU
2021-02-28 01:55:59 +08:00
感谢各位 V 友的回复!

家里是没有公网 IP,要不到,而且看到有人被识别所谓私设 web 被停宽带了……
我使用的是 nps/npc ( https://github.com/ehang-io/nps) 实现的端口转发,客户端运行在 NAS Docker 上。
证书使用的是付费证书,一年不到 10 美金,可以接受。而且 Lets Encrypt 的 OCSP 由于众所周知的原因不好使(直接影响通过手机上 Synology App 连接 NAS 的速度,当时查了好久最终发现是 LE 的 OCSP 挂了,换了个证书立马解决)

查看了路由器设置菜单,在「基本设置」-「 DNS 设置」-「静态域名映射」中新增了一条,将云服务器的域名映射到 NAS 所在 LAN IP,并在群晖的 Application Portal 中新增一条规则将 localhost:12345 指向 localhost:5001 (HTTPS)。

确实可以在手动切换 4G - Wi-Fi 的测试中,实现(基本)无感的切换,并且不会出现证书报错;从外面回到家里的过程中切换效果如何还有待观察。

通过 nslookup 和观察 DNS 缓存,基本可以确定路由器「静态域名映射」的实现方式也是和 AdGuard 类似的 DNS “劫持”。至于为什么在路由器端实现 DNS 劫持的效果比 AdGuard 稍微好一点?推测是由于我当时为了防止在 NAS 中 Docker 里运行的 AdGuard 突然挂掉,导致全家断网,在路由器 DHCP 页面填了 2 个 DNS 服务器地址:
- AdGuard (主用)
- 路由器(备用)
然后由于 TP-LINK 路由器某种不知名的 DNS 查询机制使得在路由器上实现要好于在 AdGuard 新建一条自定义解析??

关于安全问题:
@f165af34d4830eeb @julyclyde 感谢你们指出 高位端口 != 绝对安全,这一点我也深有体会。

大概是 1 年前有人扫到了我的 web page 然后试图通过枚举 admin 的密码,触发了群晖的安全机制,把 Docker 所在的 IP (172.*.*.*) 给 ban 掉了,导致彻底无法从外面访问,后来回家看日志发现了攻击痕迹。但 nps 不支持把公网访问者的真实 IP “传递”给客户端,也就是说从群晖的防火墙看来,这次是有人试图从本地 IP (172.*.*.*) 登录系统。

当然我后来通过查看云服务器上的 log 看到了攻击者的 IP,属于某欧洲国家,后来直接在云服务器防火墙把整个 CIDR 都给 block 了(反正我大概这辈子不会去那个地方)。后来也是考虑只允许来自中国大陆的 IP 通过云服务器访问,奈何 套路云 的防火墙面板不支持通过 ASN / Geo-IP 这些参数设置,只能手打 IP/CIDR (还是 cloudflare 好),遂放弃。反正一年碰不到几次攻击,大不了换个端口也能消停好久,也就是把家里不超过 10 台设备修改一下配置,改动成本不大。


TP-LINK 路由器似乎没有 ip tables 设置选项,手头上有台装了 PfSense 的软路由,这几天打算研究一下

@la0wei
@Sylv
@tankren
dLvsYgJ8fiP8TGYU
2021-02-28 01:58:43 +08:00
@julyclyde 不好意思似乎是 @错人了
@dorothyREN 见上一条,高位确实不等于安全
tankren
2021-03-01 09:36:32 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/756354

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX