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

8 小时 54 分钟前
 dhuzbb

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

前情提要

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

起源

前面的文章中讲到了如何搭建内网服务,以及如何通过内网 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 的视频,这里就不在赘述了。

前提条件

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

步骤 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-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 协议的连接端口,没有对外暴露任何的内网服务,别人想扫描爆破密码都没可能。

整个原理和流程如下:

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

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

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

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

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

360 次点击
所在节点    宽带症候群
2 条回复
ztm0929
8 小时 44 分钟前
这里面的 Wireguard 与 Nginx 之类的 Web 反向代理服务器有什么区别?它们的安全性是一样的吗?
dhuzbb
8 小时 41 分钟前
@ztm0929 这话问得我无法回答呀,两个毫不相关的东西呀。

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

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

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

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

© 2021 V2EX