对于像我这样有技术倾向的人来说,Immich 可以轻松完全取代 Google Photos,但对于非技术倾向的人来说,它大概已经做到了 90%。那最后的 10% 对于像我家人这样的非技术人士来说,可能是一道难以逾越的鸿沟,他们大概以为 VPN 是“非常靠谱的新闻”之类的缩写。我的图库里满是父母和兄弟姐妹想看的照片,而几个月来,每次有人问“你能把这些发给我吗?”,我都只能把整个相册导出来发过去,而这正是我一开始就想避免的事。

后来,当我改用 NetBird 远程访问我的家庭实验室时,我意识到我可以简单地通过反向代理暴露我的 Immich 前端。这样一来,我的家人离他们想看的照片,就只差一个链接和几个密码了。

装 VPN 客户端?想都别想

装 VPN 客户端?想都别想

哪怕再简单,让人装个东西也是强人所难

哪怕再简单,让人装个东西也是强人所难

共享自托管服务,最直接的办法就是把所有人都拉进你的网络。Tailscale、普通的 WireGuard 以及 NetBird 自己的代理都能很好地处理这一点,如果你的受众哪怕有一点点技术背景,那基本上这一整套流程就都搞定了。不幸的是,我的受众并非如此,这意味着我需要动点脑筋来解决远程访问问题。要求我的父母每次想看照片时都安装一个 VPN 客户端并登录身份提供商,这根本行不通,哪怕这跟我后来想出来的办法其实差不了多少。

其他传统方案各有各的问题。端口转发会将 Immich 的登录页面直接暴露在公开的互联网上,反正这条路也走不通,因为我的 ISP 把我塞进了 CGNAT 里。Cloudflare Tunnel 可以用,但要是拿来传照片和视频库这种大流量数据,就不太行了。而且它也不是跑在我自己的机器上,我觉得这是个减分项。

我想要的是一个带身份验证的公网地址,最终落在我自己能控制的机器上,而 NetBird 的反向代理正好就是干这个的。这个功能在 0.65 版本中引入,内置于管理服务器中,通过 mesh 网络把内部服务暴露出来,TLS 加解密和身份验证都在代理层搞定。我的 Immich 容器压根没有公网 IP,我的家庭网络上也没有开放任何端口。流量到达我 VPS 上的代理,过了身份验证这一关,然后沿着现有的 WireGuard 隧道一路走到我 Proxmox 机器上的 Immich LXC。对我家人来说,这些背后的东西根本不存在。只有一个 URL、一个密码提示,然后就是他们的照片。

设置早就弄好了

设置早就弄好了

我只需要把登录信息给他们

我只需要把登录信息给他们

因为 NetBird 是我自己搭的,所以需要做一些基础工作。自托管部署需要在管理服务器前面架一个 Traefik,因为反向代理功能靠的是 TLS 直通,而其他代理不支持这个,如果你现有的部署用的是 Nginx 或 Caddy,那就意味着需要迁移。你还需要一个通配符 DNS 记录,把服务子域名指向你的服务器,443 端口得能访问,这样才能自动配置证书,另外还需要一个独立的代理容器,连接到管理服务器。NetBird 发布了一份迁移指南,详细讲了怎么把这些东西加到已有的部署里,我花了一个下午就搞定了。

好消息是,早在家人需要用之前,我自己就已经把这一切都搭好了,所以剩下的活儿就很简单了。把 Immich 开放出去本身只需要一个仪表板页面。在反向代理下,你添加一个服务,选择一个子域名,把目标指向 Immich 所在的节点。NetBird 会自动配好域名和 TLS 证书。在我创建的那个服务的身份验证标签页里,我启用了密码保护,设了一个强度高的共享密码,然后通过另一个渠道发给家人,没有和链接放在一起。首次登录之后,会话会通过令牌保持,所以他们不必每次都重新输一遍。

每个人都有一个真实账户,但私密之门由我掌控

每个人都有一个真实账户,但私密之门由我掌控

双重认证之墙

双重认证之墙

一个共享密码就能让家人通过代理,但这套方案更妙的地方在于它背后的东西。我没有让每个人都去用公开的分享链接,而是为每个人创建了独立的 Immich 账户,这样每个人用自己的凭据登录,拥有自己的图库、共享相册和 partner sharing(伴侣共享)。它的使用体验更接近他们之前用的 Google 相册,而不是一个装满导出 JPEG 的文件夹。老实说,有个小麻烦:首次访问需要两次登录,先输入代理密码,再输入他们的 Immich 凭据。实际上,两个会话都会保持,所以这是一次性的过路费,而不是每次都要交。

同一个反向代理还负责处理相反的需求。有些东西,比如 Immich 管理面板和我家庭实验室的其他仪表盘,根本就不应该能从公网访问到。NetBird 的解决方案是 0.72 版本引入的 NetBird-Only 访问,它使服务变为私有:没有登录页面,代理转而验证请求是否来自你 NetBird 网络中属于已批准组的节点(peer)。节点身份本身就是凭据,而且因为 NetBird-Only 和同一服务上的密码认证不能同时用,对于需要两者兼具的后端,做法是在不同子域上跑两个服务:一个公开、用密码保护,给家人用;一个私有,只给我自己的设备用。

这种方法确实有些坑要注意

这种方法确实有些坑要注意

你需要一台不限带宽的 VPS

你需要一台不限带宽的 VPS

整个方案的前提是你已经在 VPS 上运行了自托管的 NetBird 服务器。如果你从零开始,隧道服务能让你更快拿到一个公网地址。我家人每看一张照片,流量都得从那台 VPS 绕一圈,所以实际能跑多快,就看你服务商给你多少带宽和流量了,而照片库那流量可不是闹着玩的。而且由于密码验证是在浏览器里完成的,Immich 移动应用无法通过;外面的人只能用浏览器来看。不过你完全可以把这个服务改成只能通过 NetBird 访问,把它锁在 mesh VPN 后面,这样就能从应用正常访问了——但这正是我想帮不懂技术的家人避开的那道坎。

这是与家人共享照片库的最佳方式

这是与家人共享照片库的最佳方式

任何给家人用的家庭实验室服务,我都会拿一个标准来检验:技术最差的那个家人也能不能用——在这个方案中,他们可以。一个链接加一个密码,轻松过关。虽然安装 VPN 并完成初始设置其实并不复杂,但对普通人来说还是太陌生了,所以得换个别的办法。NetBird 的反向代理 还处于测试阶段,管理端还有不少坑,但它让我的 Immich 照片库从“我自己用的”变成了“我们一起用的”。