NFS

来自 ArchWiki

出自维基百科

网络文件系统 (NFS) 是一种分布式文件系统协议,最初由 Sun Microsystems 于 1984 年开发,允许客户端计算机上的用户通过网络访问文件,方式类似于访问本地存储。

NFS FAQ 列出了经过良好测试的文件系统,并详细说明了关于 FAT32 的限制。

提示
  • 默认情况下,NFS 未加密。配置 #TLS 加密,或配置 Kerberos (sec=krb5p 以提供基于 Kerberos 的加密),或者在处理敏感数据时,通过加密的 VPN (例如 WireGuard) 隧道传输 NFS。
  • Samba 不同,NFS 默认情况下没有任何用户身份验证,客户端访问受到其 IP 地址/主机名的限制。如果需要更强的身份验证,可以使用 Kerberos。
  • NFS 期望客户端和服务器上的 用户 和/或 用户组 ID 相同 (除非使用 Kerberos)。使用 NFSv4 idmapping 或通过在 /etc/exports 中一起使用 anonuid/anongidall_squash 手动覆盖 UID/GID。
  • NFS 不支持 POSIX ACL。NFS 服务器仍将强制执行 ACL,但客户端将无法查看或修改它们。

安装

客户端和服务器都只需要安装 nfs-utils 软件包。

强烈建议使用时间同步守护程序,以保持客户端/服务器时钟同步。如果所有节点上的时钟不准确,NFS 可能会引入不必要的延迟。

服务器配置

全局配置选项在 /etc/nfs.conf 中设置。简单配置的用户应该不需要编辑此文件。

NFS 服务器需要共享目录列表,以导出的形式 (详见 exports(5)),必须在 /etc/exports/etc/exports.d/*.exports 中定义。默认情况下,目录以其路径原样导出;例如

/etc/exports
/data/music    192.168.1.0/24(rw)

以上配置将使 /data/music 目录可以作为 MyServer:/data/music 为 NFSv3 和 NFSv4 挂载。

自定义导出根目录

共享可以相对于所谓的 NFS 根目录。一个好的安全实践是在离散目录树中定义 NFS 根目录,这将使用户仅限于该挂载点。绑定挂载用于将共享挂载点链接到 文件系统 上其他位置的实际目录。在过去,NFS 根目录对于 NFSv4 是强制性的;现在是可选的 (从内核 2.6.33 和 nfs-utils 1.2.2 开始,它们实现了虚拟根目录)。

考虑以下示例,其中:

  1. NFS 根目录是 /srv/nfs
  2. 导出是通过绑定挂载到实际目标 /mnt/music/srv/nfs/music
# mkdir -p /srv/nfs/music /mnt/music
# mount --bind /mnt/music /srv/nfs/music
注意: ZFS 文件系统需要特殊处理绑定挂载,请参阅 ZFS#绑定挂载

要使绑定挂载在重启后保持持久性,请将其添加到 fstab

/etc/fstab
/mnt/music /srv/nfs/music  none   bind   0   0

将要共享的目录添加到 /etc/exports 中,并将它们限制为允许挂载它们的客户端机器的 CIDR 或主机名范围,例如:

/etc/exports
/srv/nfs        192.168.1.0/24(rw,fsid=root)
/srv/nfs/music  192.168.1.0/24(rw,sync)
/srv/nfs/home   192.168.1.0/24(rw,sync)
/srv/nfs/public 192.168.1.0/24(ro,all_squash,insecure) desktop(rw,sync,all_squash,anonuid=99,anongid=99) # map to user/group - in this case nobody

当使用 NFSv4 时,选项 fsid=rootfsid=0 表示 “根” 导出;如果存在这样的导出,则所有其他目录必须在其下方。/etc/nfs.conf 文件中的 rootdir 选项对此没有影响。当没有 fsid=0 导出时,默认行为与 NFSv3 中的行为相同。

在上面的示例中,由于 /srv/nfs 被指定为根目录,因此导出 /srv/nfs/music 现在可以通过 NFSv4 作为 MyServer:/music 挂载 – 请注意,根前缀被省略了。

提示
  • 对于 NFSv3 (NFSv4 不需要),crossmnt 选项使客户端可以访问标记为 crossmnt 的文件系统上挂载的所有文件系统,并且客户端不需要单独挂载每个子导出。请注意,如果子导出与不同的地址范围共享,则这可能不是理想的。
  • 除了 crossmnt 之外,还可以在子导出上使用 nohide 选项,以便在客户端挂载根导出时可以自动挂载它们。与 crossmnt 不同,nohide 仍然遵守子导出的地址范围。请注意,该选项也是 NFSv3 特有的;NFSv4 始终表现得好像启用了 nohide。
  • insecure 选项允许客户端从 1023 以上的端口连接。(据推测,只有 root 用户可以使用低编号端口,因此默认情况下阻止其他端口会创建一个肤浅的访问障碍。实际上,省略或包含 insecure 选项都不会对安全性提供任何有意义的改进或损害。)
  • 使用星号 (*) 允许从任何接口访问。

应该注意的是,在服务器运行时修改 /etc/exports 将需要重新导出才能使更改生效

# exportfs -arv

要更详细地查看当前加载的导出状态,请使用

# exportfs -v

有关所有可用选项的更多信息,请参阅 exports(5)

提示: ip2cidr 是一个将 IP 地址范围转换为正确结构的 CIDR 规范的工具。
注意: 如果目标导出是 tmpfs 文件系统,则需要 fsid=1 选项。

启动服务器

  • 要同时提供 NFSv3 和 NFSv4 服务,启动启用 nfs-server.service
  • 要仅提供 NFSv4 服务,启动启用 nfsv4-server.service

协议版本 4 导出的用户可能希望屏蔽至少 rpcbind.servicerpcbind.socket,以防止多余的服务运行。请参阅 FS#76453。此外,还可以考虑屏蔽 nfs-server.service,它由于某种原因也被拉入。

注意: 如果导出 ZFS 共享,还要启动/启用 zfs-share.service。没有它,ZFS 共享将在重启后不再导出。请参阅 ZFS#NFS

限制 NFS 到指定接口/IP

默认情况下,启动 nfs-server.service 将侦听所有网络接口上的连接,而与 /etc/exports 无关。可以通过定义要侦听的 IP 和/或主机名来更改此设置。

/etc/nfs.conf
[nfsd]
host=192.168.1.123
# Alternatively, use the hostname.
# host=myhostname

重启 nfs-server.service 以立即应用更改。

防火墙配置

要通过防火墙启用对 NFSv4 服务器的访问,必须为传入连接打开 TCP 端口 2049。(NFSv4 使用静态端口号;它不使用任何辅助服务,例如 mountd 或 portmapper。)

要启用对 NFSv3 服务器的访问,您还需要为 portmapper (rpcbind) 打开 TCP/UDP 端口 111,以及 MOUNT (rpc.mountd) 端口。默认情况下,rpc.mountd 动态选择端口,因此如果您位于防火墙后面,则需要编辑 /etc/nfs.conf 以设置静态端口。使用 rpcinfo -p 检查 NFSv3 服务器上使用的确切端口

$ rpcinfo -p
100003    3   tcp   2049  nfs
100003    4   tcp   2049  nfs
100227    3   tcp   2049  nfs_acl
...

客户端配置

打算将 NFS4 与 Kerberos 一起使用的用户需要启动启用 nfs-client.target

手动挂载

对于 NFSv3,使用此命令显示服务器的导出文件系统

$ showmount -e servername

对于 NFSv4,挂载根 NFS 目录并查找可用的挂载点

# mount servername:/ /mountpoint/on/client

然后挂载时省略服务器的 NFS 导出根目录

# mount -t nfs -o vers=4 servername:/music /mountpoint/on/client

如果挂载失败,请尝试包含服务器的导出根目录 (Debian/RHEL/SLES 需要,某些发行版需要 -t nfs4 而不是 -t nfs)

# mount -t nfs -o vers=4 servername:/srv/nfs/music /mountpoint/on/client
注意: servername 需要替换为有效的主机名 (不仅仅是 IP 地址)。否则,远程共享的挂载将挂起。

使用 /etc/fstab 挂载

对于始终在线的服务器,以及客户端启动时 NFS 共享可用的情况,使用 fstab 非常有用。编辑 /etc/fstab 文件,并添加反映设置的适当行。同样,服务器的 NFS 导出根目录被省略。

/etc/fstab
servername:/music   /mountpoint/on/client   nfs   defaults,timeo=900,retrans=5,_netdev	0 0
注意: 有关更多挂载选项,请查阅 nfs(5)mount(8)

一些需要考虑的附加挂载选项

rsize 和 wsize
rsize 值是从服务器读取时使用的字节数。wsize 值是写入服务器时使用的字节数。默认情况下,如果未指定这些选项,则客户端和服务器会协商它们都可以支持的最大值 (详见 nfs(5))。更改这些值后,建议测试性能 (请参阅 #性能调优)。
soft 或 hard
确定 NFS 请求超时后 NFS 客户端的恢复行为。如果未指定任何选项 (或者如果指定了 hard 选项),则会无限期地重试 NFS 请求。如果指定了 soft 选项,则 NFS 客户端在发送 retrans 次重传后会使 NFS 请求失败,从而导致 NFS 客户端向调用应用程序返回错误。
警告: 所谓的 soft 超时在某些情况下可能会导致静默数据损坏。因此,仅当客户端响应能力比数据完整性更重要时才使用 soft 选项。通过 TCP 使用 NFS 或增加 retrans 选项的值可能会减轻使用 soft 选项的一些风险。
timeo
timeo 值是以十分之一秒为单位的时间量,在 RPC 超时后,等待重新发送传输之前的时间。通过 TCP 进行 NFS 的默认值为 600 (60 秒)。在第一次超时后,超时值在每次重试时加倍,最大为 60 秒或直到发生主要超时。如果连接到速度较慢的服务器或通过繁忙的网络连接,则可以通过增加此超时值来获得更好的稳定性。
retrans
NFS 客户端在尝试进一步恢复操作之前重试请求的次数。如果未指定 retrans 选项,则 NFS 客户端会尝试每个请求三次。NFS 客户端在 retrans 次重试后生成 “服务器未响应” 消息,然后尝试进一步恢复 (取决于 hard 挂载选项是否生效)。
_netdev
_netdev 选项告诉系统在尝试挂载共享之前等待网络启动 - systemd 为 NFS 假定了这一点。
注意: 将第六个字段 (fs_passno) 设置为非零值可能会导致意外行为,例如,当 systemd automount 等待永远不会发生的检查时发生挂起。

使用带有 systemd 的 /etc/fstab 挂载

另一种方法是使用 x-systemd.automount 选项,该选项在访问时挂载文件系统

/etc/fstab
servername:/home   /mountpoint/on/client  nfs  _netdev,noauto,x-systemd.automount,x-systemd.mount-timeout=10,timeo=14,x-systemd.idle-timeout=1min 0 0

为了使 systemd 意识到对 fstab 的更改,重新加载 systemd 并重启 remote-fs.target [1]

此文章或章节的准确性存在争议。

理由: 并非每个人都使用 NetworkManager。请参考 Systemd#在网络启动后运行服务?(在 Talk:NFS 中讨论)
提示
  • noauto 挂载选项将不会挂载 NFS 共享,直到它被访问:使用 auto 使其立即可用。
    如果遇到由于网络未启动/不可用而导致挂载失败的任何问题,请启用 NetworkManager-wait-online.service。它将确保 network.target 在激活之前拥有所有可用的链接。
  • users 挂载选项将允许用户挂载,但请注意,它暗示了更多选项,例如 noexec
  • x-systemd.idle-timeout=1min 选项将在未使用 1 分钟后自动卸载 NFS 共享。适用于可能突然断开网络连接的笔记本电脑。
  • 如果由于 NFS 导致关机/重启时间过长,请启用 NetworkManager-wait-online.service 以确保在卸载 NFS 卷之前 NetworkManager 不会退出。
  • 不要添加 x-systemd.requires=network-online.target 挂载选项,因为这可能会导致 systemd 内的排序循环 [2]。systemd 会自动将 network-online.target 依赖项添加到 _netdev 挂载的单元。
  • 使用 nocto 选项可以提高只读挂载的性能,但仅应在服务器上的数据仅偶尔更改时使用。

作为 systemd 单元

/etc/systemd/system 中创建一个新的 .mount 文件,例如 mnt-home.mount。有关详细信息,请参阅 systemd.mount(5)

注意: 确保文件名与您要使用的挂载点相对应。例如,单元名称 mnt-home.mount 只能在您要将共享挂载在 /mnt/home 下时使用。否则,可能会发生以下错误:systemd[1]: mnt-home.mount: Where= setting does not match unit name. Refusing.。如果挂载点包含非 ASCII 字符,请使用 systemd-escape)。

What= 共享路径

Where= 共享挂载路径

Options= 共享挂载选项

提示
  • 网络挂载单元自动获取对 remote-fs-pre.targetnetwork.targetnetwork-online.targetAfter 依赖项,并获得对 remote-fs.targetBefore 依赖项,除非设置了 nofail 挂载选项。对于后者,还会添加一个 Wants 单元。
  • 附加 noautoOptions 以防止在启动期间自动挂载 (除非它被其他单元拉入)。
  • 如果您想使用要共享的服务器的主机名 (而不是 IP 地址),请将 nss-lookup.target 添加到 After。这可以避免启动时出现的挂载错误,这些错误在测试单元时不会出现。
/etc/systemd/system/mnt-home.mount
[Unit]
Description=Mount home at boot

[Mount]
What=172.16.24.192:/home
Where=/mnt/home
Options=vers=4
Type=nfs
TimeoutSec=30

[Install]
WantedBy=multi-user.target
提示: 如果系统无法访问,请附加 ForceUnmount=true[Mount],允许 (强制) 卸载导出。

要使用 mnt-home.mount启动该单元并启用它以在系统启动时运行。

自动挂载

要自动挂载共享,可以使用以下自动挂载单元

/etc/systemd/system/mnt-home.automount
[Unit]
Description=Automount home

[Automount]
Where=/mnt/home

[Install]
WantedBy=multi-user.target

禁用/停止 mnt-home.mount 单元,并启用/启动 mnt-home.automount 以在访问挂载路径时自动挂载共享。

提示: 附加 TimeoutIdleSec 以启用自动卸载。有关详细信息,请参阅 systemd.automount(5)

使用 autofs 挂载

当多台计算机想要通过 NFS 连接时,使用 autofs 非常有用;它们既可以是客户端也可以是服务器。此方法优于早期方法的原因是,如果服务器关闭,客户端不会抛出关于无法找到 NFS 共享的错误。有关详细信息,请参阅 autofs#NFS 网络挂载

技巧与诀窍

NFSv4 idmapping

此文章或章节需要语言、wiki 语法或风格方面的改进。请参阅 Help:Style 以获取参考。

理由: 说明过于复杂。客户端和服务器配置的单独章节比 “客户端不需要启用/启动 nfs-idmapd.service” 或 “不要将 nfsidmap (仅适用于 nfs 客户端) 与 nfs-idmapd.service 混淆” 之类的注释更好。(在 Talk:NFS 中讨论)

此文章或章节需要扩展。

理由: 缺少查找信息、静态绑定示例等。(在 Talk:NFS 中讨论)
提示
  • NFSv4 idmapping 并未解决默认 sec=sys 挂载选项的所有问题。请参阅 #静态映射[3]
  • 需要在客户端和服务器两者上启用 NFSv4 idmapping。
  • 另一种选择是确保客户端和服务器上的用户和组 ID (UID 和 GID) 匹配。
  • 启用/启动 nfs-idmapd.service 不是客户端运行所必需的,因为它已被新的 ID 映射器取代
# dmesg | grep id_resolver
[ 3238.356001] NFS: Registering the id_resolver key type
[ 3238.356009] Key type id_resolver registered
提示
  • 不要将 nfsidmap (仅适用于 nfs 客户端) 与 NFS 服务器使用的并派生进程 rpc.idmapdnfs-idmapd.service 混淆。
  • rpc.idmapd 和 nfsidmap 也共享来自 idmapd.conf(5) 的一些配置。
  • 有关详细信息,请参阅 idmapd(8)nfsidmap(8)

NFSv4 协议在线路上将本地系统的 UID 和 GID 值表示为 user@domain 形式的字符串。从 UID 转换为字符串以及从字符串转换为 UID 的过程称为 ID 映射

提示
  • 默认情况下,字符串的域部分是系统的 DNS 域名。如果系统是多宿主的,或者系统的 DNS 域名与系统的 Kerberos realm 的名称不匹配,也可以在 /etc/idmapd.conf 中指定它。
  • 当未在 /etc/idmapd.conf 中指定域时,将查询本地 DNS 服务器以获取 _nfsv4idmapdomain 文本记录。如果记录存在,则将使用该记录作为域。当记录不存在时,将使用 DNS 域的域部分。

在 stdout 上显示系统的有效 NFSv4 域名。

# nfsidmap -d
domain.tld

编辑以匹配服务器和/或客户端上的域

/etc/idmapd.conf
[General]
Domain = guestdomain.tld


静态映射

提示
  • 此映射仅供客户端在本地映射 uid 使用。如果您创建一个由服务器上未知的 uid (例如 1005) 拥有的文件。该文件以 uid 1005 存储在服务器上,但不再以正确的 uid “在线路上传输” 显示。
  • 您可以在与服务器交互后 (即列出文件) 查看密钥环中的所有条目
# nfsidmap -l
7 .id_resolver keys found:
 uid:nobody
 user:1
 uid:bin@domain.tld
 uid:foo@domain.tld
 gid:foo@domain.tld
 uid:remote_user@domain.tld
 uid:root@domain.tld
  • 您可以使用 nfsidmap -c 清除密钥环,但这不是必需的,在默认设置中,10 分钟后条目过期。

只有当服务器和客户端具有不同的用户/组名称时,才需要这些步骤。更改仅在客户端配置文件中完成。

/etc/idmapd.conf
[Translation]
# The default is nsswitch and other methods exist.
method = static,nsswitch

[Static]
foo@domain.tld = local_foo
remote_user@domain.tld = user


回退映射

仅在客户端配置中。当无法完成映射时要使用的本地用户/组名称

/etc/idmapd.conf
[Mapping]
Nobody-User = nobody
Nobody-Group = nobody

性能调优

此文章或章节已过时。

理由: 提及 32 位和 2.6 Linux 内核... (在 Talk:NFS 中讨论)

当在具有大量客户端的网络上使用 NFS 时,可以将默认 NFS 线程从 8 增加到 16 甚至更高,具体取决于服务器/网络要求

/etc/nfs.conf
[nfsd]
threads=16

可能需要调整 rsizewsize 挂载选项以满足网络配置的要求。

在最新的 Linux 内核 (>2.6.18) 中,NFS 服务器允许的 I/O 操作大小 (默认最大块大小) 因 RAM 大小而异,最大为 1M (1048576 字节),即使 nfs 客户端需要更大的 rsizewsize,也将使用服务器的最大块大小。请参阅 https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/5.8_technical_notes/known_issues-kernel 可以通过在启动 nfsd 之前写入 /proc/fs/nfsd/max_block_size 来更改服务器允许的默认最大块大小。例如,以下命令恢复以前的默认 iosize 32k

# echo 32768 > /proc/fs/nfsd/max_block_size
注意: 这主要适用于处理大量 nfsd 线程的 32 位服务器。降低 max_block_size 可能会降低现代硬件上的 NFS 性能。

要使更改永久生效,请创建一个 systemd-tmpfile

/etc/tmpfiles.d/nfsd-block-size.conf
w /proc/fs/nfsd/max_block_size - - - - 32768

要使用增加的 rsizewsize 挂载选项进行挂载

# mount -t nfs -o rsize=32768,wsize=32768,vers=4 servername:/srv/nfs/music /mountpoint/on/client

此外,尽管违反了 NFS 协议,但设置 async 而不是 syncsync,no_wdelay 可能会潜在地实现显着的性能提升,尤其是在旋转磁盘上。使用此选项配置导出,然后执行 exportfs -arv 以应用。

/etc/exports
/srv/nfs        192.168.1.0/24(rw,async,crossmnt,fsid=0)
/srv/nfs/music  192.168.1.0/24(rw,async)
警告: 如果服务器崩溃或未干净地重启,使用 async 会带来可能的数据丢失或损坏的风险。

自动挂载处理

此技巧对于 无线 网络和/或可能不可靠的网络上的 NFS 共享非常有用。如果 NFS 主机变得不可访问,则将卸载 NFS 共享,以期在使用 hard 挂载选项时防止系统挂起 [4]

确保在 fstab 中正确指示了 NFS 挂载点

/etc/fstab
lithium:/mnt/data           /mnt/data	        nfs noauto 0 0
lithium:/var/cache/pacman   /var/cache/pacman	nfs noauto 0 0
提示
  • 为了使此功能正常工作,请在 fstab 中使用主机名,而不是 IP 地址。
  • 为了使用非 root 用户挂载 NFS 共享,必须添加 users 选项。
  • noauto 挂载选项告诉 systemd 在启动时不要自动挂载共享,否则可能会导致启动过程停滞。

创建 auto_share 脚本,该脚本将由 cronsystemd/Timers 使用,以使用 ICMP ping 检查 NFS 主机是否可访问

/usr/local/bin/auto_share
#!/bin/bash

function net_umount {
  umount -l -f $1 &>/dev/null
}

function net_mount {
  mountpoint -q $1 || mount $1
}

NET_MOUNTS=$(sed -e '/^.*#/d' -e '/^.*:/!d' -e 's/\t/ /g' /etc/fstab | tr -s " ")$'\n'b

printf %s "$NET_MOUNTS" | while IFS= read -r line
do
  SERVER=$(echo $line | cut -f1 -d":")
  MOUNT_POINT=$(echo $line | cut -f2 -d" ")

  # Check if server already tested
  if [[ "${server_ok[@]}" =~ "${SERVER}" ]]; then
    # The server is up, make sure the share are mounted
    net_mount $MOUNT_POINT
  elif [[ "${server_notok[@]}" =~ "${SERVER}" ]]; then
    # The server could not be reached, unmount the share
    net_umount $MOUNT_POINT
  else
    # Check if the server is reachable
    ping -c 1 "${SERVER}" &>/dev/null

    if [ $? -ne 0 ]; then
      server_notok[${#server_notok[@]}]=$SERVER
      # The server could not be reached, unmount the share
      net_umount $MOUNT_POINT
    else
      server_ok[${#server_ok[@]}]=$SERVER
      # The server is up, make sure the share are mounted
      net_mount $MOUNT_POINT
    fi
  fi
done
注意: 测试时使用 TCP 探测代替 ICMP ping(NFS4 中的默认端口为 tcp 端口 2049),然后替换行
# Check if the server is reachable
ping -c 1 "${SERVER}" &>/dev/null

# Check if the server is reachable
timeout 1 bash -c ": < /dev/tcp/${SERVER}/2049"
在上面的 auto_share 脚本中。

确保脚本是可执行的

接下来检查配置脚本以每 X 分钟运行一次,在下面的示例中,这是每分钟一次。

Cron

# crontab -e
* * * * * /usr/local/bin/auto_share

systemd/Timers

/etc/systemd/system/auto_share.timer
[Unit]
Description=Automount NFS shares every minute

[Timer]
OnCalendar=*-*-* *:*:00

[Install]
WantedBy=timers.target
/etc/systemd/system/auto_share.service
[Unit]
Description=Automount NFS shares
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/auto_share

[Install]
WantedBy=multi-user.target

最后,启用启动 auto_share.timer

使用 NetworkManager 调度器

NetworkManager 也可以配置为在网络状态更改时运行脚本。

在网络状态更改时挂载共享的最简单方法是符号链接 auto_share 脚本

# ln -s /usr/local/bin/auto_share /etc/NetworkManager/dispatcher.d/30-nfs.sh

但是,在那种特殊情况下,卸载只会在网络连接已被禁用后发生,这是不干净的,并可能导致诸如 KDE Plasma 小部件冻结之类的影响。

以下脚本通过监听 downpre-downvpn-pre-down 事件,在相关网络连接被禁用之前安全地卸载 NFS 共享,确保脚本是可执行的

/etc/NetworkManager/dispatcher.d/30-nfs.sh
#!/bin/sh

# Find the connection UUID with "nmcli con show" in terminal.
# All NetworkManager connection types are supported: wireless, VPN, wired...
WANTED_CON_UUID="CHANGE-ME-NOW-9c7eff15-010a-4b1c-a786-9b4efa218ba9"

if [ "$CONNECTION_UUID" = "$WANTED_CON_UUID" ]; then
    
    # Script parameter $1: network interface name, not used
    # Script parameter $2: dispatched event
    
    case "$2" in
        "up")
            mount -a -t nfs4,nfs 
            ;;
        "down"|"pre-down"|"vpn-pre-down")
            umount -l -a -t nfs4,nfs -f >/dev/null
            ;;
    esac
fi
注意: 此脚本忽略带有 noauto 选项的挂载,删除此挂载选项或使用 auto 以允许调度器管理这些挂载。

/etc/NetworkManager/dispatcher.d/pre-down 中创建一个符号链接以捕获 pre-down 事件

# ln -s /etc/NetworkManager/dispatcher.d/30-nfs.sh /etc/NetworkManager/dispatcher.d/pre-down.d/30-nfs.sh

TLS 加密

从 Linux 6.5 开始,可以使用 TLS 加密 NFS 流量,使用 xprtsec=tls 挂载选项。首先,在客户端和服务器上安装 ktls-utilsAUR 软件包,并按照以下配置步骤分别进行配置。

服务器

创建一个私钥并获取一个包含您的服务器 DNS 名称的证书(详见 传输层安全)。这些文件不需要添加到系统的信任存储中。

注意: 当前不支持使用也已加密的自签名证书,这将导致挂载失败。

编辑 /etc/tlshd.conf 以使用这些文件,使用您自己的 x509.certificatex509.private_key

/etc/tlshd.conf
[authenticate.server]
x509.certificate= /etc/nfsd-certificate.pem
x509.private_key= /etc/nfsd-private-key.pem

现在启动启用 tlshd.service

客户端

将上一步中生成的服务器 TLS 证书添加到系统的信任存储中(详见 传输层安全 以了解更多详细信息)。

启动启用 tlshd.service

现在您应该能够使用服务器的 DNS 名称挂载服务器

# mount -o xprtsec=tls servername.domain:/ /mountpoint/on/client

检查客户端上的 journalctl 应该显示 TLS 握手成功

$ journalctl -b -u tlshd.service
Sep 28 11:14:46 client tlshd[227]: Built from ktls-utils 0.10 on Sep 26 2023 14:24:03
Sep 28 11:15:37 client tlshd[571]: Handshake with servername.domain (192.168.122.100) was successful

故障排除

有一篇专门的文章 NFS/故障排除

参见