V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
dhuzbb
V2EX  ›  宽带症候群

局域网内优雅的访问家庭内网服务

  •  
  •   dhuzbb · 67 天前 · 5507 次点击
    这是一个创建于 67 天前的主题,其中的信息可能已经有所发展或是发生改变。

    局域网内优雅的访问家庭内网服务

    前情提要

    《低成本家庭万兆内网搭建指北》
    《个人家庭网络布局分享》
    《家庭内网服务分享》

    缘起

    自从有了 NAS ,烦恼似乎开始变得多了。

    当家庭部署的内网服务多了之后,例如笔记、DNS 、影音、Wiki 等等各种各样的服务,记忆和管理这些内网服务就成了一个问题。

    直接在浏览器中输入内网服务的 IP:端口号,又面临记忆的负担,似乎不是一个优雅的方案。

    如何在局域网优雅的访问这些内网服务,减少心智负担成了一个不得不解决的问题。

    • 恰好域名可以用来替代 IP+端口号,方便记忆。
    • 服务较多,个人服务导航页可以方便的集中化管理。

    2 者结合可以完美的解决上面的问题,下面开始详细描述如何实现上面的需求。

    子域名规划

    根据内网服务的实际用途规划子域名如下,大家可以根据自己的实际情况自由发挥。

    域名 后端服务 说明
    https://binhome.cn http://192.168.0.4:3002 极空间 Docker 部署的 Sun-Panel 导航页服务
    https://note.binhome.cn http://192.168.0.4:28080 极空间 Docker 部署的笔记服务 Flatnotes
    https://book.binhome.cn http://192.168.0.4:8083 极空间 Docker 部署的阅读服务 Calibre-Web
    https://dns.binhome.cn http://192.168.0.10:80 PVE CT 容器部署的 DNS 服务 Adguard Home
    https://git.binhome.cn http://192.168.0.88:80 PVE CT 容器部署的 GitLab 服务
    以下省略 20 条 以下省略 20 条 以下省略 20 条

    想要实现的需求是:在局域网内部浏览器中输入 https://note.binhome.cn 这样的子域名,就能访问到局域网内部部署的笔记服务 http://192.168.0.4:28080

    反向代理

    上面子域名规划中的不同子域名映射到不同的后端 IP:端口,其实就是反向代理 Nginx 等服务需要做的事情。

    由于 Nginx 需要绑定 80 和 443 端口,推荐使用 PVE 的 CT 容器来部署 Nginx Proxy Manager 。

    Nginx Proxy Manager 非常的简单易用。无需编写复杂的 Nginx 配置就可以设置域名到后端服务的映射关系,非常适合小白用户。

    NPM

    除了反向代理之外,NPM 还支持泛域名 SSL 证书的申请,简单易操作。前提是事先购买域名并设置好 DNS 解析到主路由的公网 IP ,如果不介意浏览器中的红色安全提醒,也可以忽略。

    NPM SSL

    内网 DNS 重写

    完成了反向代理之后,还需要做的一步操作就是将所有 *.binhome.cn 的请求都指向 Nginx Proxy Manager 的机器 IP (假如是 192.168.0.8 )。

    修改主路由或旁路由的 Hosts 文件可以简单的达到目的:

    192.168.0.8 binhome.cn
    192.168.0.8 note.binhome.cn
    192.168.0.8 book.binhome.cn
    192.168.0.8 dns.binhome.cn
    192.168.0.8 git.binhome.cn
    以下省略 20 条...
    

    上面的做法不是不行,但还是太繁琐了,需要 一条一条的添加,实现上不够优雅。能不能只需要 1 条记录就实现呢?类似下面这种:

    192.168.0.8 *.binhome.cn
    

    DNS 重写可以完美实现上面的诉求。

    AdGuard Home 这款 DNS 服务支持泛域名重写功能。

    DNS Rewrite

    如果使用的是 OpenWRT 内置的 DNS 服务 Dnsmasq ,也能非常简单的设置泛域名重写功能。

    # 编辑 dnsmasq 的配置文件
    vim /etc/dnsmasq.conf
    
    # 在最后添加一行以下配置
    address = /binhome.cn/192.168.0.8
    
    # 重启 dnsmasq 服务
    service dnsmasq restart
    

    完成了以上设置,这样在局域网环境下,所有访问 *.binhome.cn 的请求都会解析到内网的 NPM 机器 192.168.0.8 上。

    原理解析

    下面针对上面所讲的内容进行原理解析:

    https://note.binhome.cn -> 192.168.0.2(内网 DNS 服务器) -> 192.168.0.8(NPM) -> http://192.168.0.4:28080
    

    局域网环境下整个访问流程如下:

    • 访问 https://note.binhome.cn 时,会先请求内网的 DNS 服务器 (192.168.0.2) 进行内网 DNS 解析
    • 内网 DNS 服务器会将所有 *.binhome.cn 的请求都指向 NPM 的机器 IP ( 192.168.0.8 )
    • NPM 相当于 Nginx ,会在内部将请求根据域名匹配到真正的后端服务 http://192.168.0.4:28080

    由此,就完成了请求不同的子域名,实际请求的是不同后端服务的需求。

    个人服务导航页

    集中化管理个人内网服务就需要导航页服务来实现了,推荐使用 Sun-Panel 。

    之前的文章有介绍过 Sun-Panel 是一个漂亮的服务器、NAS 导航面板、Homepage 、浏览器首页。

    Github: https://github.com/hslr-s/sun-panel
    

    部署效果如下:

    sunpanel

    类似比较出名的个人导航页还有 Heimdall 。( https://github.com/linuxserver/Heimdall)

    Sun-Panel 支持局域网和互联网 2 种模式,UI 更加简洁美观,个人更加倾向于使用 Sun-Panel 。

    后续

    完成上述操作之后,在局域网环境下,既可以直接在浏览器中输入 https://note.binhome.cn 这样的子域名来访问家庭内网服务。也可以设置浏览器的主页为个人导航页服务https://binhome.cn,一键点击访问对应的内网服务。

    解决完了内网环境下的访问之后,如何在外优雅安全的访问局域网内的服务呢?

    详见后续系列文章:《在外优雅访问家庭内网服务的姿势》。

    47 条回复    2024-10-09 11:28:08 +08:00
    vate32
        1
    vate32  
       67 天前
    猜测一下,外网用 wireguard 等方式回家
    ztm0929
        2
    ztm0929  
       67 天前 via iPhone
    宽带运营商对 80/443 端口的封锁会导致外网无法直接访问域名,在内网的场景下,是否也会呢?
    0x663
        3
    0x663  
       67 天前   ❤️ 1
    @ztm0929 用 ipv6 没封锁 80/443 等端口
    ztm0929
        4
    ztm0929  
       67 天前 via iPhone
    @0x663 笑死😂无形中推广 IPV6 了 hhh 我研究一下
    esee
        5
    esee  
       67 天前
    直接对外网暴露端口不就等于上街不穿衣服嘛.
    dhuzbb
        6
    dhuzbb  
    OP
       67 天前
    @vate32 你猜的没错
    coolcoffee
        7
    coolcoffee  
       67 天前
    DNS 配置太复杂了,我选择三级域名直接公网 DNS *.nas.xxx.com 解析到群晖局域网 ip ,群晖上再配置反向代理到其它的局域网服务。
    dhuzbb
        8
    dhuzbb  
    OP
       67 天前
    @esee 没有对外暴露任何端口呀,上面讲的都是局域网内部的。
    dhuzbb
        9
    dhuzbb  
    OP
       67 天前
    @coolcoffee DNS 配置泛域名解析还算简单吧。其实原理都差不多的。不过我觉得二级域名用起来还是比三级域名更爽一些。
    BeautifulSoap
        10
    BeautifulSoap  
       67 天前 via Android
    这个方案两个比较麻烦点
    如果通过 wireguard ,tailscale 之类组网的话

    1. dns 是通过局域网 dns 解析的,在家庭局域网外无法正确解析。不如买个域名直接设定域名解析到 192.168.0.8
    2. 每次新增服务都要配置 Nginx 反代。

    所以我现在都是直接用 ip 加端口,然后搞个简单面板凑活用了,常用服务端口记得住,不常用的从面板进去。
    LogicDX342
        11
    LogicDX342  
       67 天前 via Android
    这种方案好像没法处理需要开放多个端口的容器以及非 http 服务?
    dhuzbb
        12
    dhuzbb  
    OP
       67 天前
    @BeautifulSoap 后续文章会讲到 wireguard 的用法,不存在在家庭局域网外无法正确解析的问题。域名直接解析到内网地址也是一个方案,但是这样就浪费了这个域名了。

    每次新增服务确实需要配置 Nginx 方向代理,但是有了 NPM ,基本上 10 秒钟就配置好了,后续也不用管了。
    nekomiao
        13
    nekomiao  
       67 天前
    借楼问下光猫改了桥接,也拿到 240e 开头的公网 ip 了,外面还是 ping 不到要怎么排查
    Dk2014
        14
    Dk2014  
       67 天前 via Android
    @nekomiao 那就是路由器问题了,可能是默认开了 v6 的防火墙
    Cheons
        15
    Cheons  
       67 天前 via Android
    佩服
    好几台云服务器都在吃灰,懒得折腾。
    unidentifiedme
        16
    unidentifiedme  
       67 天前
    少了上一步,Monitoring
    内网 DNS 我用的文中提到的另一种方法,专门的域名只解析到内网地址。Reverse Proxy 用的 Traefik 而不是 Nginx Proxy Manager 。
    还有下一步,Identity Provider
    PerFectTime
        17
    PerFectTime  
       67 天前
    直接 caddy 多好,这个 nginx proxy manager 自定义程度太低了,没必要
    me221
        18
    me221  
       66 天前
    Nginx Proxy Manager 换成 traefik 可以更方便一些
    FawkesV
        19
    FawkesV  
       66 天前
    楼主 问一下题外话 暴露 ipv6 到公网有没有什么问题呀? 关了路由器的 ipv6 防火墙才能在外面直接
    dhuzbb
        20
    dhuzbb  
    OP
       66 天前 via Android
    @FawkesV 防火墙就像是大门,大门敞开了,只要你的域名或 IP 对外暴露了,那谁都可以随意进,爆破下密码都是轻而易举的事情。百分之一万不建议关闭防火墙。别急,后续文章会详细讲解在外访问家庭内务服务的方法。
    dhuzbb
        21
    dhuzbb  
    OP
       66 天前 via Android
    @me221 traefik 确实挺火的,有空我体验一下
    EdmondGUO
        22
    EdmondGUO  
       66 天前
    点赞点赞,写的不错。我是用的 paopaodns ,然后添加了解析规则把请求域名的直接给 npm 所在的机器。
    不过唯一遇到的问题是内网搭建的测速点,如果直接用 ip 访问可以跑满 2.5Gbps ,如果用域名访问的话,速度会衰减很多,貌似是经过 https 反代的原因。所以我感觉在内网如果是高速传输的任务,还是写 ip 比较好。如果是 web 服务倒是无所谓了
    WhatTheBridgeSay
        23
    WhatTheBridgeSay  
       66 天前
    @vate32 #1 没必要,家宽带公网 IPv4 直接端口转发就是,用同一套域名,区别就是在家局域网的时候用 DNS rewrite 劫持解析结果成局域网 IP ,公网依旧是会正确解析到公网 IP 访问。至于端口号的问题可以通过某些方式做映射,比如套一层 cf 用 Origin Rules 将标准端口映射成没有被 ISP 屏蔽入站的端口,或者干脆手输非标端口号也不是不行,甚至可以指定两个 hostname ,一个走 cf 不用输端口号,一个手输端口号但是直连
    tunggt
        24
    tunggt  
       66 天前
    其实你这都 nas 搭建了,干嘛不直接用 CF Tunnels 或者 frp ,让外网也直接可以访问
    至于静态站点,例如导航类,真没必要部署在 nas 上。直接用 cf workers 或者 vercel 之类更方便
    hefish
        25
    hefish  
       66 天前
    我是扛着 nas 去上班的。到哪儿都是直接访问。
    fcbwalk
        26
    fcbwalk  
       66 天前
    我的方案是域名全部配置解析局域网 ip,所有服务的访问都通过域名方式。然后外网借助 zerotier ,内网一台设备连接 zerotier ,配置为网关转发路由到局域网,然后 zerotier 官网配置路由。这样内外网就保持了一致。
    starrynight9
        27
    starrynight9  
       66 天前
    openwrt 内网访问直接 hostname 就可以了吧,比方说 hostname 是 debian ,那么可以使用 http://debian 或者 http://debian.lan 访问其 80 端口服务,openwrt 的 search domain 是 .lan ,属于局域网
    standin000
        28
    standin000  
       66 天前
    @hefish 多大的 nas ?可以多站点同步吗
    hefish
        29
    hefish  
       66 天前
    @standin000 大倒确实是不大,就一个软路由大小,多站点同步肯定是不支持的。。。我就这一个站点嘛。。
    standin000
        30
    standin000  
       66 天前
    @hefish 东西带来带去很容易丢失的,要是能同步就好
    hefish
        31
    hefish  
       66 天前
    @standin000 说实话,就扔车子后备箱里, 最近阶段躺平, 所以已经有很多天不拿出来了。。。在家也是躺平, 用不上 nas 。
    goodryb
        32
    goodryb  
       66 天前
    说实话,要是局域网,一个书签 或者一个导航页就解决了,用不着这么复杂
    dhuzbb
        33
    dhuzbb  
    OP
       66 天前
    @hefish #25 你是我听到的第一个扛着 NAS 去上班的。话说经常移动 NAS ,机械硬盘不会受到震动从而容易损坏吗?
    dhuzbb
        34
    dhuzbb  
    OP
       66 天前
    @tunggt 速度太慢,体验不好
    dhuzbb
        35
    dhuzbb  
    OP
       66 天前
    @goodryb 你说的对。但是能够通过域名访问,并且附带 https ,那不是更酷吗?
    dhuzbb
        36
    dhuzbb  
    OP
       66 天前
    @goodryb 其实对懂的人来说,一点也不复杂,都是分分钟的事情。
    hefish
        37
    hefish  
       66 天前
    @dhuzbb 固态的嘛,机械的装毛片的不移动。。。
    lcy630409
        38
    lcy630409  
       66 天前
    都内网了 还要这么长的域名干啥?
    用域啊
    或者直接 a.cn b.cn 在内网 全世界的域名都是你的
    cdwyd
        39
    cdwyd  
       66 天前
    和你的方案差不多,少了一步内网 DNS 重写。完全可以直接把域名泛解析到 nginx proxy manager 所在的内网 IP ,然后配合你后面那篇用 wg 访问内网,既可以避免多服务直接暴露也减少中间步骤。
    dhuzbb
        40
    dhuzbb  
    OP
       66 天前
    @lcy630409 其实是为了申请 SSL 证书,这样可以 https 访问,浏览器不会因为证书的安全性问题给出提醒。以及后续文章中也有写到,配合 wireguard 连回家里也需要域名访问的。
    dhuzbb
        41
    dhuzbb  
    OP
       66 天前
    @cdwyd 牛哇牛,醍醐灌顶了。但是这样做 SSL 证书就无法申请了。使用自签证书,浏览器会有安全提醒,还需要手动信任证书,强迫证患者可能有些许接受不了。
    cdwyd
        42
    cdwyd  
       66 天前 via Android
    @dhuzbb 可以申请的,npm 通过 api 权限使用 dns 解析记录的方式进行验证能申请单 let ' s encrypt 的泛域名证书,也能自动更新
    swordspoet
        43
    swordspoet  
       66 天前
    @nekomiao 防火墙设置一条放行 wan 到 lan 的策略,限制好端口
    isnullstring
        44
    isnullstring  
       65 天前
    都说 traefik 更方便些?看文档有点难上手
    主要是折腾的服务到最后经常用的可能也就 5-6 个,其他都是闲着
    习惯 NPM 配置,弄起来也快,鼠标点点完事
    oneisall8955
        45
    oneisall8955  
       65 天前
    我更喜欢 nginxui 这个项目
    dhuzbb
        46
    dhuzbb  
    OP
       65 天前
    @isnullstring 所见略同。NPM 添加一条反向代理几秒钟就搞定了。小白用户首选。
    peyppicp
        47
    peyppicp  
       50 天前
    我的思路:用 macvlan ,每个容器创建的时候直接分配独立的 ip ,然后用 adguardhome 配置 dns 域名解析到对应的服务 ip 地址。
    dhcp 配置首选 dns 为 adguardhome 所在 ip 地址
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5562 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 41ms · UTC 06:50 · PVG 14:50 · LAX 22:50 · JFK 01:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.