步骤/目录:
0.Samba的陷阱
1.需求介绍
2.Samba与frp
3.ftp
4.webdav

本文首发于个人博客https://lisper517.top/index.php/archives/59/,转载请注明出处。
本文的目的是使用树莓派搭建可公网访问的NAS,并且比较Samba, ftp与webdav这三种方式的异同。
本文实验日期为2022年10月11日。使用的是树莓派4B(内存8G版),系统为Pi OS 64位桌面版(2022年4月4日更新,镜像名 2022-04-04-raspios-bullseye-arm64.img )。

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-SambaSMB/SMB2 write activities 一节)。

综上所述,不需要改Samba的配置,只要保证Samba挂载的不是FAT文件系统(exFAT、FAT32)而是ext4、NTFS就行了( 参考回答 )。先创建空镜像再写入,本意是好的,只是FAT执行坏了。

1.需求介绍

在之前 树莓派+Samba+frp搭建NAS(网络云存储) 一文中,曾介绍过使用Samba在局域网内搭建NAS,并且使用千兆路由器后达到了不错的内网分享速度。在那篇文章中还将samba使用的445端口通过frp映射到公网ip,试图在公网也能访问NAS,但实际上并没有成功。本文将再次尝试,并且除了Samba之外,还尝试使用ftp与webdav方式搭建。需要注意的是,文中提到的所有方法都是树莓派直连硬盘,也就是说用linux把硬盘分享为NAS;如果你用windows电脑直连硬盘分享NAS,本文可能帮不了你。
最后,本文中使用的都是云服务器+frp,这样NAS的带宽会被严重限制为云服务器的带宽,有条件的建议还是用DDNS,见之前的文章 路由器与DDNS (如果你家用的是移动的宽带,也可以不用看那篇文章,就用云服务器+frp)。

2.Samba与frp

在之前的文章中,成功在树莓派上搭建了Samba,内网已经能流畅访问,千兆路由器下,文件读写最快能达到113MB/s,而机械硬盘的最高读写速度也才150MB/s左右,已经很不错了。后来试着用frp开放到公网,怀疑因为云服务器带宽不够(640KB/s),导致windows上连接超时。之后换用 3.75MB/s 的云服务器,还是无法连接,这时才怀疑是否操作有些问题。最终,通过一番寻找,笔者成功解决了Samba开放到外网、用windows连接的问题。这里就跳过Samba的搭建,直接讲如何配置frp,windows如何连接。

云服务器、frps和frpc的其他配置见前文,frpc配置好后添加一个samba的映射即可:

[samba]
type = tcp
local_ip = localhost
local_port = 445
remote_port = 44500

这里 remote_port 选择44500而不是445,主要是因为安全性。445端口本来就是windows用来共享文件夹的,据有些文章说以前 永恒之蓝 病毒针对445、139等端口搞了一些事情,导致现在445、139等端口被全网封禁(139、138、137也和文件共享有关,据说如果445走不通就会尝试这些端口)。所以现在映射445到服务器其他端口,你可以自己选一个大一点的,这里以44500为例。设置完frpc.ini后,在云服务器的防火墙中打开44500端口。

到这里,其实已经可以连接到Samba了,mac、linux都可以指定端口号,在文件浏览器中输入 smb://云服务器ip或域名:44500/共享名 即可,然后输入用户名密码即可;linux用命令行挂载时,需要如下操作:

apt install -y cifs-utils #CentOS把apt换成yum即可
mkdir /mnt/test
mount -t cifs -o username="用户名",password="密码",port=44500 //云服务器ip或域名/共享名 /mnt/test

但是windows不支持把Samba换到其他端口,只能使用445端口交流。好在有其他的方法,比如将云服务器的44500端口在windows电脑上连接到445端口。用管理员模式运行cmd,进行如下操作(这里参考了 这篇文章 ):

netstat -aon | findstr "445"

如果有输出任何字符的话,说明系统占用了445端口,一般这个进程的pid为4,相关的服务名为Server。cmd中输入 services.msc ,按Enter打开,出现一个管理服务的界面,找到一个名称为 Server 的服务,右键单击,选择属性,在 常规 分页中把它的 启动类型 从 自动 改为 禁用 。这个Server服务估计是管理一些共享文件夹的,不过笔者实验时docker desktop也需要用它(但是windows想要连接Samba必须关掉Server)。之后重启电脑,再次用管理员模式打开cmd,再次输入 netstat -aon | findstr "445" ,确认这次没有输出任何字符、只输出了空行。然后运行以下命令:

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即可删除这条端口转接设置

那么现在云服务器的44500端口就接到windows电脑的445端口上,你往本机的445端口发送什么东西,都会被转发到云服务器的44500端口(像iptables配置的端口转发一样)。此时你在文件浏览器中输入 \\localhost\共享名 ,或者用之前文章提到的 此电脑 -> 计算机 -> 映射网络驱动器 也可以,同样填 \\localhost\共享名 ,之后输入用户名密码即可。

如果Samba开放到公网后想用android手机连接,ES文件浏览器不能用(可能需要开会员才能连公网SMB,不是很想开),笔者找到的其他android的SMB客户端又要用Google Play下载。如果需要用android连NAS,建议看后面的内容,或者你把手机刷成其他海外版固件。

3.ftp

ftp是一项上古技术了,很早期就被用于计算机间分享文件,现在也有很多镜像站的网站名称中有ftp。早期的ftp不需要验证,后来发展出了vsftp,即 very secure ftp ,所以拿来做公网开放的NAS也还行。
在树莓派上进行如下操作:

apt-get install vsftpd
nano /etc/vsftpd.conf

把vsftpd的配置文件进行如下修改:

在最开头加上两行: pasv_enable=YES 和 port_enable=YES
再加上两行: pasv_min_port=65000 和 pasv_max_port=65001
把 #write_enable=YES 前面的#去掉
把 #local_umask=022 前面的#去掉

然后重启一下vsftpd服务:

service vsftpd restart

和samba一样,ftp也需要用户名、密码登录,而且ftp用户、密码对应同名的系统用户、密码(但是samba虽然用户同名,密码却独立于系统密码);默认情况下,使用某个系统用户的用户名、密码登录,登录后就会看到该用户的家目录,所以这里可以创建一个系统用户ftp_user:

useradd -m -s /bin/bash ftp_user
passwd ftp_user

然后你可以挂上需要共享的硬盘,把硬盘mount到/home/ftp_user下。如果有防火墙的话,打开20、21、65000、65001端口(比如ufw、iptables),就可以用客户端连接了。

在windows机器上,打开资源管理器,直接在地址栏输入 ftp://ftp机器ip地址:21/ 即可连接,会提示输入用户名密码(ftp_user和 passwd ftp_user 设置的密码)。
在linux机器上,带图形界面的话也可以在资源管理器输入 ftp://ftp机器ip地址:21/ ;在命令行界面,可以使用 curlftpfs 扩展:

yum install -y curlftpfs #ubuntu是apt
mkdir /mnt/ftp_test
curlftpfs -o codepage=utf8 ftp://用户名:密码@ftp机器ip地址:端口号 /mnt/ftp_test

即可把ftp文件系统挂载到/mnt/ftp_test下。
在Mac上,笔者太过贫穷没有Mac,但是估计也是在地址栏输入 ftp://ftp机器ip地址:21/ 就行了。

ftp最重要的缺陷可能是无法实时播放。笔者在内网实验时,很多视频播放器都支持播放ftp视频(即从URL打开),比如开源的SMPlayer;但是输入URL时,如果你的FTP有密码(不允许匿名连接),则可能还要在URL中加上用户名密码,比较麻烦;据说用WebDrive(收费)等软件可将FTP服务器挂载到一个驱动器号下、实时打开视频,但是笔者没有继续实验。
ftp也有优点,比如ES文件浏览器可以轻松支持公网FTP;开放到公网时,从windows客户端连接时可以随意换端口(从21换成2121或者其他),不像samba那样只能在windows客户端上把本机的445和公网ip的samba端口连接。
单从传输速度看,ftp和samba差不多。但是综合考虑,笔者还是推荐samba。

关于ftp公网开放,使用之前文章提到的frp可以实现,笔者没有继续深究。

最后稍微讲解一下ftp的配置。ftp的连接方式分为2种,PORT主动方式和PASV被动方式,默认使用PORT方式。客户端使用21端口(或者其他自行设置的端口)连接到服务器后,需要传输文件时,PORT方式是客户端打开一个随机端口(这个端口在一定范围内)、服务器端用20端口向客户端建立连接(受客户端防火墙影响),PASV方式则是服务器打开一个随机端口(用pasv_max_port和pasv_min_port确定上下限)、客户端连接到服务器的这个随机端口(受服务器端防火墙影响)。从方便的角度考虑,PASV不需要客户端在每次连接时放行端口,应该更好一点。更多ftp的配置可参考 这篇文章

4.webdav

关于在树莓派上设置webdav的内容,可参考 这篇文章 。据说webdav在开放到公网后,从windows客户端连接时比samba简单一点,笔者没有验证,主要是samba确实已经够用了,而且兼容性上samba也是最优选,参考笔者的命令可很方便地随时随地打开samba的NAS,实时查看、编辑文件,很多电视盒子、机顶盒等设备都支持SMB。

标签: frp, NAS, samba, ftp, webdav

添加新评论