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

在外优雅访问家庭内网服务的姿势

  •  
  •   dhuzbb · 13 天前 · 2244 次点击

    在外优雅访问家庭内网服务的姿势

    前情提要

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

    起源

    前面的文章中讲到了如何搭建内网服务,以及如何通过内网 DNS 重写并结合子域名以及个人服务导航页来优雅的访问局域网内搭建的各种服务。

    很多小伙伴还是对在外远程访问家庭内网服务有很大需求的,下面就来讲解一下,我个人认为的比较不错的方式。

    安全原则

    远程访问家庭内网服务的原则只有一个,那就是安全性。

    五星上将麦克阿瑟曾经说过:不要为了方便而将内网服务直接暴露在公网上,那相当于在裸奔。

    选择的原因

    所有第三方的远程访问服务个人都不推荐。主要从速度、安全性、便捷性三个方面考虑如下:

    1. 速度方面:cloudflare 、tailscale 、zerotier 、frp 、蒲公英等所有需要第三方服务器中转的,速度都不太行。
    2. 安全性方面:数据经过了第三方服务安全性无法得到保障。
    3. 便捷性方面:最好能和在家里访问家里的局域网服务一样。或者能够一键连接访问家里的网络。

    我自己亲自实践过 cloudflare 、tailscale 、frp 等等很多的方案。最后觉得最理想的方案还是:公网 IP + DDNS + Wireguard 。

    这个方案是如何保证上述三点的呢?

    1. 速度方面。公网 IP 属于直连,比所有第三方服务都要快。能够完美的跑满家里的上传带宽。
    2. 安全性方面。不经过任何的第三方服务,且 wireguard 是开源软件,安全性有保障。
    3. 便捷性方面。可以将 wireguard 理解为一个 VPN 服务。一键即可连回家庭网络。和在家里访问家里局域网一样没有任何区别,不用改变自己的使用习惯。

    此外,上面的方案还带来了一个额外的优势,如果家里部署了科学上网服务,可以在外无缝使用家里的科学上网服务。

    实现步骤

    下面以公网 ipv4 作为演示。搞懂了原理,公网 ipv6 其实也是一样的道理,B 站有大佬发过 ipv6 的视频,这里就不在赘述了。

    前提条件

    • 具备公网 ipv4 或者 ipv6 。
    • 光猫最好桥接,路由器直接拨号上网。这样路由器上获取的 IP 直接就是公网 ipv4 或 ipv6 。

    光猫桥接其实不是必须的,只是为了操作更加的简单。不过个人还是强烈建议光猫改桥接路由器直接拨号的模式,这样可以省去光猫后台设置端口转发到主路由的步骤。

    步骤 1:动态域名解析

    具备了公网 IP 后,还存在着一个问题,那就是这个公网 IP 会随着拨号设备的每次重启而变化。即使拨号设备一直不重启,过一段时间后这个公网 IP 还是会变化的。

    所以需要 DDNS 动态域名解析服务来解决上面的问题,个人比较推荐 DDNS-GO 这个开源项目。

    既可以采用 Docker 部署的方式,iStoreOS 的应用商店中也有这个插件,安装部署非常的方便。

    https://github.com/jeessy2/ddns-go
    

    DNS 解析服务商选择国内的阿里、腾讯或者国外的 cloudflare 都没有问题(个人还是比较推荐互联网大善人 cloudflare )。

    一个可有可无的小 Tip:DDNS-GO 可以设置 Webhook 通知,当你家里的公网 IP 变化了,可以直接微信通知你。

    URL: 
    https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxx
    
    Request Body:
    {
        "msgtype": "text",
        "text": {
            "content": "公网 IP 变更:\n 新 IPV4 地址:#{ipv4Addr} \n 已解析的域名:#{ipv4Domains} \n 域名更新结果:#{ipv4Result}"
        }
    }
    

    上面 key 的获取可以参考 DDNS-GO 项目文档中的 Webhook 配置参考,个人比较推荐微信通知的方式,通过企业微信的个人团队来获取 key 。

    通知的效果如下:

    微信通知

    步骤 2:部署 Wireguard

    虽然 Wireguard 在 iStoreOS ( OpenWRT )下有对应的插件,个人还是比较推荐采用 Docker 的方式来部署 Wireguard 。

    Wireguard Docker 项目地址如下:

    https://github.com/wg-easy/wg-easy
    

    Wireguard Docker 部署命令如下:

    docker run -d \
      --name=wg-easy \
      -e LANG=chs \
      -e WG_HOST=binhome.cn \
      -e WG_DEFAULT_DNS=192.168.0.2 \
      -e WG_PERSISTENT_KEEPALIVE=25 \
      -e PORT=51821 \
      -e WG_PORT=51820 \
      -v ~/.wg-easy:/etc/wireguard \
      -p 51820:51820/udp \
      -p 51821:51821/tcp \
      --cap-add=NET_ADMIN \
      --cap-add=SYS_MODULE \
      --sysctl="net.ipv4.conf.all.src_valid_mark=1" \
      --sysctl="net.ipv4.ip_forward=1" \
      --restart unless-stopped \
      ghcr.io/wg-easy/wg-easy
    
    • 需要将 WG_HOST 中的域名替换为你自己的域名
    • 需要将 WG_DEFAULT_DNS 替换为你自己的内网 DNS 服务器。

    最新版本的 wg-easy 修改了密码生成的方式,如果 Wireguard 的管理后台需要密码进行保护,可以这样做:

    # 使用下面的 Docker 命令生成密码 Hash
    docker run -it ghcr.io/wg-easy/wg-easy wgpw 你的密码
    
    # 然后在上面的 Docker 执行命令中添加一条密码配置(记住密码前后需要有单引号):
    -e PASSWORD_HASH='上面生成的密码' \
    

    Android 、iOS 、Mac 等等各大平台都有对应的客户端软件,大家自行下载安装。

    Wireguard 的使用比较简单:wg-easy 的管理后台为需要远程访问的机器生成一个配置,客户端扫码进行连接即可。详细的步骤就不再演示了。

    如果是在主路由上安装的 Wireguard ,通过上面简单的 2 步就已经可以实现远程访问的需求了。

    步骤 3:设置端口转发

    Docker 部署 Wireguard 既可以在主路由上,也可以在旁路由上。我个人是在旁路由上安装的 Wireguard ,所以多了第三步:还需要在主路由上设置端口转发到旁路由。

    iStoreOS ( OpenWRT )的端口转发设置路径:网络 -> 防火墙 -> 端口转发。

    防火墙

    添加一条端口转发:将外部端口 51820 的 UDP 协议转发到内部旁路由( 192.168.0.2 )的 51820 端口去。

    端口转发

    实现效果

    下面演示一下手机远程连接的效果:

    远程访问

    旁路由部署附带的另外一个好处就是,如果家里的旁路由部署了科学上网服务,在外手机可以无缝享受到科学上网的环境:

    科学上网

    分析总结

    从始至终,只在主路由上对外暴露了一个 Wireguard 的 UDP 协议的连接端口,没有对外暴露任何的内网服务,别人想扫描爆破密码都没可能。

    整个原理和流程如下:

    • 由于具有公网 IP 并且设置了 DDNS ,所以在外访问 binhome.cn 就相当于直接访问家里的主路由。
    • 手机客户端通过 binhome.cn:51820 的 UDP 协议来连接家里的主路由。
    • 主路由将 51820 端口的 UDP 数据全部转发到旁路由( 192.168.0.2 )的 Wireguard 监听端口 51820 。

    因此,上面就完成了远程回家的步骤。

    在手机上内网子域名也能正常访问的原因在于:Wireguard 的配置中 -e WG_DEFAULT_DNS=192.168.0.2 指定了 DNS 服务器的 IP 。

    手机客户端能够无缝科学上网的原因在于:默认情况下所有流量都会走 Wireguard 的接口,并且在旁路由上部署了科学上网服务。

    Wireguard APP 设置

    Mac 电脑上的配置也是一样的,可以修改为只有家里的局域网段走 Wireguard 的接口。

    Wireguard Mac 设置

    这样当 Mac 电脑在公司 24 小时连接家庭网络的时候,可以避免公司内网环境无法访问的问题。

    29 条回复    2024-09-30 15:45:47 +08:00
    ztm0929
        1
    ztm0929  
       13 天前 via iPhone
    这里面的 Wireguard 与 Nginx 之类的 Web 反向代理服务器有什么区别?它们的安全性是一样的吗?
    dhuzbb
        2
    dhuzbb  
    OP
       13 天前
    @ztm0929 这话问得我无法回答呀,两个毫不相关的东西呀。
    kur0d3s
        3
    kur0d3s  
       12 天前
    tailscale 可以自建控制器 headscale
    dhuzbb
        4
    dhuzbb  
    OP
       12 天前 via Android
    @kur0d3s 可以是可以,麻烦且没必要,直连不好吗
    zzzyk
        5
    zzzyk  
       12 天前
    羡慕有公网 ip 的
    stefwoo
        6
    stefwoo  
       12 天前
    电信可以打电话找社区服务员找公网 ipv4 。ipv6 的话,好像三大运营商都自带。
    jwz426
        7
    jwz426  
       12 天前
    使用 wg-easy 如果想实现异地多个 LAN 互联的话,感觉没有直接用 OpenWrt 的 wireguard 方便。
    coolcoffee
        8
    coolcoffee  
       12 天前
    都有公网 IP 了,tailscale 、zerotier 这类 P2P 组网是大概率可以直连的,中转服务器只是用来前期握手而已。

    wireguard 原生的很大弊端就是如果宽带发生了重拨导致 ip 变更,免费版本的 DNS 缓存更新就是 5 分钟起步,急用的时候都是手动设置 ip 去连接,而且以前还遇到过客户端连接时间久了需要手动重连才能生效。这个要是对于长时间的远端异地组网是致命的。

    人生苦短,我选择 tailscale🐶
    relsoul
        9
    relsoul  
       12 天前
    不赞同 lz 的组网方案,我个人的建议是走 tailscale+自建中转站。

    19 年自己已经写过对应的阿里云脚本,走的定时器查询+阿里云 api 改 dns ,这里会有几个问题
    1. 阿里云的个人版 dns 解析不会那么及时生效(具体生效时间随缘),甚至你需要先 del 原有的解析记录再 add
    2. 公网 ip 随时会变,并且这个频率不会太低,尤其是当你有外网端口访问进来的时候,可能会导致上一秒能访问,下一秒 ip 就变了,目前除非是固定公网 ip ,这种动态公网 ip 就在挑战如何触发运营商的风控机制。

    至于 Wireguard ,用了 tailscale 的体验会比单纯搭建 Wireguard 会好很多。

    nps ,cloudflare zero ,基本上都用过,体验最好的还是 tailscale 。
    dhuzbb
        10
    dhuzbb  
    OP
       12 天前
    @coolcoffee tailscale 属于商业产品,当这个产品一家独大或者为了盈利说不定哪天就给你限速或者限制客户端数了,并且 tailscale 在国内是没有服务器的。wireguard 安装部署只需一条 docker 命令,使用也是极其傻瓜化的。客户端连接时间久了需要手动重连才能生效大概率是没有配置 WG_PERSISTENT_KEEPALIVE 。至少我在公司 24 小时连回家里没有遇到什么问题。
    dhuzbb
        11
    dhuzbb  
    OP
       12 天前
    @relsoul 你是购买了一台云服务器自己建的中转站吗?成本增加了呀。公网 IP 随时变化有点太夸张了,正常来说频率极低的。退一步说,即使公网 IP 发生了变化,DNS 解析还是之前的记录,DDNS-GO 可以通过微信通知 IP 变化了,我也能随时知道现在的公网 IP 是多少的。就我个人和同事的使用情况来看,都是认为 Wireguard 比较稳定。在公司 24 小时连回家里,没有遇到过啥问题。
    relsoul
        12
    relsoul  
       12 天前
    @dhuzbb 你应该是没详细用过 tailscale ,tailscale 如果可以自动打洞 那不会走中转,如果走中转 我看他直连的速度给的挺高的,当然后续我是为了稳定才自建的。
    哈哈 没事,不强求,我也只是提出另一种方案,ip 变化这块可能是运营商和地区问题。一个服务器的成本还是挺低的(轻量服务器)
    dhuzbb
        13
    dhuzbb  
    OP
       12 天前
    @relsoul #12 tailscale 能够直连不会走中转这个我都了解的。我有 2 个同事家庭宽带有公网 ipv6 ,现在就用的 tailscale ,有时候直连就失效了,通过 status 命令查看不是直连的,不是直连后 ping 值较高,连回家里有明显的卡顿感。
    swordspoet
        14
    swordspoet  
       12 天前
    我是用的 ipv6 ,只是需要公网支持 ipv6 才能访问家里的服务。
    coolcoffee
        15
    coolcoffee  
       12 天前
    @dhuzbb 目前 tailscale 自身是开源的,社区也有对应的 control panel 项目 headscale 。 如果 tailscale 作恶,完全就可以停留在当前版本不再更新。

    我觉得 tailscale 这种零配置才更算得上优雅,可玩性也高。可以方便的进行服务端下发路由,更加精细的 ACL 权限控制,更好的客户端管理界面。
    dhuzbb
        16
    dhuzbb  
    OP
       12 天前
    @coolcoffee #15 可能需求和想要实现的目的不同。我的目的就是连回家里,访问家里的局域网服务。在主路由或者旁路由上直接一条 Docker 命令就能解决对我来说非常棒。我之所以不使用 tailscale 的原因的很大一部分在于官方文档写得很糟糕,至于路由下发以及管理后台 json 格式的 ACL 说实话我个人能力不足,搞不太懂,看到就头大。如果要使用第三方的服务,我宁愿选择类似的 netbird ,官方文档就写得比 tailscale 好太多了。有文章专门对比 netbird 和 tailscale 的。
    lovepocky
        17
    lovepocky  
       12 天前 via iPhone
    你这都有公网 v4 了,可选方案多到数不清
    dhuzbb
        18
    dhuzbb  
    OP
       12 天前
    @lovepocky 话是这样说没错,不过只需一行 Docker 命令就能完美匹配我的需求,所以我选 Wireguard 。
    coolcoffee
        19
    coolcoffee  
       12 天前
    @dhuzbb netbird 我也有用过,但是 netbird 没能满足我的需求。因为不能在用官方控制面板的情况下加入自建节点来中继流量,全公共节点的情况下就是打洞完全依赖公网 ip ,不然就只能走国外中继节点。

    我是个人用 tailscale 官方控制面板+自建中继,给公司团队小伙伴用的是自建控制面板 headscale+自建中继,我自己同时两者来回切换没有感觉有任何不适。tailscale 客户端也很贴心的提供了多账户快速切换选项。

    至于你说的 tailscale ACL 控制上手难问题这点我不否认,如果不是需要给到团队管理来管控权限使用,我可能就继续保持了好几年的默认全开放习惯一直就那样用下去了。

    其实了解内部原理也很简单,默认是无限制开放互访就像路由器下面的所有设备一样。但是如果想要某些设备组之间能才能访问就得划分 VLAN 对应的给 tailscale 设备打 tag ,然后就是禁用掉默认全通的规则,先设置已经划分好的 tag 之间可以互相访问。某些设备可以添加多个 tag 来达到跨越多个 VLAN 的互通。

    另外像服务端下发路由,无非就是客户端声明哪些内部网段我可以代理,但是声明归声明,最后还是要从控制端面板上审批允许广播才行。我可以利用这个特性,局域网里面 NAS 、虚拟机等多个设备同时声明暴露内网但只放开一个,然后如果哪个设备宕机导致我访问不了家里内网,我直接把这个规则禁用掉切换掉另外一条,流量又能重新访问到家里面。

    我用 wireguard 原生有两年多了,但是四年前用了一次 tailscale 就再也没回去 wireguard 。tailscale 这种结合个人需求可简单可复杂的才是我梦想中的 VPN ,无论是新手、轻度玩机、重度发烧友都能适用。
    zhangyp7536
        20
    zhangyp7536  
       11 天前
    我想请教一下。我自己的家庭网络( NET0 )无公网 IP ,朋友的网络( NET1 )有公网 ip 。
    我计划在 NET1 上搭建一个 frps ,来穿透到 NET0 。NET1 上有一个域名( fake.com
    fake.com:7878 可以转发 frps 的 server.port ( 7000 )。
    zhangyp7536
        21
    zhangyp7536  
       11 天前
    @zhangyp7536 上面不小心回复了,也不知道如何删除。
    我想请教一下。我自己的家庭网络( NET0 )无公网 IP ,朋友的网络( NET1 )有公网 ip 。
    我计划在 NET1 上搭建一个 frps ,来穿透到 NET0 。NET1 上有一个域名( fake.com
    fake.com:7878 可以转发 frps 的 server.port ( 7000 )。那后续 NET0 上的 openwrt 配置好 frpc (例如转发 8989 ),我是不是通过 fake.com:7878 就可以访问到 NET0 上的 8989
    fly9i
        22
    fly9i  
       11 天前
    wireguard 方案挺好的。个人一般就家里搭建个,没那么多固定的网络环境,不需要那么高级的 SDN ,而且就算相同的环境 tailscale 、zerotier 就总有打洞失败的情况,说是自动化,用起来反而更复杂了。
    dhuzbb
        23
    dhuzbb  
    OP
       11 天前
    @fly9i 所见略同。
    FawkesV
        24
    FawkesV  
       11 天前
    楼主没太看懂。 我是 TP 路由器拨号, iStores 旁路由, 还有个 NAS 。
    我 wireguard 应该安装在 iStores 旁路由 上? 那我 TP 路由器的 IPV6 防火墙没法配置端口转发的呢? 那这个防火墙还需要开吗?
    FawkesV
        25
    FawkesV  
       11 天前
    我试了下,把 wireguard 安装在 NAS 系统中,VPN 连接后,关闭 TP 路由器的防火后,确实也是可以用局域网 IP 直接访问的。 🤔
    dhuzbb
        26
    dhuzbb  
    OP
       11 天前   ❤️ 1
    @FawkesV #25 上面写的白看了呀,我哭死。防火墙千万不能关掉呀,千万别关。默认是开启防火墙的。举一个简单的例子,你浏览所有的网站,别人都能看得到你的 ipv6 的地址,假设你把防火墙关掉了,别人随便就能看到你的管理后台啥的,爆破密码简简单单的事情。我没有 TP 的路由器,它的后台界面我不熟悉,ipv6 应该是要修改防火墙设置放行 wg 的端口。建议你去看一下 ipv6 相关的教程。
    FawkesV
        27
    FawkesV  
       11 天前
    @dhuzbb #26 远古界面,不能配置单独放行端口。。
    FawkesV
        28
    FawkesV  
       11 天前
    @dhuzbb #26 感谢 我又好好找了下,找到了。 有一个‘虚拟服务器’的应用,可以做端口转发 ,开启防火墙后也能够正常连接了!
    smartruid
        29
    smartruid  
       5 天前
    顶一个,我也是你这套方案。
    如果用苹果设备的话,ddns 通知可以通过 bark 推送。
    另外公网 ip 变更的问题,我这边不会随机重播,只要半夜手动或者定时重播一次,后续就只会在同一个时间点重播了,不影响白天使用。
    tailscale ,zerotier 这些工具,不喜欢他们的账号体系,配个路由还要上他们的 web 后台改,不好不好😁
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   735 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 21:57 · PVG 05:57 · LAX 14:57 · JFK 17:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.