组了一台 NAS
我最近组了一台 NAS,用于同步手机上的相册、自建云盘存储文件、同步 Obsidian 的笔记、存储和管理影音资源、搭建 Git 托管代码等。这篇文章记录我是怎么做的。

硬件
主板选用云星 CS246,一款专门面向 NAS 的 ITX 小主板。它有 LGA 1151 CPU 插槽、2 个 2.5G 网卡(可加钱升级成 4 个)、8 个 SATA 3.0 接口、两个 NVMe 插槽,很适合用来做 NAS。花费¥429。
CPU 买了个 i3 9100T 二手散片。4 核 4 线程,带核显,可以硬解码,做 NAS 基本够用;TDP 35w,比较省电。花费¥135。
内存条选用七彩虹 DDR4 2666 8GB。说实话 8G 有点小,但是考虑到我的腾讯云服务器内存才 1G,苦日子过惯了,8G 凑合着也能用。花费¥119。
固态硬盘也是七彩虹的,CN600 128GB。Linux 系统盘 64G 都绰绰有余了,不过现在能买到的 NVMe 硬盘最小也有 128G。花费¥115。
机箱选的是疾风知 N52 NAS 机箱。它有 5 个盘位,硬盘仓支持安装风扇给硬盘散热。选它是因为我觉得它比较好看,而且相对便宜。花费¥229。
电源选了个 TT TRM SFX 350W。花费¥159。
散热器选了个铜芯铝鳍片的下压式散热器,花费¥27。硬盘仓风扇买的是利民的 12CM 无光静音风扇¥17。
总共花费¥1230。算下来,似乎并不是很划算😂。但自组 NAS 图的就是 DIY 的乐趣,为的是自由定制的权力,便不计较这个了。
系统
系统安装的是 Ubuntu 24.04.3 LTS。我理解的 NAS 就是一台 Linux 服务器,需要什么服务就在上面装就好了,这样最能自由定制,因此没有选择飞牛之类的 NAS 专用系统。主板装好后,插入安装 U 盘试下能否点亮。成功点亮后,顺便也把系统装好了。

硬盘
我本想用两块硬盘组一个 RAID 1,但是现在机械硬盘涨价严重,就只买一块 4 TB 的西数红盘。反正一块硬盘一时半会儿坏不了,等后面硬盘降价了(希望),再组成 RAID 1。
为了后续扩展成 RAID 1,我把这块 4 TB 的硬盘组成一个单盘的 RAID 1。首先使用 parted 创建分区,执行 sudo parted /dev/sda 进入 parted 交互界面,然后依次执行
1 | |
然后使用 mdadm 创建 raid:
1 | |
然后挂载到 /data:
1 | |
Mdadm 的配置最好也持久化一下:
1 | |
以后如果要加硬盘,可以执行以下命令即可:
1 | |
网络环境
我对网络环境有几点要求。第一,不能只在内网访问,在外面也要能访问。第二,要用域名访问,用不同的域名区分不同的服务,而不是用 IP + 端口。第三,同一个服务在内网和外网的访问地址是一样的,这样回到家后不需要修改任何配置。
Tailscale 实现内网穿透
为了实现内网穿透,我的方案是使用 Tailscale。Tailscale 是一个基于 WireGuard 实现的 VPN,通过 UDP 打洞实现内网穿透。如果打洞成功,则可以直连通信,无需经由中继服务器;通信速度取决于带宽,非常方便。
Tailscale 非常容易使用。在机器上安装好 Tailscale 后,执行 tailscale up,访问链接登录账号,即可将当前主机加入这个账号下的 Tailscale 网络 (Tailnet)。
1 | |
同时手机上也安装 Tailscale 客户端,登录账号后,也可以加入我的 tailnet。这样手机和 NAS 便可以随时通信。

NAT 打洞也不是总能成功。根据 Tailscale 官方文档,如果通信双方都在 Hard NAT 中,则不能实现直连。就需要通过中继服务器(称为 DERP),速度很慢。
| Client A NAT Type | Client B NAT Type | Expected Connection |
|---|---|---|
| No NAT | No NAT | Direct |
| No NAT | Easy NAT | Direct |
| No NAT | Hard NAT | Direct |
| Easy NAT | Easy NAT | Direct |
| Easy NAT | Hard NAT | Relayed |
| Hard NAT | Hard NAT | Relayed |
好在现在宽带基本上都提供 ipv6 公网地址。我在光猫上开启允许内网设备使用 ipv6 通信,让 NAS 拥有公网 ipv6 地址。这样,使用 4G/5G 网络能 100% 直连;在外面连的 WIFI 如果支持 ipv6,也能直连。
配置 DNS 服务器
我的目标是在家里连上家里的 WiFi,或者在外连上 VPN,都可以用同样的域名访问 NAS 上的服务。这首先要在 NAS 上部署一个 DNS 服务器。我使用的是 CoreDNS,它的配置非常简单:
1 | |
这样的配置让 CoreDNS 监听 192.168.1.2:58,在 hosts 中配置域名解析规则。其他域名默认 forward 到系统 DNS 解析。在路由器中将 NAS 的 IP 地址固定为 192.168.1.2,并将首选 DNS 服务器设置为 192.168.1.2。这样任何通过我家路由器上网的设备都可以通过域名访问 NAS 上的服务。
为了让连上 VPN 的设备也能用同样的域名访问 NAS,我们在 Tailscale 的控制台设置一个 Split DNS,地址设置为 NAS 的虚拟 IP;并指定后缀为 luyuhuang.tech 的域名请求 NAS 上的 DNS 服务器。

由于 NAS 的虚拟 IP 和物理局域网的 IP 不同,所以还要让 CoreDNS 监听虚拟 IP,解析结果也要返回虚拟 IP。
1 | |
这样,例如同样是访问 nas.luyuhuang.tech,内网设备解析得到 192.168.1.2,连上 VPN 的设备则得到虚拟 IP 100.64.0.3。它们都可以用同样的域名访问 NAS。
配置 Nginx 和 HTTPS
我是用 Nginx 作为所有服务的反向代理,这样可以统一使用 80 或 443 端口,但使用不同的域名区分不同的服务。为了简单我直接使用 Docker 版的 Nginx,简单写个 docker-compose.yaml 即可。因为要反向代理到各种服务,网络模式使用 host 模式。
1 | |
我的域名 luyuhuang.tech 申请了 Let’s Encrypt 的证书,因此可以直接使用这个证书部署 HTTPS 服务。简单写个脚本同步证书到 NAS 上,这样也不用担心证书过期。
这样服务配置起来就很简单了。例如我的 Homepage 服务(下文会介绍)监听 http://127.0.0.1:4000,Nginx 这边就直接反代过去:
1 | |
安装各种服务
这里介绍几个我的 NAS 上安装的服务。这些服务都是用 Docker 安装的,安装步骤都很简单,这里就不介绍了。
Immich
Immich 是一个自建相册服务。它自带 Android 和 iOS 手机客户端,可以将手机的相册同步到 NAS 上。实际上我这次搞 NAS 的导火索就是我的小米云相册的容量满了。它支持 AI 人脸识别、以文搜图的功能(需要 GPU 支持);支持地图足迹功能。我用下来体验还是很不错的。

Cloudreve
Cloudreve 是自建网盘服务。它的网页端功能很不错,大多数格式的文件,无论是图片、音乐、视频,还是文档、压缩包,都可以直接在网页端打开。它支持 WebDAV,我用来作为笔记软件的同步服务;支持离线下载,我用来下载影音资源。它还支持各种云服务的对象存储,不过我暂时还没用到。缺点是没有 Android 客户端,iOS 客户端则需收费。

qBittorrent
qBittorrent 不用介绍了吧,著名的 Bittorrent 下载器。它可以与 Cloudreve 联动,作为 Cloudreve 的离线下载器。在 Cloudreve 中创建离线下载任务,调用 qBittorrent 下载,下载完成自动存入 Cloudreve 网盘。

Jellyfin
Jellyfin 是一个影视资源库。它将影视资源整理成影片和剧集,并从影视数据库中拉取海报、标题、介绍等元数据,方便观看。它能保存观看进度,并支持服务器解码(硬解码需要 GPU 支持),方便在各种设备中观看。除了网页端和 PC 客户端,它还支持手机客户端和 TV 客户端。

我让 Jellyfin 通过 WebDAV 挂载 Cloudreve,使用其中的影视资源。Jellyfin 本身不支持远程挂载,我使用 Rclone 的 Docker 插件,让 Docker 将 WebDAV 链接挂载成 Jellyfin 所在容器的 volume。
1 | |
Homepage
最后我还部署了 Homepage,将 NAS 上所有的服务都集中到一个主页,顺便还能显示机器的基本状态、各个服务的运行状态。
