基于Armbian根文件系统安装配置多种文件共享协议

最近由于工作原因,需要在RK3568的一块开发板上部署NAS(网络附属存储)私有云的环境。一部分工作就是需要在板端把文件共享协议搭起来,方便客户端能随时随地访问到NAS的文件。目前在RK3568上跑的操作系统是一款开源的Linux操作系统,名为Armbian,Armbian是轻量级的Debian系统和为ARM开发板专门发行并重新编译的Debian系统(Ubuntu派生自Debian)。
需要安装部署的文件协议包括Samba、NFS、FTP、WebDav以及一个作者开发的基于浏览器访问的文件管理器chfs。
以下软件的安装均需要建立在板子能连接到互联网的基础上。

文件协议介绍

Samba

Samba简介

samba 是基于SMB协议(ServerMessage Block,信息服务块)的开源软件,samba也可以是SMB协议的商标。SMB是一种Linux、UNIX系统上可用于共享文件和打印机等资源的协议,这种协议是基于Client\Server型的协议,Client端可以通过SMB访问到Server(服务器)上的共享资源。当Windows是 Client,Linux是服务器时,通过Samba就可以实现window访问Linux的资源,实现两个系统间的数据交互。samba服务程序已经成为在Linux系统和Windows系统之间共享文件的最佳选择,当然在Linux系统与Linux系统之间的文件共享也选择samba。

Samba安装部署

要在Armbian上安装Samba,请运行以下命令:

1
2
sudo apt-get update
sudo apt-get install samba

安装软件包后,继续执行下面步骤,我们将执行配置并管理Samba服务:
Samba使用/etc/samba/smb.conf中的配置文件,如果更改此配置文件,则在重新启动Samba守护程序之前更改不会生效。
让我们首先创建一个通过Samba共享的目录,该目录必须存在才能在smb.conf中配置,我们将在/home下创建一个:

1
sudo mkdir -p /home/smblibin

创建samba共享用户:

1
useradd  smblibin -s /usr/sbin/nologin

设置用户密码并确认:

1
2
3
4
$ sudo smbpasswd -a smblibin
New SMB password:
Retype new SMB password:
Added user smblibin.

使用以下命令设置密码后启用samba帐户:

1
2
$ sudo smbpasswd -e smblibin
Enabled user smblibin.

配置安全Samba共享:

1
2
3
4
5
6
7
[smblibin]
path = /home/smblibin
read only = no
browseable = yes
force create mode = 0660
force directory mode = 2770
valid users = @smblibin

进行更改后重新启动samba守护程序:

1
2
sudo systemctl restart nmbd.service
sudo systemctl restart smbd.service

使用windows映射网络磁盘的方式访问共享目录:

1
\\192.168.1.xxx\smblibin

FTP

FTP简介

文件传输协议(File Transfer Protocol,FTP)是用于在网络上进行文件传输的一套标准协议,它工作在 OSI 模型的第七层, TCP 模型的第四层, 即应用层, 使用 TCP 传输而不是 UDP, 客户在和服务器建立连接前要经过一个“三次握手”的过程, 保证客户与服务器之间的连接是可靠的, 而且是面向连接, 为数据传输提供可靠保证。
FTP允许用户以文件操作的方式(如文件的增、删、改、查、传送等)与另一主机相互通信。然而, 用户并不真正登录到自己想要存取的计算机上面而成为完全用户, 可用FTP程序访问远程资源, 实现用户往返传输文件、目录管理以及访问电子邮件等等, 即使双方计算机可能配有不同的操作系统和文件存储方式。

FTP安装部署

安装vsftpd

1
2
$ sudo apt update
$ sudo apt install vsftpd

配置vsftpd

1
sudo vi /etc/vsftpd.conf

我们将只允许本地用户访问 FTP,并禁用任何匿名访问。为此,请确保存在以下几行,如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
listen=YES
listen_ipv6=NO
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
anon_mkdir_write_enable=NO
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_file=/var/log/vsftpd.log
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
ssl_enable=NO

配置用户目录

我们将为 FTP 事务创建一个新用户帐户。

  1. 添加新用户

    1
    $ sudo adduser ftplibin

    设置一个强密码并跳过所有其他提示。

  2. 将用户添加到允许的 FTP 用户列表中

    1
    $ echo "ftplibin" | sudo tee -a /etc/vsftpd.userlist
  3. 创建 FTP 和文件目录
    创建 FTP 文件夹。

    1
    $ sudo mkdir /home/ftplibin/ftp

    设置其所有权。

    1
    $ sudo chown nobody:nogroup /home/ftplibin/ftp

    删除写入权限。

    1
    $ sudo chmod a-w /home/ftplibin/ftp

    在继续之前验证权限。

    1
    2
    3
    4
    $ sudo ls -al /home/ftplibin/ftp
    total 8
    dr-xr-xr-x 2 nobody nogroup 4096 Jun 7 13:08 .
    drwxr-xr-x 3 ftplibin ftplibin 4096 Jun 7 13:08 ..

    现在让我们为文件创建实际的可写目录。

    1
    2
    $ sudo mkdir /home/ftplibin/ftp/upload
    $ sudo chown ftplibin:ftplibin /home/ftplibin/ftp/upload

    测试权限。

    1
    2
    3
    4
    5
    $ sudo ls -al /home/ftplibin/ftp
    total 12
    dr-xr-xr-x 3 nobody nogroup 4096 Jun 7 13:10 .
    drwxr-xr-x 3 ftplibin ftplibin 4096 Jun 7 13:08 ..
    drwxr-xr-x 2 ftplibin ftplibin 4096 Jun 7 13:10 upload

    最后,让我们添加一个test.txt用于测试的文件。

    1
    $ echo "vsftpd test file" | sudo tee /home/ftplibin/ftp/upload/test.txt
  4. 测试客户端FTP访问
    在Windows端文件资源管理器输入:

    1
    ftp://192.168.1.xxx

    然后输入设置的密码即可。

NFS

NFS简介

NFS是Network File System的缩写,即网络文件系统。它的主要功能是通过网络(一般是局域网)让不同的主机系统之间可以共享文件或目录。NFS客户端可以通过挂载(mount)的方式将NFS服务端共享的数据目录挂载到NFS客户端本地系统中(就是某一个挂载点下)。从NFS客户端的机器本地看,NFS服务端共享的目录就好像是客户自己的磁盘分区或者目录一样,而实际上确是远端的NFS服务端的目录。NFS主要用于类Unix系统之间的共享, 最早是由Sun公司发展出来的。

NFS网络文件系统类似windows系统的网络共享、安全功能、网络驱动器映射,这也和linux系统里的samba服务类似。应用于互联网中小型集群架构后端作为数据共享,如果是大型网站,那么有可能还会用到更复杂的分布式文件系统,例如Moosefs(mfs)、glusterfs、FastDFS。

NFS安装部署

NFS服务端配置

  1. 安装nfs服务主程序nfs-kernel-server
    这个软件提供nfs的主要服务,提供文件系统的完整功能。这里要提醒一下,NFS服务器会直接使用到内核的模块,所以内核必须要支持 NFS 才行。如果操作系统的版本是自行编译的内核的话,需要注意编译NFS的内核支持。安装命令如下:

    1
    root@debian:~# apt install nfs-kernel-server
  2. 安装RPC主程序rpcbind以前的程序名叫做portmap
    NFS 服务都是通过 RPC 来具体实现的,所以要正常使用NFS服务,需要启动 rpcbind来实现端口的映射工作,正常安装完nfs-kernel-server程序会
    自动安装上rpcbind,如果没有安装通过下面命令安装:

    1
    root@debian:~# apt install rpcbind
  3. 查看NFS主服务

    1
    root@debian:~# systemctl status nfs-kernel-server.service
  4. 查看rpcbind服务

    1
    root@debian:~# systemctl status rpcbind.service
  5. 设置NFS主程序开机启动

    1
    root@debian:~# systemctl enable nfs-kernel-server.service
  6. 设置rpcbind主程序开机启动

    1
    root@debian:~# systemctl enable rpcbind.service

    正常安装完程序后会启动服务并添加开机启动。

  7. 配置文件/etc/exports
    这个文件是NFS的主要配置文件,如果不存在新建这个文件。先举个例子:将/home/nfs/目录共享给局域网中192.168.1.0/24网段的用户可读写并且数据同步写入到硬盘和内存,所以用户只读。/etc/exports配置文件的内容如下:

    1
    2
    3
    root@debian:~# vim.tiny /etc/exports
    /home/nfs 192.168.1.0/24(rw,sync) *(ro)
    [共享目录] [可以访问的主机(权限)] [*代表所有用户(权限)]

    这个配置文件很简单,每一行前面是要共享的目录,是以目录为单位。然后这个目录可以依照不同的权限共享给不同的主机,不同的主机用空格分开,主机后面是以小括号”()”定义权限参数,若权限参数不只一个时,则以逗号”,”分开,并且主机名与小括号是连在一起的,主机与共享目录之间用空格分开,在这个文件内也可以利用#号来进行注释。可以使用主机名,但这个主机名必须要在/etc/hosts内,或可以使用DNS找到该名称,重点是可以找到IP地址,如果是主机名可以支持通配符,例如”*”或”?”均可接受。
    小括号内常用的权限参数如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    ro:共享目录只读;
    rw:共享目录可读可写
    sync:同步,将数据同步写入内存缓冲区与磁盘中,效率低,但可以保证数据的一致性;
    async:异步,将数据先保存在内存缓冲区中,必要时才写入磁盘,效率高,但有丢失数据的风险;
    wdelay(默认):如果有多个客户端要对同一个共享目录进行写操作,则将这些操作集中执行。对有很多小的IO写操作时,使用该选项可以有效的提高效率;
    no_wdelay:如果有多个客户端要对同一个共享目录进行写操作则立即写入。当设置了async选项时,no_wdelay选项无效,应与sync配合使用;
    root_squash(默认):将来访的root用户映射为匿名用户或用户组;
    no_root_squash:来访的root用户保持root帐号权限;
    all_squash:所有访问用户都映射为匿名用户或用户组;
    no_all_squash(默认):访问用户先与本机用户匹配,匹配失败后再映射为匿名用户或用户组;
    anonuid=<UID>:指定匿名访问用户的本地用户UID,默认为nfsnobody(65534);
    anongid=<GID>:指定匿名访问用户的本地用户组GID,默认为nfsnobody(65534);
    secure(默认):限制客户端只能从小于1024的tcp/ip端口连接服务器;
    insecure:允许客户端从大于1024的tcp/ip端口连接服务器;
    subtree_check :若输出目录是一个子目录,则nfs服务器将检查其父目录的权限;
    no_subtree_check(默认) :即使输出目录是一个子目录,nfs服务器也不检查其父目录的权限,这样可以提高效率;
    hide:共享一个目录时,不共享该目录的子目录;
    no_hide:共享子目录;

    如果想了解更多的参数,可以使用man exports.。
    我的配置为:

    1
    2
    root@debian:~# cat /etc/exports
    /home/nfs 192.168.1.0/24(rw,sync,no_root_squash) *(ro)

    即/home/nfs目录为我们创建的共享目录。客户端访问到的就是这个目录。权限为可读可写、实时写入磁盘、来访的root用户保持root帐号权限。

NFS客户端配置

  1. 安装客户软件nfs-common和rpcbind

    1
    2
    root@debian:~# apt install nfs-common
    root@debian:~# apt install rpcbind

    正常安装完nfs-common这个软件rpcbind也会一同安装上

  2. 查看rpcbind服务的状态

    1
    root@debian:~# systemctl status rpcbind.service

    没有启动要手动启动这个服务,并设置开机启动这个服务

  3. 通过命令showmount查看共享的目录
    在挂载远程NFS共享目录前,做好先使用showmount命令查看NFS服务器的共享目录列表,已确定这些共享目录是否运行本地访问。showmount命令的格式如下:

    1
    root@debian:~# showmount  [选项]  [主机的IP或名称]

    常用的选项如下:

    1
    2
    3
    4
    5
    6
    -a:该选项一般在NFS服务器上使用,用于显示已经挂载了服务器共享目录的客户端及他们所使用的共享目录。
    -d:与-a类似,但只显示目录,不显示具体的客户端。
    -e:显示指定NFS服务器输出的共享目录列表
    -h:显示帮助信息
    -v:显示版本信息
    --no-headers:不输出标题信息

    具体例子:

    1
    root@debian:~$ showmount -e 192.168.1.102       #显示NFS服务器192.168.1.102 输出的共享目录
  4. 创建挂载点并挂载共享目录
    用户可以自定义挂载点,而与需与NFS服务器上共享目录一样的路径,用户可以创建多个挂载点,挂载同一个共享目录。创建的目录如果由使用者全权控制,使用者对挂载目录应该有读写执行的权限。
    挂载共享目录使用的命令与挂载本地文件系统使用的命令一样,都是使用mount命令,其格式如下:

    1
    root@debian:~# mount  [选项]  NFS服务器IP或主机名:共享目录  挂载点

    命令格式中的冒号(:)一定不要少,他是在NFS服务器IP或主机名和共享目录中间,没有空格,mount命令与nfs相关选项说明如下:

    1
    2
    3
    4
    5
    6
    7
    8
    -t nfs:指定要挂载的文件系统类型为NFS,不加这个选项也可以,mount命令会自动识别
    -o ro:只挂载的文件系统为只读
    -o rw:可读写
    -o port=n:指定连接NFS服务器使用的端口号
    -o retry=n:指定放弃挂载前尝试的时间,单位为分钟。前台挂载的默认值为2,后台挂载的默认值为10000
    -o fg:指定以前台方式完成挂载工作。如果与NFS服务器之间的连接存在问题,那么mount命令会一直重复尝试挂载,直到成功或超时为止。在这个过程中,mount命令会占用终端窗口,用户无法在窗口中运行其他命令
    -o bg:与fg相反,使用后台方式完成挂载工作。如果与NFS服务器之间的连接存在问题,那么mount命令会在后台进行挂载,而不会占用终端窗口。
    注意:-o选项可以通过逗号(,)分隔,联合使用。

    具体例子:把NFS服务器192.168.1.102的共享目录/home/nfs挂在到本地的/home/nfs目录,挂载选项设置为只读,后台挂载方式,放弃挂载前尝试的时间为1分钟

    1
    root@debian:~# mount -t nfs -o rw,bg,retry=1  192.168.1.102:/home/nfs  /home/nfs
  5. 卸载NFS文件系统
    与卸载普通的本地文件系统一样,可以通过umount命令把它卸载,终止与NFS服务器的连接。但在卸载前,应该确保已经没有任何进程在使用该文件系统。
    卸载NFS文件系统的命令格式如下所示:

    1
    root@debian:~# umount [远程文件系统或挂载点]

    卸载上面例子挂载的NFS文件系统的方法:

    1
    2
    3
    root@debian:~# umount /home/nfs  

    root@debian:~# umount 192.168.1.102:/home/nfs

WebDav

WebDav简介

WebDav 基于 HTTP 协议的通信协议,在GET、POST、HEAD等几个HTTP标准方法以外添加了一些新的方法,使应用程序可对Web Server直接读写,并支持写文件锁定(Locking)及解锁(Unlock),还可以支持文件的版本控制。

WebDav部署

WebDav 是 GitHub 上开源的项目,基于 Go 语言实现,不仅跨平台,还支持 ARM 架构,可在㠌入式设备中部署 WebDav 服务器。项目地址为hacdias
在 GitHub 下载对应的架构 WebDAV,如:linux-arm64-webdav.tar.gz 。解压后获得 webdav 。
用文本编辑器新建 config.yaml 文件,内容如下:

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
35
36
37
38
39
40
41
# 监听任意网卡,多网卡可指定对应ip
address: 0.0.0.0
port: 8880
# 如果无需验证填 false
auth: true
# 如果不需要 https 则填 false
tls: true
# https证书和密钥,如果 tls 为 false,cert 和 key 不需要
cert: /data/www/cert/szhome.xf1024.com_nginx/cert.pem
key: /data/www/cert/szhome.xf1024.com_nginx/cert.key
# 访问前缀,建议默认
prefix: /

# 如果 auth 为 false 生效,文件共享的路径
scope: /data/webdav
# 是否允许修改
modify: true
rules: []

# 跨域设置
cors:
enabled: true
credentials: true
allowed_headers:
- Depth
allowed_hosts:
- http://localhost:8880
allowed_methods:
- GET
exposed_headers:
- Content-Length
- Content-Range

# 用户信息,如果 auth 为 true 生效
users:
- username: admin
password: admin
scope: /home/admin
- username: libin
password: libin
scope: /home/libin

在板端运行如下命令:

1
webdav -c ./config.yaml

然后使用windows映射网络磁盘的方式访问共享目录即可:

1
http://192.168.1.xxx:8880

chfs

chfs简介

chfs是一个界面简洁,简单易用的免费文件共享服务器。使用http协议,只需浏览器就可以管理文件。

chfs部署

  1. 下载chfs文件
    1
    wget http://iscute.cn/tar/chfs/2.0/chfs-linux-arm64-2.0.zip
  2. 解压缩
    1
    unzip -o chfs-linux-arm64-2.0.zip -d /usr/local/bin
  3. 改变属性到500
    1
    chmod 500 /usr/local/bin/chfs
  4. 可以把它做成服务,开机自启:
    1
    vi /etc/systemd/system/chfs.service
  5. 粘贴下面的内容,根据自己情况修改
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    [Unit]
    Description=chfs
    After=network.target

    [Service]
    User=root
    Type=simple

    #ExecStart=/usr/local/bin/chfs --file="/usr/local/etc/chfs.conf"
    #按说明,是可以用一个配置文件来启动chfs的,但我不知道为何用不上,我用了下面的方法。

    ExecStart=/usr/local/bin/chfs --path="/home/chfs" --port=8080 --rule="::|admin:123456:RWD" --log=""
    #path后是共享文件夹路径,端口号是8080,匿名用户没有权限,管理员admin密码123456,完全权限。不记录log。
    #其他详细命令,请到作者页面查看。

    ExecReload=/bin/kill -HUP $MAINPID
    KillMode=process
    [Install]
    WantedBy=multi-user.target
  6. 保存上面的文件,然后
    1
    systemctl daemon-reload
  7. 启动chfs
    1
    systemctl start chfs
  8. 关闭
    1
    systemctl kill chfs
  9. 激活开机启动
    1
    systemctl enable chfs
  10. 关闭开机启动
    1
    systemctl disable chfs
  11. 从网页浏览器输入即可。
    1
    http://192.168.1.xxx:8080/

总结

以上五种协议均是基于Armbian已运行起来且联网的基础上,重新安装配置完成。但是产品化的NAS用户是不会自己配置这些协议的,所以我们需要在NAS出厂前就配置好这些文件共享协议。
思路就是在编译NAS固件之前就把这些协议移植进入根文件系统中。需要用到一个很重要的命令chroot。它会将当前目录设置为根目录。是配置根文件系统很契合的一个命令。
将在编译服务器中的Armbian SDK中的根文件系统解压,并将解压后的目录用chroot命令设置为根目录。将上述五种协议重新在此根文件目录中重新安装配置一遍即可。
然后重新压缩。将之打包进入Armbian编译的固件中,烧录到板端。烧录成功后上电,五种文件共享协议验证均可使用。