网络文件系统(NFS)
NFS 允许系统通过网络与其他系统共享目录和文件。使用 NFS,用户和程序访问远程系统中的文件时,体验几乎与访问本地文件相同。
NFS 的几个主要优点包括:
-
本地工作站所需的磁盘空间更少,因为常用数据可以集中存放在一台机器上,其他机器仍可通过网络访问。
-
用户不必在每台网络机器上分别维护主目录。可以在 NFS 服务器设置主目录,再让整个网络使用。
-
软盘、CD-ROM 光驱、USB 闪存盘等存储设备可以供网络中的其他机器使用,从而减少整个网络需要配备的可移动介质驱动器数量。
安装
在终端提示符下运行以下命令,安装 NFS 服务器:
sudo apt install nfs-kernel-server
要启动 NFS 服务器,可以在终端运行:
sudo systemctl start nfs-kernel-server.service
配置
将目录加入 /etc/exports 文件,即可配置要导出的目录。例如:
/srv *(ro,sync,subtree_check)
/home *.hostname.com(rw,sync,no_subtree_check)
/scratch *(rw,async,no_subtree_check,no_root_squash)
确认所有新增的自定义挂载点已经创建;/srv 和 /home 通常已存在:
sudo mkdir /scratch
使用以下命令应用新配置:
sudo exportfs -a
可以用一种主机名格式替换 *。应尽量精确地声明主机名,避免不需要的系统访问 NFS 挂载。注意,*.hostname.com 会匹配 foo.hostname.com 及其全部子域,因为 * 也会匹配点号。
sync 和 async 控制是否保证在响应请求前将修改提交到稳定存储。async 可以提高性能,但有数据丢失或损坏的风险。某些旧版 exportfs 会在未指定该选项时发出警告。
subtree_check 与 no_subtree_check 用于启用或关闭一项安全检查,确认客户端试图挂载的导出文件系统子目录确实在其权限范围内。这种检查会影响某些场景的性能,例如经常重命名文件的主目录。只读文件系统更适合启用 subtree_check。某些旧版本的 exportfs 会在未指定此选项时发出警告。 (filesystem)
NFS 挂载还有多种可选设置,用于调整性能、加强安全或提供便利。每项设置都有相应取舍,应根据具体场景谨慎使用。例如,no_root_squash 允许任意客户端系统的 root 用户修改由 root 拥有的文件,虽然方便,但在允许共享挂载点上存在可执行文件的多用户环境中,可能造成安全问题。
该配置文件的细节见 exports(5) 手册页。
配置 NFS 客户端
要在客户端系统启用 NFS 支持,在终端运行:
sudo apt install nfs-common
使用 mount 命令挂载另一台机器共享的 NFS 目录,命令形式如下:
sudo mkdir /opt/example
sudo mount example.hostname.com:/srv /opt/example
另一种方式是在 /etc/fstab 中添加一行。该行必须指定 NFS 服务器的主机名、服务器导出的目录,以及本地用于挂载该共享的目录。
/etc/fstab 中这一行的一般语法如下:
example.hostname.com:/srv /opt/example nfs
修改 /etc/fstab 后,需要通知 systemd 配置发生了变化,否则尝试挂载时会收到以下警告:
mount: (hint) your fstab has been modified, but systemd still uses
the old version; use 'systemctl daemon-reload' to reload.
因此,请执行:
sudo systemctl daemon-reload
高级配置
NFS 在服务器端和客户端都由多个服务组成。每个服务可以有自己的默认配置;所安装的 Ubuntu Server 版本不同,配置所在的文件和使用的语法也可能不同。
全部 NFS 相关服务读取统一的配置文件 /etc/nfs.conf。该文件使用 INI 风格语法,详情见 nfs.conf(5)。此外,/etc/nfs.conf.d 目录可以包含 *.conf 片段,用来覆盖前面片段或主配置文件 nfs.conf 中的设置。
新的命令行工具 nfsconf(8) 可以查询甚至设置 nfs.conf 中的参数。尤其是 --dump 参数,可以显示合并 /etc/nfs.conf.d/*.conf 全部修改之后的有效配置。
重启 NFS 服务
由于 NFS 包含多个独立服务,修改配置后可能难以判断应该重启哪些服务。
下表汇总了可用服务、它们关联的元服务,以及各自使用的配置文件。
|
服务 |
|
|
配置文件 |
|---|---|---|---|
|
|
PartOf |
|
|
|
|
BindsTo |
|
|
|
|
|||
|
|
BindsTo |
|
|
|
|
PartOf |
|
|
|
|
PartOf |
|
|
|
|
PartOf |
BindsTo |
|
例如,systemctl restart nfs-server.service 会重启 nfs-mountd、nfs-idmapd,以及正在运行的 rpc-svcgssd。重启 nfs-utils.service 则会重启 nfs-blkmap、rpc-gssd、rpc-statd 和 rpc-svcgssd。
当然,仍然可以用常规的 systemctl restart <service> 单独重启各个服务。
NFS 软件包提供的各种 systemd 单元,详见 nfs.systemd(7) 手册页。
将 NFS 与 Kerberos 配合使用
Kerberos 可以在 NFS 之上增加一层安全保护:既可仅提供更强的身份验证机制,也可用来对 NFS 流量进行签名和加密。
本节假设你已经搭建 Kerberos 服务器,并且 KDC 和管理服务正在运行。搭建方法见 Ubuntu Server 指南的其他章节。
使用 Kerberos 的 NFS 服务器
NFS 服务器仍需要常规的 nfs-kernel-server 软件包及其依赖,同时还需要安装 Kerberos 软件包。严格说,Kerberos 软件包并非必需,因为可以从 KDC 复制所需密钥,但安装它们会方便很多。
本例采用以下设置:
-
DNS 域为
.vms。 -
Kerberos realm 为
VMS。 -
NFS 服务器为
nfs-server.vms。 -
NFS 客户端为
nfs-client.vms。 -
ubuntu/admin主体在 KDC 上拥有管理权限。
请根据实际环境调整这些名称。
首先安装 krb5-user 软件包:
sudo apt install krb5-user
然后使用具备管理权限的主体,为 NFS 服务器创建密钥:
kadmin -p ubuntu/admin -q "addprinc -randkey nfs/nfs-server.vms"
将密钥提取到本地 keytab:
sudo kadmin -p ubuntu/admin -q "ktadd nfs/nfs-server.vms"
Authenticating as principal ubuntu/admin with password.
Password for ubuntu/admin@VMS:
Entry for principal nfs/nfs-server.vms with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
Entry for principal nfs/nfs-server.vms with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
确认密钥可用:
sudo klist -k
Keytab name: FILE:/etc/krb5.keytab
KVNO Principal
---- --------------------------------------------------------------------------
2 nfs/nfs-server.vms@VMS
2 nfs/nfs-server.vms@VMS
现在安装 NFS 服务器:
sudo apt install nfs-kernel-server
由于 /etc/krb5.keytab 已存在,安装过程会自动启动与 Kerberos 相关的 NFS 服务。
如果之前已经安装该软件包,此次只是首次启用 Kerberos,则应在此时重启 NFS 服务,使 Kerberos 相关的 NFS 服务也启动:
sudo systemctl restart nfs-server
接下来填写 /etc/exports,将导出限制为使用 krb5 身份验证。例如,用 krb5p 导出 /storage:
/storage *(rw,sync,no_subtree_check,sec=krb5p)
刷新导出配置:
sudo exportfs -rav
exporting *:/storage
安全选项详见 exports(5) 手册页,大致如下:
-
krb5:仅使用 Kerberos 进行身份验证,非认证流量以明文传输。 -
krb5i:使用 Kerberos 进行身份验证和完整性检查,非认证流量仍为明文。 -
krb5p:使用 Kerberos 进行身份验证、完整性检查和隐私保护,非认证流量也会加密。
使用 Kerberos 的 NFS 客户端
客户端的步骤类似。首先准备客户端的 keytab,这样安装 NFS 客户端软件包时,系统就能通过检测 keytab 的存在,自动启动额外的 Kerberos 服务:
sudo apt install krb5-user
要让 root 用户无需密码即可通过 Kerberos 挂载 NFS 共享,必须为 NFS 客户端创建一个主机密钥:
kadmin -p ubuntu/admin -q "addprinc -randkey host/nfs-client.vms"
再提取该密钥:
sudo kadmin -p ubuntu/admin -q "ktadd host/nfs-client.vms"
现在安装 NFS 客户端软件包:
sudo apt install nfs-common
如果之前已经安装该软件包,此次只是首次启用 Kerberos,则应在此时重启 NFS 服务,让 Kerberos 相关服务也启动:
sudo systemctl restart nfs-client.target
现在应该可以执行第一次 NFS Kerberos 挂载:
sudo mount nfs-server:/storage /mnt
这种配置使用所谓的机器凭据,因此上述挂载命令在没有 Kerberos 票据时也能工作。klist 会显示当前没有票据:
# mount nfs-server:/storage /mnt
# ls -l /mnt/*
-rw-r--r-- 1 root root 0 Apr 5 14:50 /mnt/hello-from-nfs-server.txt
# klist
klist: No credentials cache found (filename: /tmp/krb5cc_0)
注意,上面的操作以 root 身份执行。接下来尝试以 ubuntu 用户访问已有挂载,并且不先获取 Kerberos 票据:
# sudo -u ubuntu -i
$ ls -l /mnt/*
ls: cannot access '/mnt/*': Permission denied
ubuntu 用户只有获得 Kerberos 票据后才能访问该挂载:
kinit
Password for ubuntu@VMS:
ls -l /mnt/*
-rw-r--r-- 1 root root 0 Apr 5 14:50 /mnt/hello-from-nfs-server.txt
此时不仅有 TGT,还有 NFS 服务的票据:
klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: ubuntu@VMS
Valid starting Expires Service principal
04/05/22 17:48:50 04/06/22 03:48:50 krbtgt/VMS@VMS
renew until 04/06/22 17:48:48
04/05/22 17:48:52 04/06/22 03:48:50 nfs/nfs-server.vms@
renew until 04/06/22 17:48:48
Ticket server: nfs/nfs-server.vms@VMS
root 用户挂载时使用机器凭据有一个缺点:文件系统必须保存持久秘密,即 /etc/krb5.keytab。有些环境不允许这样保存持久秘密。替代方案是使用 rpc.gssd 的 -n 选项。rpc.gssd(8) 对它的说明如下:
-
-n:指定此选项后,UID 0 必须获取用户凭据,用它替代本地系统的机器凭据。
启用这个选项并重启 rpc.gssd 后,即使 root 用户也需要先获得 Kerberos 票据,才能执行 NFS Kerberos 挂载。
该选项通过 /etc/nfs.conf 的 [gssd] 小节控制:
[gssd]
use-machine-creds=0
使用 sudo systemctl restart rpc-gssd.service 重启服务后,root 用户也必须先获取票据,才能挂载 NFS Kerberos 共享。
从 Ubuntu 20.04 LTS 及更早版本升级
早期 Ubuntu 版本通过传统的 /etc/default 配置文件机制配置 NFS 服务,主要用于调整传给各守护进程的命令行选项。原文将目录写作 /etc/defaults/,并列出 /etc/default/nfs-common 和 /etc/default/nfs/kernel-server;后一处路径存在笔误,通常对应 /etc/default/nfs-kernel-server。
每个文件都对可用设置作了简短解释。
Ubuntu 22.04 LTS(Jammy)及后续版本为 NFS 软件包采用了新的配置格式:不再由启动脚本读取多个 /etc/default/nfs-* 文件,而是使用一个位于 /etc/nfs.conf 的主配置文件,语法为 INI 风格。
从 Ubuntu 20.04 LTS(Focal)或更早版本升级时,会发生以下情况:
-
安装默认的
/etc/nfs.conf配置文件。 -
如果
/etc/default/nfs-*文件被修改过,转换脚本会运行,并将本地修改写入/etc/nfs.conf.d/local.conf。
如果转换脚本失败,软件包安装也会失败。例如,/etc/default/nfs-* 文件包含转换脚本无法处理的选项,或者存在语法错误。遇到这种情况,请向 nfs-utils 软件包提交缺陷报告。 (file a bug for the nfs-utils package)
可以手动运行转换工具以获得更多错误信息。该工具位于 /usr/share/nfs-common/nfsconvert.py,必须以 root 身份运行。
如果一切顺利——大多数情况下应当如此——系统会在 /etc/nfs.conf 中保留默认设置,在 /etc/nfs.conf.d/local.conf 中保留修改。可以手动合并这两个文件后删除 local.conf,也可以维持现状。请记住,/etc/nfs.conf 并不是全部配置;还应检查 /etc/nfs.conf.d,因为其中的文件可能覆盖默认值。
随时可以运行 nfsconf --dump 检查最终设置:它会合并全部配置文件,并显示最终生效的非默认设置。











暂无评论内容