背景: 家中运行一台 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 的指定端口?
尽可能避免用户在设备端进行操作,如记住不同的 ip:port,在网络环境变化时手动输入(可行,但用户操作不便,排除)
已经尝试过以下方案,效果均不好
可能可行的其他方案?
NAS 用的是群晖,5001 是 HTTPS 端口
如果能实现 IP 地址重定向,但无法同时实现端口重定向,可妥协
1
learningman 2021-02-26 02:46:40 +08:00 via Android
可以,iptables SNAT 和 DNAT,DNS 管不了端口的
|
2
f165af34d4830eeb 2021-02-26 02:52:44 +08:00 via iPhone
|
3
f165af34d4830eeb 2021-02-26 03:09:41 +08:00 via iPhone
额外说一句,保证安全可不是靠高位端口这种野路子,外网访问内网走 vpn 更稳妥,不建议把私人 web 服务暴露在公网上。
|
4
Niphor 2021-02-26 04:00:50 +08:00
你路由器 host 里加一条,像 op 的话直接加 dnsmasq 里
|
5
ysc3839 2021-02-26 04:13:14 +08:00 via Android
nas.example.com 解析到云服务器,然后在路由器上修改 hosts 让 nas.example.com 指向 NAS 不就好了吗?为什么离开局域网失效不可行?你离开了局域网不是要走云服务器吗?
|
6
Sylv 2021-02-26 06:29:34 +08:00 via iPhone
首先路由器得支持 dnsmasq (我是华硕路由器刷了梅林系统)。
然后 ssh 到路由器上。 编辑 dnsmasq 配置文件: vi /jffs/configs/dnsmasq.conf.add 加入将 NAS 域名解析到内网 IP 的规则,例如: # NAS address=/mynas.com/192.168.1.10 然后重启 dnsmasq: service restart_dnsmasq 这样一来,内网访问 mynas.com 时就会通过路由器 dnsmasq 解析为内网 IP 192.168.1.10 ,直接内网访问 NAS,不需要出去外网再绕回来;外网访问时还是解析为外网 IP 。 |
7
soulzz 2021-02-26 08:54:56 +08:00
|
8
weyou 2021-02-26 09:19:49 +08:00 via Android
在路由器上将所有的 DNS 请求强制重定向到自己的 DNS 服务器可以解决缓存的问题。
比如在 Openwrt 路由上可以设置 Firewall Custom Rule: iptables -t nat -I PREROUTING 1 -i br-lan -p udp --dport 53 -j DNAT --to-destination <自己的 dns ip 地址>:53 |
9
weyou 2021-02-26 09:23:38 +08:00 via Android
会错意了,上述并不能解决已解析好的域名地址缓存
|
10
tankren 2021-02-26 09:26:37 +08:00
在家直接用局域网 IP 访问不就好了?自己给自己找麻烦
|
11
tankren 2021-02-26 09:27:00 +08:00
如果实在记不住 自己做一个导航页
|
12
locoz 2021-02-26 09:37:22 +08:00 via Android
内外网访问时,端口是否相同?如果相同的话,直接在路由器端做内网 dns,然后外网通过 vpn 连接回来,百分百无感切换。
|
13
hjylxmhzq 2021-02-26 09:53:03 +08:00
可以用 iptables 试试,如果只用网页端的话也可以做个跳转页
|
14
Slin 2021-02-26 10:22:52 +08:00
改下 host 文件不就行了吗 或者在 nas 搭建一个局域网 dns 服务
在家你的域名会被解析成局域网 ip,如果你就固定一台电脑使用 直接改 hosts 就行了 |
15
Slin 2021-02-26 10:26:36 +08:00
看了你后面说的问题,我没有遇到过, 你在切换网络环境 用 dig 命令, 测试下域名解析情况
|
16
Slin 2021-02-26 10:30:57 +08:00
@tankren 这种需求很常见,如果你使用 客户端填写 服务的访问地址,你就需要使用域名,内外网环境切换方便,不一定是 用在浏览器。
|
17
la0wei 2021-02-26 10:45:38 +08:00
我有类似的经验,前两天刚刚搞定。家里的 n2n 今早挂了,无法连上去看配置,我回忆下配置。
需要的设备:能自定义 hosts 的路由器一台,linux 设备一台或 linux 虚拟机,nas 如果能安装 haproxy 也行。 路由器配置:192.168.1.10 linux 设备:安装 haproxy,frontend 中 bind 端口 12345 。backend 中 server 指向 192.168.1.10:5001 原理:访问 nas.example.com:12345 时,路由器解析到 linux 设备的 ip,而该 ip:12345,则是反代的 192.168.1.10:5001 。 优势:无需改其他设备的配置,比如端口之类的。上面几个回答都解决了 ip 的问题,但是没解决端口的转换。 |
18
la0wei 2021-02-26 10:47:02 +08:00
#17 有误,应为 路由器配置:192.168.1.10 nas.example.com
|
19
la0wei 2021-02-26 10:49:02 +08:00 1
另外说一句,你画的 ppt 还怪好看的
|
20
tankren 2021-02-26 11:18:53 +08:00
@Slin #16 那倒是 不过楼主这种情况只能统一局域网端口和转发端口然后加上网关 DNS 覆盖才能比较完美的实现 有些人性化的客户端可以配置两套服务端信息 当连入指定 WiFi 时走局域网 IP
|
21
jim9606 2021-02-26 11:19:52 +08:00
如果不满意 dns 劫持的效果,我建议用 iptables dnat+snat,不过企业路由能不能支持类似功能我是不清楚了。
不过你用群晖的话 QuickConnect 好像就可以自动判断是否处于内网并自动做 301 跳转。通过浏览器 js 进行检测。 |
22
Maskeney 2021-02-26 11:35:18 +08:00 via Android
iptables 之类的方式劫持你的公网小鸡 IP 重定向到局域网 IP 上
|
23
Lemeng 2021-02-26 11:43:36 +08:00
可以,画拓扑图的点个赞
|
24
la0wei 2021-02-26 11:49:50 +08:00
@tankren 我的方案优点在于用户对修改无感知,低门槛。建导航的方法也是极好的,对习惯用浏览器的用户比较友好,但是对客户端要求比较高。
我为何研究这个方案,因为之前我有加速下载的需求,奈何 http 不能很好的利用我宽带的多拨叠加带宽,而 http 下载工具支持镜像功能的很少,还需要大量的手工操作,忒麻烦,才催生出这套方案。 靠手工配置确实可以解决问题,但是都太麻烦了,还是中心化的解决方案比较方便,一劳永逸。 另外我的方案和导航式的并不矛盾,可以很多好的融合 |
25
piku 2021-02-26 13:20:58 +08:00
问题我懂了。但下面回复的我没理解。
在家里还是用的域名吧。域名还是指向的公网 ip 吧。这就是简单的内网域名访问回流问题啊。 在家里网关路由器上做两条。先 dst-nat 把访问公网 ip:端口的重定向到内网 ip:端口。 然后 src-nat 把这部分流量 masquerade,否则回流有问题。 有的路由器直接有内网服务器选项,自己能处理回流。 |
26
hanguofu 2021-02-26 15:17:43 +08:00 via Android
请问如何在 局域网内输入自定义的名字就可以访问同一个局域网内的其它设备啊?
|
28
la0wei 2021-02-26 17:26:46 +08:00
@tankren #52 没有公网不影响吧。公网访问楼主已经自己实现了,你看原文。内外网原理是一样的,细微差别而已。
1.公网是公开的 dns 解析,内网是路由器自定义 hosts 实现,两者都实现了域名到 ip 的转换。 2.端口部分,我猜楼主用的是 frps:内网有个客户端,主动连接外网服务端保活,服务端转发到客户端实现对内网的访问。frps 和 haproxy 不深入探究原理的话,在这个例子里最根本的区别在于 frps 是反弹式的。 具体实现是否有问题还是看楼主操作后再看看。 有一个情况我觉得建导航的方式也是非常不错的,甚至部管端口,不一样就不一样。别在在手机上访问时没关流量,看电影把房子送给移动了。内外网有显著差异还是不错的,能提醒自己切换网络。 |
30
joesonw 2021-02-26 18:20:55 +08:00
路由器 ip tables.
|
31
la0wei 2021-02-26 18:54:14 +08:00
@tankren @piku 确实非常接近典型的 nat 回流问题,也启发了我。区别在于楼主的情况还是有不一样的,他没有公网 ip,防火墙 /路由器默认的的 nat 回流设置需要替换外网 ip 地址,需要设备支持命令行及 iptables
在路由器有公网 ip 的情况下,可以充分利用设备特性,此时不需要添加任何设备,不需要任何命令,全图形化操作。 tp-link 企业级路由器示例:问题描述及解决方法 https://blog.csdn.net/x55x5/article/details/86146915 不过 nat 回流只解决了 ip 的问题,没解决端口。不过咱可以修改内网端口,内网改成 12345 就好 https://serverfault.com/questions/592254/how-to-configure-synology-to-use-only-standard-http-ports-80-and-443-instead-of 路由器没有公网 ip 的情况下,我建议路由器自定义 hosts,同时修改群晖端口为 12345 。 这个方案应该是最精简的了。不需要添加任何设备,不需要任何命令行操作,避免了设备限制(自定义 hosts--路由器大概率支持,修改端口--群晖大概率支持)。 最终结论:路由器自定义 hosts,同时修改群晖端口为 12345 |
32
la0wei 2021-02-26 18:55:14 +08:00
|
33
no1xsyzy 2021-02-27 14:10:09 +08:00
话说,DHCP 下发路由表,使得公网 IP 导向群晖,然后在群晖上添加这个 IP (使得它收到 DST=IP 的包的时候自己消费掉),这也可行吧,就是挺邪门的。
甚至流量不用经过路由器? |
36
dorothyREN 2021-02-27 17:09:23 +08:00
是什么原因让你认为高位端口就安全了
|
37
julyclyde 2021-02-27 18:49:25 +08:00
如果端口相同且本来要访问的那个 IP 地址不变的话
直接在网关加路由,目标为本来要访问的,下一跳为实际访问的,然后在实际访问那个服务器上增加那个本来要访问的 IP 地址就行了 你需要考虑的是怎么搞到人家的 SSL 证书 |
38
la0wei 2021-02-27 20:22:58 +08:00
|
40
la0wei 2021-02-27 23:09:18 +08:00
@julyclyde 根据我个人非常浅薄的经验,没有遇到证书的问题。我在外网有个服务器,使用 cloudflare 反代,内网将域名指向一台 linux 设备,并在 linux 上使用 haproxy 转发。
PC-->局域网 haproxy-->cloudflare-->服务器 对于 let'encrpt 证书可能会出现问题,因为确实 ip 和地址不一致,但我认为可能出问题的是在签发阶段,ip 和域名不匹配,这个很容易理解。而签发完成后,证书是否能够用在别的服务器上,这点我就不清楚了。毕竟证书只关乎公私钥,ip 是否严格限制就不知道了。而 cloudflare 证书实测可行。 但我理解 haproxy 只是转发 tcp,证书还是从服务器获得的,对于局域网来说依然是原始 ip 和证书,出问题的可能性不大。 我内网没有类似群晖已经签发 https 证书的设备,暂时无法测试可行性。 |
41
dLvsYgJ8fiP8TGYU OP 感谢各位 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 |
42
dLvsYgJ8fiP8TGYU OP |
43
tankren 2021-03-01 09:36:32 +08:00
@dLvsYgJ8fiP8TGYU #38 pfsense 配置看这里 https://blog.51cto.com/fxn2025
|