之前写过一篇帮朋友配置Intel NUC的文章，没想到今天我也有自己的NUC了。本篇记述我为这个NUC安装和配置系统的全过程。硬件选取本来一开始是没打算买主机的，因为我家这边夏天经常停电，不过不搭配UPS使用的话，频繁的突然断电早晚会把文件系统弄坏。但这次下定决心买NUC，主要还是因为发工资了，并且工作用的电脑一直没到，开虚拟机笔记本又过热，笔记本一过热电池就鼓包，活生生变成一个安全隐患。所以想来想去，不如买一个永除后患。说起mini主机，我第一个想到的就是Intel NUC。现在这个赛道，Intel NUC已经卖给华硕了，国产品牌也有不少后起之秀，比如零刻，价格便宜，性能更好。不过我买都买了，也就不多说什么了。我觉得Intel虽然把NUC卖给了华硕，但两家毕竟都是大厂，最基本的保障还是有的。而且我买NUC的目的主要是运行Linux，虽然零刻那边价格便宜，但是不知道Linux支持怎么样。如果到时候又得关安全启动，又得调着调那，最后还有一堆东西不兼容，那就麻烦了。好消息：Intel NUC用到现在，安全启动不用关，什么也不用调，装出来的系统直接就能用，也没发现有什么硬件不兼容的问题。特别好。这里要点名批评雷蛇：都什么年代了，还在BIOS里偷工减料。我买你们家的笔记本，在上面跑个Linux怎么了？且不说Linux支持有多差，甚至哟肚饿发行版本跑都跑不起来，电池还老鼓包。什么玩意儿啊，呸。至于型号，我买的是NUC13ANHi7，就是i7厚款。京东买的，自带16GB内存和500GB的NVMe固态。本来想买裸机然后回来自己插，这样的话钱不会差太多，但东西更好。可是裸机京东没货了，迫不得已只能买了个16GB内存的版本。好在对于Linux来说，500GB的固态算是够用，目前只是工作使用，未来打算将除了打游戏之外的需求都搬到NUC上，不过那是之后的事情了。内存只有16GB，对于Linux本身还是够用的，不过大家从我之前的文章也看出来了，我是写Java的，那IDEA开起来，Gradle daemon后台一跑，再来几个数据库的Docker，还有Chrome，开他十几个标签，直接给16GB的内存干满了——浏览器用掉了一半的内存，Java用掉了剩下的一半。数据库和Linux系统只能在swap中夹缝求生。所以下个月发了工资第一件事就是升级一下内存，直接干到64GB拉满。在存储方面我也考虑了一下，原本打算做个Btrfs的RAID 1，但是后来发现有点亏。虽然说我这个NUC能插三个盘：一个NVMe固态，尺寸是2280，一个M.2 B key的SATA固态（NGFF），但尺寸是2242，还有一个就是2.5英寸的SATA硬盘位。第一个槽位的NVMe暂且好办——买来的时候已经插上了，暂时不需要更换。虽然是金士顿的，但总不能刚到手就暴毙吧。第二个NGFF的就不好办了——我目前没找到哪个大牌子还在做这个协议的硬盘。淘宝上能找到的全都是杂牌子，2TB的硬盘能卖到726，这价格我真的有点不敢碰。最后SATA的盘位也好办，京东上随便找个三星镁光之类的冲就完了。所以归根结底，我觉得Intel NUC这个2242的B key槽位就很鸡肋，哪怕你整一个2242的NVMe呢？所以之后升级的话我可能就要考虑放弃这个槽位，只扩容SATA盘位了。如果硬要扩展的话也不是不行。所有数据都放在主盘上，然后可以重建的数据放在SATA盘上，比如BT下载之类的，总之就是丢了可以在下回来的。至于2242那个盘，那就只能存放一些本地有备份的，比如有些电影想拿出来再看一遍，那就放到这个盘上，万一崩盘了也不会造成任何麻烦。至于性能，我这个型号的NUC用的CPU是13代I7 1360P。从跑分来看这个CPU甚至要比我现在笔记本的i7 10875H还要高。不过实际使用来看，可能是内存不够吃，浏览器反而有卡顿的感觉。不过以现代CPU的性能来看，只要不是土豆，只要你不跑高性能运算，大部分情况下，包括开发，都是够用的。瓶颈和限制都在外部：比如电源功率上不去，散热跟不上，内存频率低/不够用。。。反正我觉得Intel NUC对我来说是够用的。那么决定好硬件之后，京东下单从上海调货，花费5299，后来想起来自己没有USB鼠标，只有键盘，又跑去戴尔那边买了个20块钱的光学鼠标。装系统一如既往地，我选择了openSUSE。这次也一样，在Leap和Tumbleweed之间纠结了一下，最后选择了风滚草。由于买的是带硬盘的配置，所以硬盘上带了个Windows 11，但是我不想折腾这个东西，但也不想放过这个机会，所以为了以备不时之需，我选用CloneZilla搞了个整盘克隆。如果之后有需要的话可以通过这个克隆文件把Windows 11还原回去。克隆完毕之后我又去华硕的官网搜索我这个NUC的型号，找到对应的BIOS更新。一开始我还担心这玩意儿别是非得进Windows才能更新吧，后来我看提供了一个CAP文件。开机按F7就可以直接从U盘里读这个文件进行BIOS更新。体验极佳，这里要点名表扬Intel。一切都准备妥当之后，烧写openSUSE的镜像，保持安全启动打开（当然还顺手跳了一下散热设置，然风扇转的更激进一些），开始安装。有些老生常谈的项目就不多说了，什么插根网线调成DHCP、配置主机名之类的，这些就略过了。桌面我选的GNOME，抽象，但是好用。至于分区加密，我这次选上了启用LVM。这次读了wiki才知道，如果你不启用LVM就开启加密，那开机一次要输入好几次密码才能解锁全部分区。如果启用了LVM，那么每次开机只需要输入一次密码，就能够解锁全部分区了。非常好。关于这个LVM还得多说几句。LVM全称叫做Linux逻辑卷管理。它是从硬件层面，也就是块设备的层面，将不同的硬盘统一进行抽象，这样当你配置全盘加密或者软件RAID的时候就不用触及Linux的fstab了，只需要在LVM里修改设备就好了。不过这里我还在想，LVM的功能是不是会和Btrfs重复？因为Btrfs也能提供类似软件RAID的功能，同时也不需要触及fstab，只要把硬盘加进存储池里就好了。后来我的老板给出了一个不同的见解：他说LVM从块设备级别提供了更灵活的硬盘管理方式。你可以使用LVM创建一个大的存储池，然后将上面的逻辑卷格式化成不同的分区，然后挂载；而Btrfs只能是Btrfs。假如你需要再加一个swap分区，如果有LVM的话，你只需要新增一块硬盘，然后在上面划分一个逻辑卷，mkswap就可以了。但Btrfs就做不到，因为它只是一个文件系统。所以如果后续不出意外的话，大家可能会看到一篇我写LVM扩容的文章。至于文件系统的配置，主文件系统当然是Btrfs，它的快照还是比较好用的。使用独立的交换分区，但大小只有2GB，一开始我寻思这16GB的内存还能不够吃？意思意思得了。现在看来，还真不够。如果后续不打算加内存的话，交换分区还是得大一点。虽然这个后期可以调，但是调就意味着你得先缩小一个分区，然后把这个分区的容量加给swap。有些文件系统不支持缩小，那就麻烦了。最后就是其他的杂项了，什么开启安全启动、CPU缓解策略（这个本来想禁用的，后来想想，为了工作的信息安全，还是开开吧）、防火墙、ssh什么的就不多说了。并不是什么很重要的事，全看个人需求，你开了也罢，关了也好，看着来。配置系统完事之后就是配置系统了。从哪里开始呢？从开机开始。开机问题因为目前我的NUC独占一个外接显示器，而我的笔记本在支架上。我目前使用的蓝牙键鼠可以配对多个设备，并且可以切换。所以我就没把键盘再拿出来，怪麻烦的。但这样有个问题：我的键盘是蓝牙的，但蓝牙到系统启动之后才有，可是要启动系统就得先输入密码解锁LUKS。可是要输入密码，就得现有蓝牙，要有蓝牙就得先进系统，要进系统就得解锁LUKS，要解锁LUKS就得……看到问题了吧？我这个蓝牙键盘不能解锁全盘加密。也就是说这个NUC只要关了，我再开就不行了，因为输不了密码。怎么办呢？我咨询了群友，群友说有一种很高级的蓝牙适配器，能够记住曾经配对过的键盘，并把它作为普通键盘呈现。我虽然没有听过这种蓝牙适配器，不过我推断这应该是以前的老黄历了。你想啊，这都2024年了，怎么会有这么好心的蓝牙适配器？我灵机一动，想了个土办法：把装系统用的薄膜键盘放在旁边备着。等需要开机输密码了就插上，不用的时候就拔了搁一边。反正是之前买东西送的，个儿不大，也不占地方。不过这个键盘不知道咋回事，输密码的时候自动开启Fn，导致键盘右边的字母全都变成小键盘的数字了。刚开始装完系统重启后输入密码，直接给我干到GRUB的启动界面了，我一想，坏了，别是我安装的时候输错密码了吧。就当我想输入reboot的时候，看到屏幕上写了个reb66t，我一看，啊？左思右想，原来是Fn开了，那输密码的时候按着Fn就行了。其实这个问题我还有一个解决方案，就是利用TPM。使用fde-tools可以把LUKS的加密密钥封进TPM里，开机就可以自动解密了。就算之后因为系统更新导致解密失败，也可以手动输入密码，然后重新密封密钥。可是正当我准备跟着Wiki走的时候却发现，pcr-oracle这个包更新了，更新之后改了命令行，导致fde-tools对它调用失败。我寻思这种破坏式更新不是应该提升大版本号吗？哎，没办法，人家的项目，人家爱干啥干啥，我也管不了。不过我看4月19日fde tools的维护者已经把新的patch提交到openSUSE的工厂了。估计下次风滚草打包的时候就可以用了吧。如果之后可以了，我会在另写一篇文章的。上网问题众所周知，国内的网络质量一直一言难尽。而要想痛快地使用Linux，一个好的网络连接必不可少。之前在虚拟机里的时候我是用tailscale，我专门组了一台德国的服务器来帮我做流量中转。可是放到NUC上就不行了。不使用出口代理就能和节点UDP直连；可是只要一使用出口代理，节点立马不可达，只能用中继。中继就慢了啊，能跑到500KB每秒都算烧高香了。我一想这不行，还得是专业的软件做专业的事。软件就不介绍了，我相信各位读者各有神通。这里我介绍介绍怎么给Linux配置代理。我使用的是GNOME桌面，所以很自然地，就可以通过GNOME的设置来配置。其次就是修改/etc/sysconfig/proxy，这里面提供了一个比较方便的系统级代理，大概是SUSE才有的？当然，如果你用的不是SUSE，那传统的环境变量http_proxy和https_proxy也是一种办法。如果以上两个还不行，我们还可以借助第三方软件，一个叫做proxychains的软件（软件包proxychains-ng），它可以利用库注入来劫持应用的网络请求，让它强行通过代理。比如proxychains4 rclone copy ...，这样就可以让rclone在自身不吃代理的情况下，让它发出的流量走代理。当然了，各个软件都有自己的代理配置方法，比如Gradle、Git这些。关于Git要说一句，如果你使用ssh的话，那轻易是没法走代理的，如果使用http或者https克隆和推送，那可以直接走http和https代理。最后如果还是不行的话，那就只能祭出最终的大杀器了：软路由以旁路路由的身份提供透明代理。使用的是NekoRay，这个软件在openSUSE上有个很奇怪的问题，就是默认情况下找不到openssl。由于新版本的openssl和1.1版本不兼容，所以需要手动安装openssl 1.1的包，不然更新订阅的时候就会提示TLS握手失败。GNOME托盘图标处理完网络就可以开始说正事了。不知道GNOME这帮人怎么想的，把托盘图标给弄没了。这一个桌面管理器做的越来越抽象。好看到是好看，可是太抽象了容易耽误事儿。没有托盘图标，不说别的，就JetBrains那个ToolBox，开机自启之后就是运行在托盘里。没有托盘图标，你叫我怎么升级和更新IDE？好在并不是我一个人嫌弃没有托盘图标。就连Ubuntu都嫌弃，所以他们搞了一个插件，叫AppIndicator and KStatusNotifierItem Support。它的主要功能之一就是把托盘图标给整回来了。中文输入法GNOME倒是自带几种中文输入法，但我觉得都不好用。所以我选了Rime。由于GNOME上继承的输入法框架是iBus，你当然可以用fcitx，但是还是集成的用起来好一些吧。所以要安装的包有两个：rime和ibus-rime，安装之后记得先重启一下，不然刚装完进去GNOME的输入法设置是找不到Rime的。在GNOME里启用Rime之后，还需要一些配置。比如把候选字从竖着的调成横着的，把繁体中文调成简体中文。要调整候选字方向，在~/.config/ibus/rime/ibus_rime.custom.yaml文件中这样写：patch: "style/horizontal": true要调整候选字的个数，在~/.config/ibus/rime/default.custom.yaml里这样写：patch: "menu/page_size": 7配置文件调整完成之后，可以去托盘那里找到输入法的选项，选择部署即可读取最新的配置文件。要调整简体中文，在输入法激活时按F4，选择“朙月拼音·简体字”即可。备份如一开始所说，由于存储接口的不同，组软件RAID 1并不会带来特别大的好处，反而可能会导致性能较差的硬盘拖慢整个RAID的性能。但是没有RAID来提供冗余性，那该怎么保证数据的安全性呢？我想到了我之前一直在用的一个备份软件：Duplicati。这个软件支持多种后端存储，可以通过增量备份的形式保存不同时间的备份。我之前一直使用这个软件来备份我的Windows笔记本。刚好，这个软件也支持Linux。下载RPM包安装后发现缺少依赖，经过一番搜索，只需要手动安装gtk-sharp就好了。但是问题又来了：有些要备份的数据需要root权限才能读取，这该怎么办呢？搜索了半天，最后发现其实Duplicati的源码中包含了一个Service，但不知何故这个service文件并没有进到安装包里，我们手动配置一个就好了（/etc/systemd/system/duplicati.service）：[Unit] Description=Duplicati web-server After=network.target [Service] Nice=19 IOSchedulingClass=idle EnvironmentFile=-/etc/sysconfig/duplicati ExecStart=/usr/bin/duplicati-server Restart=on-failure [Install] WantedBy=multi-user.target配置完成后重载systemd并启用服务：sudo systemctl daemon-reload sudo systemctl enable --now duplicati由于Duplicati运行在root权限，因此建议只将webui暴露给localhost。之后打开浏览器，访问http://127.1:8200即可打开网页端了。关于存储后端，我使用的是BackBlaze的B2，我单独创建了一个桶用来存备份的东西，也不需要额外配置其他的什么锁和加密之类的。加密的部分我们使用Duplicati在上传之前完成即可。关于备份的内容，我目前备份了如下文件夹：/etc：系统的所有自定义配置/home：用户数据/opt：没有使用包管理器安装的软件/root：根用户的数据/srv：和当前服务器有关的特定数据，虽然我这不是服务器，但也备份上了/usr/local/bin/：用户自行安装的软件/usr/local/sbin：用户自行安装的特权软件/var/log：系统日志，以备系统崩溃时使用/var/opt：给opt下的软件用的var文件夹/var/spool：未完成的打印队列等/var/crash：崩溃日志/var/container-data：我自己偏好的容器数据文件夹其中关于/var是最难搞的，因为它里面有些数据值得备份，有些不值得，你得自己慢慢择。备份频率是每两小时备份一次，备份的保留策略我选的智能，因为我也不知道我要什么，所以就全自动了。目前来看价格上应该不会特别贵。B2存储每月每TB价格6美元，赠送2倍还是3倍月均存储的下载流量，不过我暂时用不上。这种能够随时存取的级别，这个价格就不算贵了，隔壁AWS差不多要20多美元一个月。我这块盘一共就500G，就算占满了，里面的数据天天变，还能变出10TB不成？我觉得成本上来看问题不大。结束语至此就算是全部都配置完了。至于后续的使用就全看个人了。像是我就安装了JetBrains ToolBox来管理写代码用的IDE，后来也安装了Docker，而且新版本的Docker也支持给cli挂代理了。所以整体还是比较顺利地，跟着官方文档走就可以了，也没有坑，因此这里也就不再详细介绍了。今天写完文章看了一眼，新快照出来了，fde-tools也更新了，新版本兼容了新的pcr-oracle。本来想跟着流程走一走，但没想到它要LUKS2，这玩意儿还是实验性功能。我一想，这也实验那也实验，万一哪天盘炸了，那我也就实验了。所以最终决定还是不要乱搞了，开机插键盘输入个密码也挺好。之后我打算买个小的UPS，断电了就直接进挂起，只有内存需要供电，那应该也能撑好久呢。除非是什么大的系统更新，不然应该不会需要频繁的重启输入密码。回想文章开头，说买NUC主要还是为了减轻笔记本的压力，不让电池过热鼓包。但是当我今天发现笔记本的触摸板按不下去的时候，我就知道，这电池又他妈鼓包了。操。至此之前欠下的债就算是还完了。虽然没有正式约定过每月一更，但是我还是希望保持这个更新频率。现在有了工作那肯定是得优先保证工作。如果像之前那样托更了的话，我会试图在几个月之内补上的。如果没补上的话，那就是真的鸽了。--全文完--
【歪门邪道】使用Hetzner Storage Box代替Google Drive和DropBox
最近处于闲的长毛但又找不到合适的工作的阶段。最近要么就是出去骑车锻炼身体（然后回来吃稻香村的点心长肉），要么就是折腾折腾电脑，也没怎么写程序。前几天突然发现我常用的一个欧洲服务器提供商Hetzner推出了专注于存储的新产品，想来想去，发现其实还不错，就拿来准备替代我即将到期的Google云端硬盘。背景以前我一直是Google的忠实粉丝：使用Google搜索，看YouTube，在Google Play上消费，订阅Google One（Google云端硬盘），不过最近几年热度有所减弱。我几个月前看了一篇新闻，说一个外国人给自己女儿的私处病灶拍摄了一张照片发给家庭医生，被谷歌的AI判定为儿童色情，这位父亲的Google账号也因此被关停。对于像是Google、苹果和IBM这种有大公司病的企业，其实他们并不那么关心「你」作为一个用户对于他们有多大的价值，而他们也不在乎「你」为他们带来的利益，尤其是当「你」是个人用户并且你的案例是个例的时候。反正根据新闻报道，这大哥申诉了几个月也没能拿回他的Google账号，这意味着他的照片、联系人等数据从此一去不复返，同时由于他手机使用了Google Fi，他出门连流量都没得用。如果他还用Google Voice，那我建议他可以考虑重开了。类似的争议在苹果方面也有。跨区封号（中国居民使用美区账号，一旦被封几乎没有恢复的可能性）就不用说了；之前苹果说要推出一个AI来扫描用户的照片，从而防止儿童色情犯罪。这个做法一度成为风口浪尖，最后不得已被停止。看起来无论是什么公司，他们似乎都在以正义的名义不断地索求更多对用户数据的访问权限。有些是索求，有些则是强制拿来。这下中国经验推广到全世界了。在这个大家越来越不把用户当人的时代，我们个人用户有没有办法站着吃饭呢？有，但是得加钱。例如提供企业级云服务的AWS，他们家就保证了永远不会偷看用户数据，即便是具有版权争议的数据，只要没有收到版权投诉（大概率是使用AWS进行了文件分享，而非因为存储），他们就不会管你在上面存了什么。但是至于价格嘛，也是非常的企业级：最便宜的存储类具有12小时的访问延迟，每月每TB要1美元；访问这些数据需要发起恢复请求，这个请求是按照对象数和对象大小分别收费的；数据恢复后，除了要为原本的存储类继续付费，你恢复出来的用于访问的数据要存在其他存储类，这个存储类的费用同样也要支付；最后如果你要在AWS之外的地方访问这些数据，你还要支付90美元每TB的下载流量费。不过归根结底，这世界上没有100%的安全。云服务商也会无故封号（这里点名批评IBM混合云）；NAS的硬盘也可能在重建时坏掉；也有可能你的存储服务提供商的机房着火了，把你的数据和备份全部烧掉了；还有可能天上掉下来陨石，正好砸中了你家的NAS和这个地球上所有存有你数据的服务器、移动硬盘、U盘、手机等设备（陨石：精确制导，不用谢）。总之，100%的安全是不可能的，但是通过遵循良好的实践原则，我们可以把数据损失的风险与代价降到最低。例如普通用户使用移动硬盘存储他们珍贵的照片，若这块硬盘受到物理损伤，那么这里面的数据也就从此一去不复返了（我们称这种用户为「亡命之徒」）。但如果这位用户遵循321原则：这些照片一共有三个副本（1份原件2份拷贝）；分开放在至少两种不同的存储介质上，例如原件在移动硬盘，一份拷贝在一个U盘上，另一份在AWS的磁带上；并且把U盘寄存在父母家或公司。这样即便你的移动硬盘坏了，你还可以通过放在其他地方的U盘，或者AWS云服务恢复数据。如果AWS发生了生产事故，除了索要赔偿外，你还可以通过移动硬盘和U盘这两种介质补充备份。只要行动及时，321备份原则能够在很大程度上保证你的数据可用性。 安全提示 当然了，一份数据的拷贝越多，其泄露的风险就越大，例如公司/父母家被盗了，AWS被入侵等。因此在考虑数据备份的同时不要忘记加密。但如果后续失去了解密的手段（例如丢失密钥、忘记密码），那么很遗憾，你的数据就在那里，但你就是访问不了它。因此时常检查你的备份是一个好习惯。存储安全并不是「设置然后遗忘」这么简单。它是一个需要你持续付出精力去维护的成果。 基于此，我目前的数据全部都存放在Google云端硬盘上，好像也没什么其他的备份。看起来很危险的样子。这几年没出什么大事情我真的烧高香了。我的需求前面说了这么多，总结成一句话就是：我要花钱了。因为一些原因，家里有一个类似NAS的存储设备，但是它并不能24小时开机，实际上家里的电也不是很稳定，大约每个月都会遇到意外停电。总的来说，这个设备就是一个大的半离线存储池，上面存储了一些长期用不到的数据，例如说远古时代的照片，我看过的动漫、电影等不需要随时访问的数据。这些数据加起来大约有4TB。目前这些数据仅受UnRaid阵列保护，一旦出现意外，没有备份。经常访问的数据位于我的电脑和一块2TB的移动硬盘上。由于电脑上的存储比较紧缺，虽然有2TB，但是除了系统、各种虚拟机、越来越大的游戏等，实际剩下能存储文件的地方不多，因此需要临时周转一些大文件的时候我会用到移动硬盘。这些数据主要有下载了但还没看的番、骑车录制的影像（多半都会删掉，但需要我过一变看看有没有值得留下的 摔车 精彩瞬间）。这部分数据大约在3TB左右，没有冗余阵列保护，没有备份，属于是亡命之徒了。其次我还有一个24小时运行的工控机，它主要运行一些服务，例如旁路网关、BT下载等。产生的数据基本上在下载完成后我都会拷贝到我的笔记本上，因此无需备份。最后就是我的手机。这上面的数据主要就是照片、截图和表情包。除了照片之外剩下的数据无关痛痒，照片主要同步到Google Photos上。鉴于我取消了Google One的订阅，因此之后的可用空间就剩下15GB了。我需要定期从Google Photos下载同步到的数据，并存储到其他地方。但总的来说，这部分数据量不大，因为我不怎么拍照片。除了存储方面的需求，我还希望可以做好备份。由于现实条件比较紧张，因此我偏向于无需增加实体的备份方法，也就是说额外购买硬盘做冗余备份不在考虑之列；对应地，我需要按月支付云服务商来租用存储服务。这并不是最佳实践，但也满足了321原则：原件在本地，两份副本在两个云服务商处，这三个副本都位于不同的地区。设计方案这里我们来列举一下需要的软件和服务，以及大概的思路。软件方面Duplicati：支持Windows、Linux和macOS的备份软件。具有去重功能（我1GB多的桌面备份了几个版本之后只有不到600MB），支持WebDAV、FTP、SSH、S3等各种存储后端。开源免费。MountainDuck：在Windows和macOS上将WebDAV、SFTP、FTP、S3等存储后端挂载为硬盘，在Windows资源管理器或访达中访问。付费软件，大版本买断制，截至目前大版本号是4，许可证价格为39美元。CyberDuck：如果你不想付费，来自MountainDuck的开发者也开发了这款文件浏览工具，支持的协议与MountainDuck一样，只是不能在Windows资源管理器或访达中访问，但可以实现文件的浏览、下载、上传等操作。免费版本可以一直使用，但定期会有弹窗提示你考虑捐助开发者。捐助10美元及以上可以获得一个许可证，用来解除前述恼人的提示，同样地，也是买断制。RCLONE：一个命令行工具，支持在不同的存储后端之间复制、粘贴、移动、同步数据。支持的协议最为广泛，使用起来也不算复杂（大概吧）。服务方面Hetzner Storage Box：提供以FTP、FTPS、SFTP、WebDAV等多种方式访问的存储产品。AWS S3：AWS S3对象存储服务。其中Hetzner Storage Box不提供图形界面的文件浏览功能（类似Google云端硬盘的网页版），并且分享数据也比较困难（无法通过链接的形式分享文件）。但由于我不需要使用网页端，也没有朋友可以分享数据，因此Storage Box很适合我。如果你有这方面的需求，Hetzner提供了基于NextCloud的存储服务，叫Storage Share，本质上和你自己运行NextCloud是一样的，也支持WebDAV，但额外多了分享和网页端，同时NextCloud也有手机App，在易用性上更好。当然，价格也更贵一些（大约额外加价50%吧，5TB从10欧元涨到15欧元不到；10TB从21欧元涨到28不到；1TB的好像就贵了1欧元左右），但总体来说也还是比Google云端硬盘和DropBox便宜。设计思路UnRaid服务器上的数据暂且不备份，因为数据量大，比较贵，等我工作之后再说吧。手机上的照片同步到Google Photos之后，可以在网页端下载，也可以使用导出的方式获取所有照片。导出之后就可以当作普通数据存储到其他地方了。最关键的就是电脑上的数据了。由于本文想实现替代Google云端硬盘，因此主要有两方面需求：一个是备份重要的文件夹，如果可能的话应该留取多个版本；然后就是网盘，将一部分数据存放在远端，并通过挂载的方式随时存取。网盘部分的数据违反了321原则，因为它不存在本地原件，因此只有两份副本。但好处是它扩展了本地可用的存储，并且手机端通过支持WebDAV协议的文件管理器即可访问远端数据。关于备份，我使用了Duplicati，它提供了网页端的管理界面（默认只有本机能够访问），在设置上也简单明了，能够提供一个位置的不同版本的数据，以便在我后悔的时候及时恢复。Duplicati在备份过程中可以选择在本地加密，然后上传到远端。关于网盘，我是用MountainDuck将远端挂载为本地硬盘。它用起来其实和Google的客户端差不多，都是自动同步新增文件，按需下载并缓存远端文件。MountainDuck支持在远端建立加密的存储库，但需要使用同样的软件才可以解密并读取。 关于软件的易用性 MountainDuck的使用体验不如Google和DropBox的客户端细致，有时候会出现同一个文件需要上传多次、莫名其妙出现同步冲突的情况，也有时软件以为自己同步了，但远端文件长度是0，此时删掉本地缓存的话，文件就会丢失。虽然这是小概率事件，我也不清楚原因，但这就要求用户在写入时需要额外的检查（推荐使用7z等可校验格式，或者使用FastCopy等支持校验的软件），如果不想在写入时担惊受怕，可以考虑使用SFTP协议上传文件，然后使用MountainDuck将WebDAV挂载为只读。 以上的所有数据都通过WebDAV协议存储于Hetzner Storage Box上。而Hetzner Storage Box提供了快照功能，我设置了每天一次快照。但为了避免Hetzner无法访问，我还将Hetzner上面的数据定期同步到S3上。使用Rclone在一台服务器上配置好基于SFTP访问的Hetzner Storage Box和AWS S3的远端配置（为节省成本可以使用GLACIER_IR或其他归档存储类）。定期执行如下脚本：rclone -c -P sync hetzner-u316777: aws-us-east-1:skyblond-hetzner-u316777 --checkers 2 --retries 10以上命令是通过sync命令将hetzner远端的数据同步到aws上，使用MD5作为checksum检查文件是否更改，将会删除hetzner中不存在的文件，并写入新增的文件。如果想要增量备份，则可以考虑使用copy命令并通过生命周期配置定期删除老旧文件，以实现回收站功能。这里比较重要的一点是使用MD5作为checksum确认文件是否重复（-c标志）。因为S3远端再上传时，取决于文件大小，rclone会附带文件的MD5并存储于元数据中。因此只需要计算源文件的MD5即可确认是否需要更新。如果网盘中的文件不经常修改，那么同步完成之后就不会消耗太多流量。此外由于rclone不具有失败提醒的功能，所以我建议定期手动执行脚本，以便保证同步备份是有效的。关于后面的--checkers和--retries，前者用于限制计算MD5的线程数量，因为StorageBox会限制并发数，默认配置是8个，我MountainDuck占用一个，Duplicati占用一个，rclone主要进程占用一个，然后再来8个计算MD5的现成，肯定会导致失败。出现失败之后，通过后一个配置可以让rclone多尝试。 关于手把手教程 由于我比较懒，因此我不会在本文中提供手把手教学。如果我能一边读这些软件和服务的文档一边配置出我想要的效果，那么我相信屏幕前的你也一定可以。 关于在实践中发现的一点bug 我在使用中遇到一个关于Shell的文件名问题。Hetzner StorageBox使用了一个类似蜜罐环境的Shell用以限制用户可以进行的操作。这在Shared host上是可以理解并完全必要的，但该Shell环境在处理文件名时似乎有一些问题。具体的表现是我在将文件同步到AWS S3时，计算MD5的命令出现错误，根据返回代码判断是内存过大引发了OOM Kill。但是一般来说不应当如此，于是我仔细检查了命令，结果发现他们的Shell在处理形如(something) [something.pdf这种括号不匹配的文件名时就会出问题。我已经向Hetzner反馈了这个问题，但是将近半个月了还没有任何进展，我推测这个shell应该不是他们自己编写的，而是采用了一些开源产品，需要等待上游修复才行。当然，这些文件是我备份的Calibre文件夹，也好解决：要么打成压缩包，要么放回硬盘上用Duplicati备份。 那么，代价是什么呢？我换到这种方案已经有大约一个月了。从经济上来说，Hetzner提供的Storage Box就算是加上S3的费用，也要比Google云端硬盘和DropBox提供的方案要便宜。具体来说是这样的：Google云端硬盘的2TB档提供49.995美元每年每TB的价格，上传下载不限；隔壁DropBox的2TB档则是59.94美元每年每TB；而Hetzner的1TB档提供38.16美元每年每TB的价格（需要考虑欧元汇率，因为Hetzner使用欧元结算）。加上S3的存储，我使用了最便宜的Deep Archive存储层，每年每TB价格是12美元。S3的同步费用主要是PUT和GET请求，分别用于数据上传和MD5查询。对于查询请求，每百万个对象0.4美元，上传则是每万个对象0.5美元。若提前删除，还需要支付额外的存储费用（即最短存储期限），我建议每隔180天或90天备份一次，这样可以避免支付太多的存储费用。如果发生意外，我需要从S3上恢复全部数据，则一次的费用是：生命周期转换费用0.5美元每万个对象，3.84美元每TB每5天（假设恢复的文件5天后自动删除），90美元每TB的数据传输费用。因此恢复一次的费用大约在100美元左右。虽然一次数据恢复的成本很高，但是相比之前只是用Google云端硬盘或DropBox，如果被封号且申诉失败，届时连花钱买自己的数据都不可能。此外，加上S3的存储费用，Hetzner的1TB档年度存储成本已经和Google云端硬盘持平了，但如果考虑最大的20TB档，光是存储就可以降到25美元每年每TB，直接干爆Google。但是话虽这么说，用户体验并不只是存储单价，还有网络。谷歌在世界各地都有数据中心（中国和朝鲜除外），而Hetzner的Storage Box只能从德国机房访问。虽然相比Google可以裸连，但速度实在是不敢恭维：不到100KB/s，是的，所以无论如何都还是得挂代理。而由于服务器在德国，因此香港、日本、美国等常用地区的代理并不能发挥出最佳效果，下载速度只有10MB/s左右；使用德国地区的代理则能够达到20MB/s的下载速度。至于上传？我家4MB/s的小水管无论是谷歌还是Hetzner都能被跑满，无所谓了。后记不使用现成的商品，就意味着要自己折腾。自己折腾就意味着更多的麻烦事，更少的文档，以及更多的时间成本。本文的意图在于使用自己的方案平替之前依赖的谷歌服务。我想今后工作之后，经济状况不一样了，可能还会有新的解决方案。对于我来说，数据掌握在自己手里当然是最好的，所以我的终极方案可能会是使用TrueNAS来做存储池，然后使用其他软件来提供服务。当然，云服务的一个好处就在于实时在线，如果完全靠自己来实现备份321原则的话，恐怕成本会很高。但是借助云服务就不一样：自己家一份数据，单位或亲戚家里一份备份，最后在云服务上备份一份。 当然，以上都是后话，截至目前，在「如无需要勿增实体」的基本原则下，这篇文章所记载的方法应该是（对我来说）最稳妥的数据存储方案了。此外这篇文章主要使用WebDAV和SFTP两种协议访问存储后端。如果没有使用rclone的需求，那么其他任何WebDAV协议都可以配合MountainDuck和Duplicati工作。使用SFTP就是因为他可以在上传前计算MD5，这样就可以直接和S3远端确认数据是否有变更，而不需要每次重新传输大量数据——也就是说，你不在乎流量和带宽的话，SFTP并不是rclone的必选项。推广最后的最后，Hetzner Cloud（主营业务是VPS）有一个推广服务。如果您愿意使用我的推广，请通过如下链接注册Hetzner Cloud，注册后您会收到20欧元的点数，可用于支付Hetzner家的VPS；当您额外消费10欧元后，我也会收到10欧元的点数作为回馈：https://hetzner.cloud/?ref=XeiXFN7QIPaG遗憾的是Hetzner Robot（主营业务是独立服务器、Storage Box）并没有类似的推广业务，可能是因为这类业务真的没有可以送点数的空间。-全文完-