家庭 NAS 搭建
自己电脑上各种资源实在太多,硬盘空间紧张。此时搭建一个 NAS 放在家里就显得很有必要了。于是今年终于动手了。
硬件
由于专门的 NAS 硬件太贵,动辄好几千。我便在淘宝上四百多块钱买了一块 12 * 12 cm 的主板,上面带一块 J1800 双核赛扬(有的 Atom 主板尺寸更小功耗更低,然而价格贵了些)。单独购买外置的 12 V 电源时,考虑到可能同时带一块 3.5" 硬盘和一块 2.5" 硬盘,于是买了 7 A 的适配器。又在淘宝上买了一块 3T 的西数红盘(WD30EFRX)作为硬盘。最后,把老笔记本上的 2G SO-DIMM 内存条拆下来装到主板上。
现在硬盘和主板直接放在柜子里,不过有个「机箱」更好。我于是拿卡尺量了一下它们的尺寸和螺丝孔的位置,画了一个外壳:由四片亚克力拼成,硬盘放下面,主板放上面。准备到淘宝上找商家切亚克力板,自己拿螺纹塞规钻出螺纹。
软件
软件上考虑使用 NFS 实现文件访问。借用办公室的显示器和键盘安装 Ubuntu 15.04 后将 NAS 拿回家,搭建 NFS 服务器。
考虑到网络读写不稳定,且 NAS 很大作用是保证数据即使在其它客户端被攻陷后也不丢失损坏,便想到用 union mount。Union mount 简而言之就是把一个只读目录(lower)和一个可读写目录(upper)映射到同一个目录(union)里。用户读取 union 中的文件时,实际就是从 upper 或 lower 中读取,而用户修改 union 中的文件时,所有改动都会被存进 upper 里。这样 union 看起来就是一个完全可读写的普通目录,然而 lower 目录实际并不会被更改,因此处于相对安全的境地。我只要定期 ssh 到 NAS 上看看具体修改了哪些内容,把确定需要保留改动从 upper 里写入 lower 里就好。
Union mount 现在最常见的两个实现是 AuFS 和 OverlayFS。前者由于被 Docker 采用,前两年忽然又火了一阵,然而实现非常复杂。后者的原理和实现都非常简洁,且在 3.18 时被合并进了 Linux 内核。因此我选择了 OverlayFS,并且专门为其写了一个工具。事与愿违的是,我发现无法在 OverlayFS 之上建立 NFS 服务器(i.e. OverlayFS 无法被 export 到 NFS)。于是我只好改用 AuFS 了,毕竟 AuFS 官方主页里就有 export to NFS 的指南。
具体设置较为简单:AuFS 部分,在 /etc/fstab 中加入
none /mnt/aufs aufs noauto,x-systemd.automount,br=/var/userdata/upper=rw:/var/userdata/lower=ro 0 3
NFS 部分,安装 nfs-kernel-server 后在 /etc/exports 中加入
/mnt/aufs *(rw,async,fsid=0,crossmnt,root_squash,no_subtree_check)
外网访问
就此,NFS 就已经可以在家里的内网放问了。然而,要在外网访问,需要考虑安全的问题。NFSv4 开始支持使用 Kerberos 进行身份验证。然而搭建 Kerberos 相对麻烦,我便想到曲线救国,直接使用 ssh 进行端口转发完成加密和认证。虽然这样会带来一些 overhead,不过由于我在外网访问 NAS 的频率低于在家里访问,所以问题尚不算大。
接下来就是在路由上设置端口转发允许外网访问到 NAS 的 22 端口。首先想到的是 MiniUPnPc,这样不用进入路由器设置里也可以完成端口映射,且不需要 NAS 有固定的内网 IP。然而联通配的路由器没有开启 UPnP。进路由器设置界面,发现里面既无法直接设置端口映射,也无法打开 UPnP。好在根据网上找到的方法破解了它后,就可以设置端口转发了。既然已经进了路由器管理界面,干脆直接给 NAS 设置了固定的 IP,打开固定的端口映射。再配合上 DDNS,就可以畅快地从外网也访问 NAS 了。