树莓派+Samba+frp搭建NAS(网络云存储)
步骤/目录:
0.Samba的陷阱
1.树莓派下载安装samba
2.配置samba
3.为samba绑定系统用户
4.其他客户端连接到共享文件夹
(1)linux
(2)Windows
(3)安卓手机
(4)投影仪、电视
附:ES文件浏览器 连接Samba
5.frp+samba
6.加快读写速度
(0)分析瓶颈、测试硬盘
(1)网线直连
(2)换路由器
(3)修改smb.conf
(4)其他
(5)后续
(6)总结
7.自动挂载硬盘
8.使用qBittorrent离线下载
附录:小米手机开启FTP服务器
本文首发于个人博客https://lisper517.top/index.php/archives/16/
,转载请注明出处。
本文的目的是使用树莓派搭建NAS,可以远程访问云硬盘上的文件,并可进行离线下载。
本文实验日期为2022年2月19日。使用的是树莓派4B(内存8G版),系统为Pi OS 32位桌面版(2022年1月28日更新,镜像名 2022-01-28-raspios-bullseye-armhf.img )。frps运行在阿里云服务器(系统镜像Ubuntu 20.04)。
本文使用Samba搭建NAS,而且并没有涉及UPS电源、RAID等,属于入门级NAS,感兴趣的可自行深造。Samba可以替换为FTP,或者懒得自建NAS也可以购买群晖等现成NAS。
0.Samba的陷阱
当你在windows中打开 我的电脑 ,此时打开的东西叫文件管理器(Windows Explorer)。从文件管理器向其它地方拷贝东西,WE会要求目标硬盘先创建一个同等大小的空镜像(内容全部为0的镜像),再填充数据;Samba会调用 ftruncate()
函数来创建,而该函数在FAT文件系统上运行奇慢,需要花很长时间才能创建好空白镜像,WE以为Samba卡死了,最终会返回0x8007003B错误( 参考回答 )。
FAT文件系统创建空镜像这么慢,归根结底是不支持sparse file(稀疏文件),所以它创建空镜像时真的会在硬盘上挨个写入0;而支持sparse file的,直接指定空镜像文件的头尾区块、存在metadata中即可,不用管这些区块上原本是1还是0。
在Samba的设置中有一项隐藏的默认值 strict allocate = no
,如果改成yes,当单个文件大小超过500MB,Samba自己就会要求先生成空镜像再填充数据(参考 wiki-Samba 的 SMB/SMB2 write activities
一节)。
综上所述,不需要改Samba的配置,只要保证Samba挂载的不是FAT文件系统(exFAT、FAT32)而是ext4、NTFS就行了( 参考回答 )。先创建空镜像再写入,本意是好的,只是FAT执行坏了。
1.树莓派下载安装samba
输入apt install samba
即可。一共安装了16个包(如果没有samba-common-bin则需手动下载):
attr libcephfs2 liburing1 python3-dnspython python3-gpg python3-markdown
python3-requests-toolbelt python3-samba python3-tdb python3-yaml
samba-common samba-common-bin samba-dsdb-modules samba-vfs-modules tdb-tools
2.配置samba
samba的配置文件为/etc/samba/smb.conf
。在其中底部添加:
[shared]
path = /home/samba_user/shared #共享文件夹目录
valid users = samba_user
writable = yes
read only = no
create mask = 0755 #创建文件时,权限为755(测试时发现不管改成什么,创建的文件都是755)
directory mask = 0755 #创建目录权限为755(同上)
#browseable = yes #无权限的人可看到资源名称
另外在[global]
下添加:
security = user #设定安全等级
保存退出,使用testparm
检测samba设置有无语法错误。
关于samba配置更多信息可参考这篇文章。安全方面,还可用hosts allow设置允许访问的主机、write list设置仅哪些用户可进行写操作。
3.为samba绑定系统用户
创建用户的命令可以参考 提升树莓派安全性 。这里新建一个用户samba_user,并创建共享文件夹:
mkdir -p /home/samba_user/shared
useradd -d /home/samba_user samba_user
passwd samba_user
chown -R samba_user:samba_user /home/samba_user
然后为samba指定该用户及设置该用户的SMB密码,激活该用户,并重启服务:
smbpasswd -a samba_user #后面更改SMB密码也用这个命令
smbpasswd -e samba_user #-d可disable指定SMB用户
service smbd restart #服务名也可能不叫smbd。service --show-all查看所有服务
注意SMB密码和用户的系统密码可能不同,连接到samba共享文件夹只需要SMB密码。但是添加其他SMB用户时,还需要先创建一个同名的系统用户(否则 smbpasswd
时会提示 Failed to add entry for user
),即需要添加SMB用户时,要先添加一个系统用户,然后添加同名SMB用户,设置SMB密码,连接时用SMB密码。增加用户的范例:
useradd -d /dev/null -s /sbin/nologin samba_user2
如上设置的samba_user2系统用户,没有家目录,也无法登录,只是为了添加SMB用户而创建,安全性好一点。然后用 smbpasswd
添加SMB用户即可。
最后使用ufw打开samba使用的445端口:ufw allow 445
。
4.其他客户端连接到共享文件夹
(1)linux
以树莓派为例(这里顺便测试一下刚才的Samba设置),在资源管理器的地址栏输入 smb://树莓派ip ,按回车键后出现两个文件夹:print$与shared,其中shared就是刚才设置的共享文件夹,print$则是samba设置文件自带的。双击shared文件夹后提示需要输入密码,选择已注册用户,用户名为samba_user,密码为SMB密码,下面可以选是否记住密码、记住多久,然后即可进入共享文件夹。接下来插上u盘模拟硬盘,将u盘挂载到shared文件夹下:
df -h
#输出结果
#/dev/sda1 ...... /media/pi/xxxxx
umount /media/pi/xxxxx
cd /home/samba_user/shared
mkdir usb_1
mount -o uid=samba_user,gid=samba_user /dev/sda1 usb_1 #指定挂载后文件夹所属用户及组
用root身份时会默认挂载到root:root下,这里指定挂载到samba_user下才可对共享文件夹有rwx的权限(默认755)。
然后在资源管理器中查看,可以成功看到u盘里的文件,也可修改、删除、新增文件。
最后这里说明一下samba的权限问题:用smbpasswd -a 用户名
可添加一个SMB用户,该用户必须是系统用户。读写权限有两个地方受到限制,一是登录SMB的系统用户对共享文件夹有无rwx权限,二是在smb.conf里设置共享文件夹的读写权限(writable = yes
、read only = no
都是可写入)。所以挂载硬盘时要挂载到SMB用户同名的系统用户下(要不然就在挂载时设置权限为xx7),且[shared]
里面要指定可以读写共享文件夹。
如果在命令行下,也可以挂载,但是要安装一些samba客户端或扩展。以CentOS为例:
yum install -y cifs-utils
mkdir /mnt/shared
mount -t cifs -o username="用户名",password="密码" //树莓派ip/共享名 /mnt/shared #如 //192.168.1.190/shared
cd /mnt/shared
ls -al
可以看到挂载成功。还可以设置开机自动挂载,参考 这篇文章 ,在linux上使用fstab自动挂载SMB网络存储,命令如下:
vim /etc/fstab
写入一行:
//树莓派ip/共享名 /mnt/shared cifs defaults,username=用户名,password=密码,iocharset=utf8,nofail,auto 0 0
然后可以试验一下:
ls -al /mnt/shared
umount /mnt/shared
mount -a
ls -al /mnt/shared
没有报错,能正常挂载。
(2)Windows
在资源管理器的 此电脑 界面(就是显示C盘和其他盘符的界面),左上角点击 计算机-映射网络驱动器-映射网络驱动器 ,驱动器随便选,文件夹 写\\树莓派局域网ip\shared
,点击连接,需要输入凭证。输入samba_user和对应的SMB密码后成功登录,也可增、删、改文件。
如果windows上无法连接,可试试打开SMB功能:在设置中搜 启用或关闭Windows功能 ,找到 SMB 1.0/CIFS 文件共享支持 ,勾选上后确定,等组件下载完(带客户端、服务器端、自动删除),重启。但是这个可能是1.0的Samba协议,不知道对读写速度有无影响。笔者测试时没有开启此功能也可连接到共享文件夹。
测试速度:树莓派4B无线连接,接口和u盘都支持usb3.0,百兆路由器,写入速度5-6MB/s(不含创建镜像的时间),读取速度5-6MB/s。这里使用的是exFAT格式的u盘,写入大文件时会花较长的时间生成镜像,再写入数据;写入10GB的大文件时,由于镜像迟迟未创建完毕,windows上还出现了0x8007003B错误。下一节中尝试加快读写速度。
(3)安卓手机
可用 ES文件浏览器 。但是据说其可能使用老的Samba协议,导致传输速度低。
其他应用也有能连samba的。
另外,有的手机自带ftp服务器,也可以方便地与电脑传输文件,详见附录。
(4)投影仪、电视
在投影仪、电视自带的应用市场一般也能找到 ES文件浏览器,下载即可。另外,据说SMB在播放高码率视频时,不时卡顿,不如NLDA,笔者没有进行比较。
附:ES文件浏览器 连接Samba
以安卓手机为例,选择 网络-局域网-新建, 服务器 填 树莓派ip:445
,用户名、密码填SMB用户名、密码即可。
5.frp+samba
frps和frpc的初始搭建参考 frp+云服务器搭建能从外网访问的redis、mysql。这里默认已经配置好了frps、frpc,仅在frpc.ini增加一项映射。
samba默认使用445端口,在树莓派的frpc.ini中添加:
[pi4B-samba-server-1]
type = tcp
local_ip = localhost
local_port = 445
remote_port = 44550
之后树莓派上重启frpc:service frpc restart
,然后到frp服务器的防火墙打开44550端口(云服务器不要用ufw打开)。
在树莓派上,资源管理器输入 smb://frp服务器ip:44550 ,即可看到print$和shared两个文件夹;但点开shared时显示 挂载windows共享失败 : 连接超时,可能是由于云服务器的带宽只有5Mbps(640KB/s)。
在windows上,映射网络驱动器 不能写\\云服务器ip:44550\shared
,只能用默认的445端口。不过可以使用netsh命令将云服务器的44550端口接到本地的端口445(参考文章)。打开cmd,输入:
netsh interface portproxy add v4tov4 listenaddress=127.0.0.1 listenport=445 connectaddress=云服务器ip connectport=44550
netsh interface portproxy show all #查看一下
#最后使用netsh interface portproxy delete v4tov4 listenaddress=127.0.0.1 listenport=445即可删除这条端口转接设置
确认无误后,在 映射网络驱动器 的 文件夹 一栏直接填\\127.0.0.1\shared
即可。可能由于云服务器带宽问题,测试时一直卡在尝试连接界面。
注意,以上流程稍微有些问题,具体参考新的文章:
Samba, ftp与webdav 。
6.加快读写速度
(0)分析瓶颈、测试硬盘
首先测试一下瓶颈可能在哪里。从windows机器到树莓派,数据需要经过:硬盘读写->树莓派内存->树莓派网卡->有线时通过网线,无线通过无线网卡->路由器->有线或无线->客户端(暂不考虑客户端变化)。可以控制的地方主要有:
硬盘或u盘读写速度;
硬盘或u盘是否通过usb3.0连到树莓派;
树莓派内存是否够用(本文中是8G版,测试时内存消耗不大);
网线传输速度/树莓派网卡速度;
路由器网口是百兆还是千兆。
首先测试一下u盘。安装hdparm(apt install hdparm
),输入下面的命令:
hdparm -Tt /dev/sda1
#输出结果
Timing cached reads: 1688 MB in 2.00 seconds = 844.54 MB/sec
Timing buffered disk reads: 342 MB in 3.01 seconds = 113.62 MB/sec
可以看出u盘的读取还是很快的(hdparm更详细的教程见runoob-hdparm)。
然后使用dd命令测试u盘写入速度:
cd /home/samba_user/shared/usb_1
dd if=/dev/zero of=./testwritefile bs=4KB count=131072 #写入5GB的文件,测试前要确保有这么大的空间
# 输出结果
...
5242880000字节(5 GB,4.9 GiB)已复制,178.29 s,29.4 MB/s
#rm testwritefile
写入速度为30MB/s左右。
更多关于dd命令测试硬盘的内容可参考这篇文章。
(1)网线直连
用买路由器送的免费网线直连树莓派到路由器,写入速度提升到11.5MB/s,已经达到路由器百兆上限(12.5MB/s),提升明显。
(2)换路由器
测试时的路由器只有百兆网口,换成千兆网口后估计速度可进一步提升;换成千兆网口后理论上支持125MB/s读写,但u盘的读写只有113 / 30 MB/s,将成为新的瓶颈。
(3)修改smb.conf
在[global]
下添加:
read raw = yes
write raw = yes
aio read size = 0 #关闭异步读取
aio write size = 0 #关闭异步写入
large readwrite = yes
由于测试时瓶颈是路由器,修改samba配置后读写速度还是11.5MB/s。
(4)其他
挂载的硬盘最好不用NTFS格式,若用的是NTFS注意使用ntfs-3g挂载(据说树莓派默认即ntfs-3g)。树莓派上格式化设备为指定格式:mkfs -t 格式 /dev/sdxx
,也可以用其他工具。windows上可试试DiskGenius。
据说换网线也可提升速度。当然,前提是瓶颈在网线;若路由器只支持百兆,换网线应该也没用。
另外,有些设备可能用的还是比较老的samba协议,若要添加对老samba协议的支持,可以在smb.conf中的[global]
下添加:
min protocol = NT1
NT1为Samba v1,SMB2、SMB3分别是v2、v3。
最后,从windows10机器上向共享文件夹拷贝文件时会先生成等大的镜像,再写入数据;写入10GB的大文件时,由于镜像迟迟未创建完毕,windows上还出现了0x8007003B错误。所以目前还不能从windows机器上写入大文件。
(5)后续
使用希捷硬盘(exFAT格式),通过带USB3.0的硬盘盒连接到树莓派的USB3.0接口,树莓派和windows电脑都通过网线直连到路由器的1000M网口,smb.conf的[global]
下添加相应内容。测试读写速度为80-100MB/s,写入单个文件、高峰时可达113MB/s,已经达到硬盘写入速度极限。
(6)总结
使用samba共享树莓派挂载的硬盘,可以实现Pi OS、windows间共享文件(android未测试),进行一些设置后甚至可达硬盘读写速度上限。但是从windows向硬盘写入10G以上的大文件时会报错(因为linux系统下写入一般是先创建空白镜像,而windows系统在这段时间内无法得到反馈,误以为写入操作卡死),算是一个缺陷。
7.自动挂载硬盘
修改/etc/fstab文件,添加一行:
设备名 挂载点 硬盘格式 设置 是否备份 是否检测及检测顺序
/dev/sdxx /home/samba_user/shared/1 exfat defaults,uid=1003,gid=1004,nofail,auto,noatime 0 0
(这里的挂载点为/home/samba_user/shared/1
,而smb.conf中设置的是path = /home/samba_user/shared
,两处不一致会导致windows下显示共享盘的大小为派的sd卡大小而不是硬盘大小,但是对实际使用几乎没问题。如果只有一张NAS硬盘就可以把两处改一样)
其中uid和gid可通过id samba_user
查看;
设备名推荐换成UUID=xxxxxx
,不会挂错地方。硬盘的UUID可插上硬盘后通过 blkid
或 ls -l /dev/disk/by-uuid
查看;
关于nofail,auto,noatime的解析参考浅析 fstab 与移动硬盘挂载方法。
最后,使用raspbian带桌面的系统,会发现系统识别到存储介质时会自动挂载,一般是在/media/pi/目录下,所属用户和组都是pi。若要关闭这个功能,需要以pi用户的身份登录桌面,在文件管理器中,左上角 编辑-偏好设置-卷管理 ,第一个选项是开机自动挂载,第二个选项是插入移动存储时自动挂载。
8.使用qBittorrent离线下载
也可以用aria2代替,但是据说aria2没有公网ip时下载较慢。以下参考了利用树莓派进行挂机下载。
apt install qbittorrent qbittorrent-nox
(下载qBittorrent-Enhanced-Edition可自动封禁迅雷吸血鬼ip,见上述参考文章)
下载完成后,使用qbittorrent-nox
即可开启qBittorrent的Web UI,在 树莓派ip:8080 可访问到网页qBittorrent,十分方便。默认用户密码为admin和adminadmin,在 设置-Web UI 中修改。
接下来把qbittorrent-nox注册到开机自启:
nano /etc/systemd/system/qbittorrent-nox.service
服务文件中写入以下内容:
[Unit]
Description=qBittorrent-nox_WebUI
After=network.target
[Service]
User=root
Type=simple
RemainAfterExit=yes
ExecStart=/usr/bin/qbittorrent-nox -d
ExecStop=/bin/kill $MAINPID
Restart=on-failure
RestartSec=5
StartLimitInterval=0
[Install]
WantedBy=multi-user.target
允许自启,并开启qBittorrent-nox:
systemctl enable qbittorrent-nox
systemctl start qbittorrent-nox
附录:小米手机开启FTP服务器
在 文件管理器-分类-远程管理 中可开启FTP服务器,设置里还可以修改连接的用户名和密码。开启后手机显示 ftp://手机ip:2121 ,在windows的资源管理器输入 ftp://手机ip:2121 、用户名密码 即可查看手机文件。测试了一下,写入速度1.9-2.5MB/s,读取速度3MB/s,勉强能用。
后续:更换为千兆路由器后,写入速度在16-40MB/s,提升明显。