网络文件系统(NFS)

网络文件系统(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 包含多个独立服务,修改配置后可能难以判断应该重启哪些服务。

下表汇总了可用服务、它们关联的元服务,以及各自使用的配置文件。

服务

nfs-utils.service

nfs-server.service

配置文件

nfs-blkmap

PartOf

nfs.conf

nfs-mountd

BindsTo

nfs.conf

nfsdcld

nfs-idmapd

BindsTo

nfs.conf, idmapd.conf

rpc-gssd

PartOf

nfs.conf

rpc-statd

PartOf

nfs.conf

rpc-svcgssd

PartOf

BindsTo

nfs.conf

例如,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 检查最终设置:它会合并全部配置文件,并显示最终生效的非默认设置。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容