NAS搭建

NAS搭建

其实很早的时候就想搞一台NAS玩了,毕竟有很多想收藏的高清视频,还有一些自己私人资料,不方便存在云盘里面的。之前HP Gen8机器还是不错,扩展性也非常不错,只是感觉有点小贵,然后就是风扇噪音问题比较严重,查了下说是HP虚拟的一个Raid卡造成的问题,在*nix下面无法获取到硬盘的温度,导致风扇会以最大转速工作。当然查Gen8的资料是最近正式想整一台NAS后才开始。之前是用蛮早的一台上网本,好像是三星N2600之类的型号吧,装了CentOS,专门下载PT和存照片。后来空间不够用,就想起还是组一台NAS吧,正好家里有6台笔记本(Surface Pro 4, Thinkpad T400, Thinkpad E330, Thinkpad E420 x 2, Samung N2600),2.5寸硬盘有6个,本着不能浪费的原则,就开始整NAS了。

技术选型

19年春节前就一直想着这个事情,老天也是“给力”,春节期间还真是没有出过一个太阳,就宅在家里想着怎么组这个NAS。

FreeBSD/ZFS/Jail

FreeBSD很稳定,port也非常好用。之前工作的主力系统是Gentoo,所以对FreeBSD很有好感。但是ZFS一直没有正式接触过,于是把FreeBSD Handbook好好地看了下,确实ZFS很强大,可以忘掉Raid,忘掉分区,不同目录设置不能参数适应不同用途(加密,压缩等等),快照功能。还有Jail可用,用途有点类似Linux下的Docker,可以把程序关到Jail里运行,不影响主系统。

但是真正用起来感觉还有好多东西需要深入研究,但又没那么多时间。

  1. ZFS很强大,但同时也是内存大户,推荐是1T配1G内存,然后建议是配ECC内存(这个作者原意思是关心数据的话,不管是什么文件系统,都建议ECC)。现在内存不是太贵,但是要自己组NAS的话,ECC内存好像不好搞定。
  2. ZFS优化比较麻烦。在虚拟机里用ZFS和UFS测试NextCloud/MySQL时,发现ZFS明显慢很多。放狗搜了下,关于ZFS优化MySQL这方面,有蛮多参数需要配置的。
  3. ZFS快照功能暂时好像用不上,没这需要。但蛮喜欢加密和压缩功能的。
  4. Jail配置NAT网络比较麻烦,不如Docker来得方便。而且PF与iptables又不一样,还要查不少资料,烦。
  5. 担心FreeBSD的硬件兼容性,不能够让NAS达到最节能的状态。

所以最后还是放弃了FreeBSD。

OpenMediaVault(OMV)

之前本来确实是想用FreeBSD来组NAS的,后来@kurtyan推荐使用OMV。然后就是虚拟机里搞了一把,有几个槽点吧。

  1. OMV镜像安装不支持UEFI,这个锅应该让Debian 8背吧。。。然后就是OMV镜像安装时,好像要选整个硬盘,这个有点恶心,后来干脆自己先装好Debian 9然后再装OMV。
  2. 感觉Web管理页面上有太多我不想要,也用不着的功能,看着比较浪费。

感觉OMV比较适合新手,界面什么的还是比较友好的。后来一想这个web管理界面,FreeBSD的webadmin也可以管理啊,一查Linux也可以用webadmin。但最后还是没有用webadmin,自己从基层组算了。

Debian/LVM/Docker

OMV是基于Debian的,还不如自己搭建想要的功能呢。刚开始有考虑CentOS,但本人不喜欢它的图形安装界面,好像比Debian耗资源一些,就pass掉了。

既然是自己用的NAS就需要考虑下数据的安全问题,以防硬盘突然挂掉,开始考虑的是软raid,重要数据raid 1,视频数据raid 0,后来考虑再三还是放弃了软raid的方案,买的是4盘位机箱,比较少,还是用USB3.0外挂硬盘,定时备份重要数据,特别重要的文件就GnuPG加密后传网盘。还有一个就是使用LVM管理分区,这样可以最大限度地使用硬盘空间,后面系统配置的时候再详细谈下。其实ZFS对于这两点很适合,send/recv备份很方便,分区根本不需要管,把不同硬盘加到不同pool就OK了。

还有一个选Linux的原因应该就是Docker了。这样可以很大程序减少应用程序对系统的干扰,把能在Docker下面跑的都放进去,各自跑各自的。

所以我最后选择了Debian开干。

硬件配置

硬件配置最开始设想的是4个SATA3接口,2个网卡,PICe接口进行扩展,CPU性能无所谓。网上搜了不少,候选方案有下面几个:

  1. HP Gen8。2个数据网口,1个管理网口。这点对于服务器管理非常重要,丢在某个角落完全不用管,可直接iLO进行所有操作。有4个盘位,还有内置的USB、SD卡插口。就是有点小贵,还有风扇噪音。
  2. HP Gen10。2个数据网口,4个盘位,AMD CPU。感觉也OK,风扇不吵了,但是少了iLO,而且低配价格也很高。
  3. GA N3160主板。2个数据网口,4个盘位,PCI插槽。刚开始是冲是它去的,最后PCI插槽放弃了,而且价格比J3455贵100多大洋。
  4. ASRock J4105/J3455。1个数据网口,4个盘位,PCIe x1插槽。两块板CPU有差别,内存一个是DDR4,一个是DDR3。但是J3455支持16G,J4105只支持8G。最后选择了J3455,因为它便宜 :)

其实最早是蛮想2个网口链路聚合的,这样多处同时从NAS存取数据的时候,网络不会成为其瓶颈,后来想了想,估计同时多处使用NAS的情况最近几年都不会有,后面如果确实有需要,可以PCIe转双网卡就OK。家里网线是六类双屏蔽(那个硬啊,现在有点后悔用双屏蔽的了),交换机Linksys SLM2008,路由器Buffalo WZR-HP-AG300H,光纤入户100M,所以暂时屋内1G局域网应该够用了。

这里给自己上了一课吧,当时查ASRock官网J3455的时候,就注意到SATA的第3,4接口是ASMedia ASM1061出来的,跟我后来买的PCIe转SATA接口是一样的。好像最高是400MB/s,就是如果这几个接口上SSD的话,可能会影响期性能。而且PCIe 2.0 x1的最高速度是500MB/s,这块也成了影响其性能的要点了。

电源选择方面,可以选小的DC转24针这种,完全没有噪音,功耗也低,但是但是贵啊。。。。最后选了一个ENP 7025B 250W的Flex电源,有噪音,功耗也比DC高,但是但是便宜啊 :(

开始机箱自带的风扇是12cm,直接从电源取电,也就是说一直是全速状态。看了下J3455板是CPU和机箱风扇电源接口都是3线的,所以可以调节风扇转速,后来又购了1个12cm 1500rpm的3线风扇。可惜板子不支持4线的风扇。。。

嗯,后面再详细记录下系统方面的配置吧。

软件配置

Debian

Debian安装比较简单了,将网络安装的ISO写入到U盘,安装就OK了。其实完全可以用PXE来搞定,后面再记录下PXE吧。

LVM

LVM里面有几个名词,PV物理卷(可以是硬盘,分区,文件),VG卷组(由物理卷组成的组,有点类似ZFS的Pool),LV逻辑卷(类似普通分区,可格式化,挂载)。

PV操作

1
2
3
4
dd if=/dev/zero of=/dev/xxx bs=512 count=1
pvcreate /dev/xxx
pvs
pvremove /dev/xxx

VG操作

1
2
3
4
5
6
7
vgcreate vg-nas /dev/xxx /dev/xxx
vgextend vg-nas /dev/xxx
vgreduce vg-nas /dev/xxx
vgchange -a y/n vg-nas # activating/deactivating vg
vgremove vg-nas
vgrename vg-nas-old vg-nas-new
vgs

LV操作

1
2
3
4
5
6
lvcreate -L 1T -n lv-data vg-nas # linar
lvcreate -l 100%FREE -n lv-other vg-nas
lvs
lvextend -l +100%FREE -n vg-name lv-name # /dev/vg-name/lv-name
resize2fs /dev/vg-name/lv-name
lvreduce --resizefs -L 500G vg-name/lv-name

LVM调整挂载点容量大小就比较方便了,不明白的时候可以看RedHat的在线文档,写得很详细。

sshd

默认SSHD是密码登录的,可以用sshkey-gen生成密钥后,再用ssh-copy-id将公钥复制到远程主机。NAS我需要internet也能访问到,这样SSHD默认配置就不太合适了,需要改几个地方,其实打开/etc/ssh/sshd_config就一目了然,从配置字面上就能知道啥作用了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Protocol 2

PermitRootLogin no
StrictModes yes
MaxAuthTries 6 #BAN IP的话可以用Fail2ban
MaxSessions 10

AuthorizedKeysCommand none
AuthorizedKeysCommandUser nobody

PasswordAuthentication no
PermitEmptyPasswords no

AllowGroups sshusers #将需要使用ssh的用户加入sshusers用户组

内网穿透

之前内网穿透使用的是ssh端口转发,NAS用远程端口转发-R 2222:127.0.0.1:22 VPS(VPS的2222端口转发到NAS的22端口),然后在终端机使用本地端口转发-L 4444:127.0.0.1:2222 VPS(终端机4444端口转发到VPS的2222端口),这样在终端机ssh -p 4444 localhost就可以访问NAS了,很方便不是?后来好像有时候网络不稳定,掉线后NAS不会自己进行端口转发,然后就找到了现在用的frpopenwrt frp

其中frp VPS Server端的配置如下。其实程序自带的说明文件里说得很详细,认真看下就可以配得很好了。

/etc/frp/frps.ini
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[common]
bind_addr = 0.0.0.0
bind_port = 7000

bind_udp_port = 7001

tcp_bind_port = 7000

dashboard_addr = 127.0.0.1
dashboard_port = 7500

dashboard_user = user
dashboard_pwd = pwd

log_file = /var/log/frps.log

log_info = info
log_max_days = 3

privilege_token = privilege_token

max_pool_count = 5
max_ports_per_client = 0

authentication_timeout = 900
tcp_mux = true
frps.service
1
2
3
4
5
6
7
8
9
10
11
12
13
[Unit]
Description=frps daemon
After=network.target
Wants=network.target

[Service]
Type=simple
User=nobody
Group=nogroup
ExecStart=/usr/bin/frps -c /etc/frp/frps.ini

[Install]
WantedBy=multi-user.targe

其中NAS的frp配置如下。OpenWrt的话,直接使用screen,sleep 30 && screen -dmS frpc frpc -c /etc/frp/frpc.ini,加到/etc/rc.local

frpc.ini
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[common]
server_addr = VPS_IP
server_port = 7000

log_file = /var/log/frpc.log
log_level = info
log_max_days = 3

privilege_token = privilege_token

admin_addr = 127.0.0.1
admin_port = 7400
admin_user = admin_user
admin_passwd = admin_pwd

pool_count = 5
tcp_mux = true
user = nas
log_fail_exit = true
protocol = tcp

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 2222
frpc.service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[Unit]
Description=FRP Client Daemon
After=network.target
Wants=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/frpc -c /etc/frp/frpc.ini
Restart=always
RestartSec=20s
User=nobody

[Install]
WantedBy=multi-user.target

下载工具

NAS的话必须要下载片子咯,BT/PT使用的是transmission,普通其它下载用的是aria2。使用transmission需要下载几个包apt install transmission-{daemon, remote{,-cli}},平时使用的话我在bash里加了下载几个alias。

1
2
3
4
alias lcp='rsync -avhW --no-compress --progress'
alias t-remote='transmission-remote -n user:password localhost'
alias t-remote='transmission-remote-cli -c user:password@localhost:9091'
alias a-d='aria2c -x 10 -j 1 --http-user user --http-passwd passwd'

NextCloud

其中架NAS最重要的一点就是网盘,放一些家庭照片和视频,常跟老婆説,等以后崽结婚的时候,把小时候的照片拿出来看,哈哈哈。

之前家里用的是FreeBSD下面架设的,这次换成Debian,那肯定就用Docker来跑这些咯,以后迁移起来也是非常快的,打包带走。。。

docker-compose.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
version: '3.7'

services:
db:
image: mariadb
restart: always
volumes:
- ./db:/var/lib/mysql
- /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
environment:
- MYSQL_ROOT_PASSWORD=pwd1
- MYSQL_PASSWORD=pwd2
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
nextcloud:
image: nextcloud:15-fpm-alpine
depends_on:
- db
volumes:
- ./html:/var/www/html
- /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
restart: always
nginx:
build: ./nginx
depends_on:
- db
- nextcloud
ports:
- "80:80"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
- ./html:/var/www/html
restart: always

其中./nginx/default.conf可以直接参考官网文档,然后还有一点就是nginx和nextcloud的docker image中用户名ID不一致,这样共享的目录./html就不能同时使用。需要调整下,nginx的image很小,可以直接从它下手,nginx的Dockerfile如下。

nginx
1
2
3
4
FROM nginx:alpine

RUN sed -i 's/:100:/:82:/g' /etc/passwd; \
sed -i 's/:101:/:82:/g' /etc/passwd /etc/group

SAMBA

家里其他设备访问NAS估计用得最多的就是SAMBA了吧,直接在/etc/samba/smb.conf最后加上一些配置就OK了,也懒得再认真配置了,只要能访问到就OK。

smb.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
[public]
comment = public
path = /data/BTDownloads
browsable = yes
create mask = 0660
directory mask = 0771
writable = no
guest ok = yes
[videos]
comment = public
path = /mnt/videos
browsable = yes
create mask = 0660
directory mask = 0771
writable = no
guest ok = yes
[win7]
comment = public
path = /mnt/cdrom
browsable = no
create mask = 0660
directory mask = 0771
writable = no
guest ok = yes
[personal]
comment = personal
path = /mnt/nas/personal
browsable = no
create mask = 0660
directory mask = 0771
writable = yes
guest ok = no

NFS

家里还有一些其他设备,比如路由器(OpenWrt)和Raspberry Pi,它们可以很方便的使用NFS,这样NAS提供NFS服务就可以了。修改/etc/exports

1
/mnt/nas/Tools  *(no_subtree_check,ro,all_squash,insecure,async)

其它

硬盘多了,功率也大,安装包hdparm可以设置硬盘standby的时间,据説可以延长使用时间,减小功耗,前提是不要设置得太小,硬盘磁头一停一启动地可能更耗硬盘。修改/etc/hdparm.conf

/etc/hdparm.conf
1
2
3
/dev/sdb {
spindown_time = 250
}

安装hddtemp sensors来读取温度值。

BIOS设置

关闭非必要功能,节能设置等

WOL,需要开启PCIE power on

tips

  1. NAS下载了很多片片,要传到手机上看,之前都是iTunes通过WIFI读取SAMBA共享文件,再传到VLC,慢得1B,还得再多开台电脑。后来了解到可以直接用curl传,方便了很多。curl -F "filename='filename'" -F "files[]=@filepath" http://VLC_IP/upload.json,本来想写个shell脚本自动上传目录下的所有文件的,但是没有找到好的方法,干脆用python吧,直接造成shell脚本运行。 :(不会直接使用Python上传到VLC,POST传的东西跟平时有点不一样。。。

  2. 下载Dropbox文件,Bash脚本Dropbox Uploader,在VPS上面下载Dropbox的照片,然后再传回来。

  3. 下载OneDrive文件,用windows里面的客户端可能是最简单的,但没有在NAS里面安装虚拟机,也不想平时再开台机器。后来想了一条路,Chrome下载OneDrive的照片目录,zip文件,然后打开Chrome开发工具,直接将刚才那个请求Copy as cURL,这样可以直接在NAS下载照片了。

  4. Picasaweb。long long ago,那时候Google还没有被封,传照片就到Picasa,哈哈,里面好多年轻的照片啊。这里需要设置下,在Google Drive里面设置下,将Google Photos照片导入到Google Drive,然后使用rclone将里面的照片复制到本地。rclone copy remote:Google\ Photos /mnt/photos -P

  5. 照片存了这么多份,肯定有重复的。最开始写了脚本进行查重,思路就是找出所有图片文件,对md5码,发现效率不高,后来放狗搜发现一个好工具fdepesfind . ! -empty -type f -size +500k -size -50M -exec md5sum {} + | sort > ~/allfiles,然后再对allfiles文件用unique就能找出重复文件了。fdupes -r -S -1 Data Documents nextcloud Pictures Work > ~/allfiles,这个也是找出所有重复文件,还可以直接使用fdupes快速删除重复文件。

后期优化

家庭网络换成1G带宽,扩展链路聚合。路由器换成了Buffalo AG300H,交换机换成了Cisio SLM2008,这样家里千兆OK了,但是发现丫我的无线是100M的WAN和LAN,电视机是100M口,一口老血吐出来。电视机的话,使用Xbox One S看得了,1000M口。无线路由器有空再换个好点的吧。开始装修的时候就是考虑NAS链路聚合的,毕竟多设备同时访问NAS的话,不链路聚合的话可能会成为瓶颈。到时候NAS换了PCIe的双网卡,硬盘只要4口,全换成4T盘,这样也OK的。

PXE

PXE的方案我使用的是DHCP Server在OpenWrt,然后tftp server在NAS。

DHCP配置/etc/config/dhcp

1
2
3
4
config boot 'linux'
option filename 'pxelinux.0'
option serveraddress '192.168.1.222'
option servername 'Liangwu PXE SERVER'

tftp-hpa配置。这里我在NAS上面直接将tftp跑在docker里面的。下载Debian netboot,并解压到res目录。

1
2
3
4
5
6
7
8
9
10
11
12
version: '3.7'

services:
tftp-hpa:
image: jumanjiman/tftp-hpa
restart: always
ports:
- "69:69/udp"
volumes:
- ./res/debian-installer/amd64/boot-screens/syslinux.cfg:/tftpboot/pxelinux.cfg/default:ro
- ./res/debian-installer:/tftpboot/debian-installer:ro
- ./res/windows:/tftpboot/windows:ro

修改./res/debian-installer/amd64/boot-screens/syslinux.cfg,增加下面内容支持windows安装。制作PE镜像,加入网卡驱动,这些在Microsoft文档可以找到。

1
2
3
4
5
6
7
label 9
menu label Install Windows 7
KERNEL memdisk
INITRD windows/winpe_7.iso
APPEND iso raw
prompt 0
timeout 0