menu

NAS

Done: Yes 优先级: 4 位置: 其他 标签: 家电 预算: 265

需求

  • 家庭多媒体中心,需要支持多个设备(TV 手机 PC)
  • 下载站,迅雷、百度云、BtSync
  • 照片存储,能挂载成 PC/Mac 磁盘,Lightroom 能直接修改

emby + kodi

二手价格

CPU:赛扬 4900 奔腾 G4560 i3 400

主板:H110M 250

固态:M.2 100G 150

内存:4G ddr4 200

电源:250-300w 200

nn蜗牛星际组 NAS

蜗牛星际:我集齐了ABCD款,折腾矿渣一个月的全记录!__什么值得买

矿难来袭!速看蜗牛星际矿NAS用料。 - 徐自远的乱七八糟小站

蜗牛星际 A

usb3.0

usb3.0 接触不良,上面的口没成功过,下面的口用力差确实能成功识别 usb3.0

获取 usb 信息,需安装 sudo pacman -S usbutils, 提供 lsusb, usb-devices, lsusb.py. 其中 lsusb.py 特别好用

功耗

639.3 小时,用电量 10.61 kwh。硬盘唤醒功率:24w,硬盘休眠功率 14w。

验证网卡千兆

iperf 传输速率只有 100mbit

lshw 可查看硬件信息

网卡信息 mii-tool ethtool

Download Intel® Network Adapter Driver for 82575/6, 82580, I350, and I210/211-Based Gigabit Network Connections for Linux*

ArchLinux

对 Nas 系统了解不多,直观印象就是 Linux 上+ WebUI。我还是喜欢通过 ssh 进行系统管理,所以我选择用 ArchLinux 组建一个 NAS 系统。

配合一台云主机用 Nginx 做反向代理,加上内网穿透技术,相对安全的把服务暴露到互联网。

aurutils

aurutils 的思路是用一个自定义的本地 pacman 源,将 aur 上的包编译后存入本地的源,再通过 pacman -Syu 安装,非常聪明

aur sync $package_name

sudo pacman -Syu $package_name

需要建一个本地 pacman 的 repository,详见 man aur

aur 被墙可以用清华大学的镜像,比如:

env AUR_LOCATION='[https://aur.tuna.tsinghua.edu.cn](https://aur.tuna.tsinghua.edu.cn/)' aur sync -c jellyfin

see https://github.com/AladW/aurutils/blob/master/lib/aur-query#L5

systemd

alias s='sudo systemctl'

sudo systemctl set-default multi-user.target

固态才16G,日志也不要太大,512足够了

sudo journalctl --vacuum-size=512M

开机启动的服务:

● ├─aria2.service
● ├─cps.service
● ├─dnsmasq.service
● ├─frpc.service
● ├─jellyfin.service
● ├─mega.service
● ├─nfs-server.service
● ├─nginx.service
● ├─nmb.service
● ├─privoxy.service
● ├─rslsync.service
● ├─shadowsocks-libev@****.service
● ├─smb.service
● ├─sshd.service
● ├─transmission.service
● ├─****

文件共享协议

Nas 最重要的功能,就是把存储空间暴露给其他网络上的设备。这方面比较简单,就是 nfs 和 smb。

NFS

鸟哥的 Linux 私房菜 – NFS 服务器

nfs 的配置起来比较简单,不幸权限管理要细化起来还是比较麻烦的。

把目录开放给主机,实际主机上的应用程序都有了读取 nfs 目录的能力。

相对安全要求不高的情景,我还是直接用 all_squash root_squash,然后再用 anonuid anongid 设置特定的用户。

安全性需要搭配 Kerberos 使用,太繁琐。

Mac 经常会断掉

macOS X Mount NFS Share / Set an NFS Client - nixCraft

使用 nfs.map :

NFS uid/gid mapping

Kodi

kodi 需要 insecure,见 3 NFS sharing from Linux

Samba

启用 smbnmb,不要去启用 samba

权限

各类下载软件的默认都用各种的用户和组,修改各种 systemd 脚本不好维护。

  1. setfacl 精细化控制各个目录各个用户的权限,ex:setfacl -d -m u:user:rwx target
  2. 用组管理,比如 download media 作为各个目录的组权限,再把需要的用户加入组中。

方案 2 足够简单且基本覆盖当前需求

媒体服务器

只做文件共享的 NAS 和 SAN 又有什么区别呢😁?

jellyfin

Kodi 更像一个带资源管理器的播放器,不能脱离GUI,没有一般意义的 server 版本。

linuxserver/docker-kodi-headless

Emby 3.6 之后也不开源了,代替品

jellyfin/jellyfin

安装了 jellyfin 后还安装了 FFmpeg

http://192.168.1.6:8096

将用户加入组 jellyfin 方便修改 jellfin 生成的文件

rslsync 和 jellyfin 在 1900 端口有冲突

OpenMediaVault

Download | openmediavault

aria2

sudo pacman -Syu aria2

配置文件 /etc/conf.d/aria2c.conf ,修改下载目录和启用 rpc。见 aria2c.conf

systemctl start aria2cd.service

btsync

http://192.168.1.6:8888/gui/

需要搭配 ss 使用,手动建需要fq的地址加入 privoxy 的gfwlist 配置里面,在 app 设置代理为 privoxy

config.getsync.com
config.resilio.com
173.244.217.42
209.95.56.60
107.182.230.198
173.244.209.150
54.235.182.157

Transmission

鉴于 bt 下载都是通过预分配空间再来写入数据来减少碎片,直接在存放媒体的 8t 叠瓦盘上下载就不太合适了,所以我用闲置的 ssd 来做下载盘,下载完成后再移入目标磁盘。通过开启 incomplete_dir 来实现这个功能。这个功能需要修改 /var/lib/transmission/.config/transmission-daemon/settings.json 。其实用了 ssd 预分配也可以关掉,毕竟 ssd 可以不管文件碎片化了,预分配浪费一次写入也对寿命无益,不过,0占位的文件可能已经被文件系统优化了,所以未经验证的认为影响应该不大。不过我还是关掉了。

需要注意, 停止服务后,才能修改 settings.json 。不然 stop 的时候会重置 settings.json

另外还要注意权限问题,transmission 是以 transmission:transmission 这个用户来操作的。

Incomplete-dir

设置下载中的目录到 ssd,避免折腾坏叠瓦盘。

transmission 可以通过设置 incomplete-dir 来实现,/etc/transmission-daemon/settings.json

"incomplete-dir": "/mnt/ssd/srv/bt",
"incomplete-dir-enabled": true,

The incomplete-dir appears to be used only when the download-dir matches the entered folder when adding the torrent. You could argue that the free selection of download folder (which could be on another filesystem entirely) conflicts with using a single incomplete-dir. So I would suggest explicitly not using the incomplete-dir setting at all as it is not used when selecting a download folder that differs from download-dir anyway.

transmission-daemon: UDP Failed to set receive / send buffer

debian - transmission-daemon: UDP Failed to set receive / send buffer - Unix & Linux Stack Exchange

transmission-tracker-add

AndrewMarchukov/tracker-add: Fully automated script for adding more trackers to Transmission.

Book

  • calibre 创建维护书库
  • calibre-web,作为 书库(calibredb) 的前端,calibre 提供的web端太简略
  • calibre-helper,监控特定目录下的文件变更,自动添加进书库

这些命令都需要编辑同一个目录,需要统一权限

calibre

书用 calibre 来管理,calibre 会将书复制到 CALIBRE_LIBRARY_PATH,一本书在 nas 起码上存在两份。

  • 安装 calibre 主要是用它的命令行工具,来管理 CALIBRE_LIBRARY_PATH。
  • 找不到 headless 的版本,安装 calibre 引入一堆用不上的 qt 依赖,有点难受。
  • 还有很强大的阅读功能也用不上。
  • 在 mac/pc 上也可以通过 nfs 挂载这个目录,直接用本地的 calibre ui 来管理和阅读。
  • 没有译者字段,应该可以自定义metadata
  • 另外解析 pdf 元数据的时候有个小 bug,还给提了 PR

calibre-web

建议用 aurutils 安装

aur sync calibre-web

calibre-helper

脚本见 calibrew_helper,监听目录变化并自动导入 calibre.

sudo pacman -Syu inotify-tools poppler
  • inotify-tools 用于实现监听目录
  • poppler calibre 需要依赖 pdfinfo

目前只实现对于新增/修改文件的添加,删除会被忽略。主要是用于监听 rslsync 的目录。

TODO

  • 频繁变更是否需要一个队列来避免通知丢失
  • 出现重复如何处理,calibre 通过 title 和 authors 判断是否重复。有些书的标题都是 untitled 或者是其他一致的无意义字符,直接覆盖也是不合理的
  • calibredb add ... -e override 可实现自动覆盖
  • 权限与 calibre-web 一致,写入的文件,calibre-web 才能更改
# /etc/systemd/system/calibre-helper.service
[Unit]
After=rslsync.service
[Service]
User=calibre-web
Group=calibre-web
ExecStart=/opt/bin/calibre_helper.sh
[Install]
WantedBy=default.target

内网穿透

选用 frp,配置见

端口:

  • Nas webUI 80/443
  • rslsync webui 8888
  • transmission 9091
  • calibre-web 8083
  • jellyfin 8096

Requirement

  • 云主机(必须)
  • 域名(可选)

frp 做穿透

nginx 做反向代理,可以实现全部走80端口,根据不同子域名派发到各种的服务

为了实现相同的域名可以在外网和内网同时访问到服务,有两个方案:

方案1

  • 外网:云主机(nginx → frps) → 内网主机(frpc →具体服务)
  • 内网:内网主机(nginx → 具体服务)

外网访问由frp来做反向代理,而内网又需要 nginx 来做反向服务,需要部署两套规则。

NAS%20306933e74a424c04892d6b5ddc49eabe/Untitled%201.png

方案2

外网:云主机(nginx → frps)→内网主机(frpc → nginx → 具体服务)

内网:内网主机(nginx → 具体服务)

看起来多了一层,但反向代理的职责主要都交给了 nginx,而 frp 只需要代理一个 tcp 端口而已。规则简单了许多。

ssl 一定要在末端启用。

xray xlts

对于方案二来说,xray 或torjan 的回落也是可以起到简单转发的作用,nginx 这里是可以不用的。不过 nginx 还是值得的,比较多了一些控制和灵活性。

回落到 nginx 只能回来到 80 端口,因为流量已经被解密了。所以需要注意让外部 ip 访问 80 端口转发到 https:

server {
       listen 80;
       server_name ....
       # 阻止外部ip直接走 http
       if ( $remote_addr != 127.0.0.1 ) {
        rewrite ^ https://$host$request_uri?;
       }
       location / {
       ...}
}

安全

暴露到公网,最基本的安全还是要的:

启用 http basic auth

  1. sudo htpasswd -c /etc/nginx/.htpasswd user pass
  2. 找个[在线服务][https://www.web2generators.com/apache-tools/htpasswd-generator]直接生成

证书

使用通配符证书还是最方便的

sudo certbot certonly --manual \
--preferred-challenges=dns \
--email dourokinga@gmail.com \
--server [https://acme-v02.api.letsencrypt.org/directory](https://acme-v02.api.letsencrypt.org/directory) \
--agree-tos \
-d "*.dourok.info"

检查 dns txt 记录生效:

nslookup -type=txt

硬盘管理

更新:内置 16G 固态已经损害。用 256 的 SSD 安装系统。再把 /var 独立分区,幸好还有一个 sata 接口可以作为启动盘。

见 :fstab

机械硬盘设置 30 分钟定时休眠:

sudo hdparm -S 241 /dev/sdx

SSD 250G

btrfs,两个主要作用

  • 挂载 /var 目录
  • 临时下载目录

主要分为两个 subvolume

  • var 挂载 /var : mount -t btrfs -o subvol=val,defaults /dev/sdc1 /var
  • srv 临时下载目录,需要设置 quota,不要让这这个目录把硬盘写满
sudo btrfs qgroup limit '200g' srv

sudo btrfs qgroup show -pcre /mnt/ssd

2T

现状:

49G ./temp 737G ./.18p 1.6G ./aria2 16K ./lost+found 11M ./rslsync 20G ./works 453G ./.transmission 226G ./archives 66G ./games 1.6T .

长期用途下载盘+缓存:

  • transmission
  • rslsync
  • aria2
  • webDav*
  • jellfin 缓存(/mnt/seagate_3t/jellyfin)
  • pacman 缓存
  • 18p 资源()

下载资源,完成后复制到8T归档,2T 磁盘需要定期清理。

3T

现状:

40G ./download 741G ./pictures 16K ./lost+found 30G ./resources 36G ./电子书资源共享(中文) 9.5G ./jellyfin 1.7T ./media 61G ./MainCalibre 12K ./.Trashes 30G ./Games 2.6T .

长期用途:备份盘+低强度工作

  • Lightroom 图片库(是否支持 nfs)
  • 图书
  • 游戏
  • 音乐归档
  • 代码备份(rsync 定期备份 或 rslsync )
  • 历史工作目录备份
  • 个人资料(+ google drive)

8T

希捷 SMR 磁盘。主要存放影视资源供本地播放器(Jellfin)使用

33G ./music 420M ./comic 1.2G ./game 812G ./staging 22G ./documentary 247G ./movies 546G ./episodes

权限

主用户属于 users(985)

transmission 有自己的用户和组

jellyfin 有自己的用户和组

监控

sysstat

TODO

弃用

布线

mega

Description=Mega Cmd Service
After=local-fs.target network.target
[Service]
Type=simple
User=root
ExecStart=/usr/bin/mega-cmd-server
WorkingDirectory=/mnt/seagate_2t/
Restart=on-failure
[Install]
WantedBy=multi-user.target

ss

与wiki不一致,见 https://github.com/shadowsocks/shadowsocks-libev/issues/1949#issuecomment-369467859

sudo systemctl enable shadowsocks-libev@us8.service

proxychain-ng 可实现对当个进程的代理

sudo pacman -Syu privoxy proxychains-ng

最终方案 prixovy 将 sock5 代理转换为 http 代理。可通过配置实现 gfwlist https://www.zfl9.com/ss-local.html#gfwlist 。再通过 proxychain-ng 全局走 prixovy 代理

检验一下是否有走 ss

proxychains curl [https://api.ipify.org](https://api.ipify.org/)\?format\=json

tc-play

veracrypt/tc-play

这个版本已经编译不过了,用我 fork 的版本

Update tcplay.c · douo/tc-play@ac63ea0

写入速度还是可以的

Untitled.pngb

keyboard_arrow_up