Red Hat Training

A Red Hat training course is available for Red Hat Enterprise Linux

8.6. 配置 NFS 服务器

在 NFS 服务器中配置导出的方法有两种:
  • 手动编辑 NFS 配置文件,即 /etc/exports,以及
  • 通过命令行,即使用 exportfs命令

8.6.1. /etc/exports 配置文件

/etc/exports 文件控制哪些文件系统被导出到远程主机,并指定选项。它遵循以下语法规则:
  • 空白行将被忽略。
  • 要添加注释,以井号(#)开始一行。
  • 您可以使用反斜杠(\)换行长行。
  • 每个导出的文件系统都应该独立。
  • 所有在导出的文件系统后放置的授权主机列表都必须用空格分开。
  • 每个主机的选项必须在主机标识符后直接放在括号中,没有空格分离主机和第一个括号。
导出的文件系统的每个条目都有以下结构:
export host(options)
上述结构使用以下变量:
export
导出的目录
host
导出要共享的主机或网络
options
用于 host 的选项
可以指定多个主机,以及每个主机的特定选项。要做到这一点,将它们列在与用空格分隔的列表相同的行中,每个主机名后跟其各自的选项(在括号中),如下所示:
export host1(options1) host2(options2) host3(options3)
有关指定主机名的不同方法的详情,请参考 第 8.6.5 节 “主机名格式”
在最简单的形式中,/etc/exports 文件只指定导出的目录和允许访问它的主机,如下例所示:

例 8.6. /etc/exports 文件

/exported/directory bob.example.com
在这里,bob.example.com 可以从 NFS 服务器挂载 /exported/directory/。因为在这个示例中没有指定选项,所以 NFS 将 使用默认设置
默认设置为:
ro
导出的文件系统是只读的。远程主机无法更改文件系统中共享的数据。要允许主机更改文件系统(即读写),请指定 rw 选项。
同步
在将之前的请求所做的更改写入磁盘前,NFS 服务器不会回复请求。要启用异步写入,请指定 async 选项。
wdelay
如果 NFS 服务器预期另外一个写入请求即将发生,则 NFS 服务器会延迟写入磁盘。这可以提高性能,因为它可减少不同的写命令访问磁盘的次数,从而减少写开销。要禁用此功能,请指定 no_wdelay。只有指定了默认的 sync 选项时,no_wdelay 才可用。
root_squash
这可防止远程连接的 root 用户(而不是本地)具有 root 权限;相反,NFS 服务器会为他们分配用户 ID nfsnobody这可以有效地将远程 root 用户的权限"挤压"成最低的本地用户,从而防止在远程服务器上可能的未经授权的写操作。要禁用 root 压缩,请指定 no_root_squash
要对所有远程用户(包括 root 用户)进行压缩,请使用 all_squash :要指定 NFS 服务器应该分配给来自特定主机的远程用户的用户 ID 和组 ID,请分别使用 anonuidanongid 选项,如下所示:
export host(anonuid=uid,anongid=gid)
这里,uidgid 分别是用户 ID 号和组 ID 号。anonuidanongid 选项允许您创建特殊的用户和组帐户,为远程 NFS 用户共享。
默认情况下,Red Hat Enterprise Linux 下的 NFS 支持 访问控制列表 (ACL)。要禁用此功能,在导出文件系统时请指定 no_acl 选项。
每个导出的文件系统的默认值都必须被显式覆盖。例如,如果没有指定 rw 选项,则导出的文件系统将以只读形式共享。以下是 /etc/exports 中的示例行,其覆盖两个默认选项:
/another/exported/directory 192.168.0.3 (rw,async)
在这个示例中,192.168.0.3 可以挂载 /another/exported/directory/ 读写,对磁盘的所有写入都是异步的。有关导出选项的更多信息,请参阅 man exportfs
其他选项在未指定默认值的情况下可用。这包括禁用子树检查、允许来自不安全端口的访问以及允许不安全的文件锁(对于某些早期 NFS 客户端实现是必需的)。有关这些较少使用的选项的更多信息,请参阅 man 导出
重要
/etc/exports 文件的格式要求非常精确,特别是在空格字符的使用方面。需要将导出的文件系统与主机、不同主机间使用空格分隔。但是,除了注释行外,文件中不应该包括其他空格。
例如,下面两行并不具有相同的意义:
/home bob.example.com(rw)
/home bob.example.com (rw)
第一行只允许 bob.example.com 中的用户对 /home 目录进行读写访问。第二行允许来自 bob.example.com 的用户以只读方式挂载目录(默认),而其他用户可以将其挂载为读/写。

8.6.2. exportfs 命令

使用 NFS 将每个文件系统导出到远程用户,以及这些文件系统的访问级别,均列在 /etc/exports 文件中。当 nfs 服务启动时,/usr/sbin/exportfs 命令启动并读取此文件,将控制传递给实际挂载进程的 rpc.mountd (如果 NFSv3),然后传给 rpc.nfsd,然后供远程用户使用。
手动发出时,/usr/sbin/exportfs 命令允许 root 用户有选择地导出或取消导出目录,而无需重启 NFS 服务。给定正确的选项后,/usr/sbin/exportfs 命令将导出的文件系统写入 /var/lib/nfs/xtab。由于 rpc.mountd 在决定对文件系统的访问权限时引用 xtab 文件,因此对导出的文件系统列表的更改会立即生效。
以下是 /usr/sbin/exportfs 常用的选项列表:
-r
通过在 /var/lib/nfs/etab 中构建新的导出列表,将 /etc/exports 中列出的所有目录导出。如果对 /etc/exports 做了任何更改,这个选项可以有效地刷新导出列表。
-a
根据将哪些其他选项传给 /usr/sbin/exportfs,导致所有目录被导出或取消导出。如果没有指定其他选项,/usr/sbin/exportfs 会导出 /etc/exports 中指定的所有文件系统。
-o file-systems
指定没有在 /etc/exports 中列出的要导出的目录。将 file-systems 替换为要导出的其它文件系统。这些文件系统的格式化方式必须与 /etc/exports 中指定的方式相同。此选项通常用于在将导出的文件系统永久添加到导出的文件系统列表之前,对其进行测试。有关 /etc/exports 语法的详情,请参考 第 8.6.1 节 “/etc/exports 配置文件”
-i
忽略 /etc/exports ;只有命令行上指定的选项才会用于定义导出的文件系统。
-u
不导出所有共享目录。命令 /usr/sbin/exportfs -ua 可暂停 NFS 文件共享,同时保持所有 NFS 守护进程正常运行。要重新启用 NFS 共享,请使用 exportfs -r
-v
详细操作,当执行 exportfs 命令时,更详细地显示正在导出的或取消导出的文件系统。
如果没有将选项传给 exportfs 命令,它将显示当前导出的文件系统列表。有关 exportfs 命令的详情,请参考 man exportfs

8.6.2.1. 使用带有 NFSv4 的 exportfs

在 Red Hat Enterprise Linux 7 中,不需要额外的步骤来配置 NFSv4 导出,因为上述任何文件系统都自动提供给使用相同路径的 NFSv3 和 NFSv4 客户端。在之前的版本中并非如此。
要防止客户端使用 NFSv4,请在 /etc/sysconfig/nfs 中设置 RPCNFSDARGS= -N 4 来将其关闭。

8.6.3. 在防火墙后面运行 NFS

NFS 需要 rpcbind,它可为 RPC 服务动态分配端口,并可能导致配置防火墙规则的问题。要允许客户端访问防火墙后面的 NFS 共享,请编辑 /etc/sysconfig/nfs 文件来设置 RPC 服务运行的端口。要允许客户端通过防火墙访问 RPC 配额,请参阅 第 8.6.4 节 “通过防火墙访问 RPC 配额”
默认情况下,/etc/sysconfig/nfs 文件在所有系统中都不存在。如果 /etc/sysconfig/nfs 不存在,请创建并指定以下内容:
RPCMOUNTDOPTS="-p port"
这会将"-p port"添加到 rpc.mount 命令行: rpc.mount -p port
要指定 nlockmgr 服务使用的端口,请在 /etc/modprobe.d/lockd.conf 文件中设置 nlm_tcpportnlm_udpport 选项的端口号。
如果 NFS 无法启动,请检查 /var/log/messages。通常,如果指定了已在使用的端口号,NFS 将无法启动。编辑 /etc/sysconfig/nfs 后,您需要重启 nfs-config 服务,以便新值在 Red Hat Enterprise Linux 7.2 中生效,然后再运行以下命令:
#  systemctl restart nfs-config
然后,重启 NFS 服务器:
#  systemctl restart nfs-server
运行 rpcinfo -p 以确认更改生效。
注意
要允许 NFSv4.0 回调通过防火墙设置 /proc/sys/fs/nfs/nfs_callback_tcpport,并允许服务器连接到客户端上的该端口。
NFSv4.1 或更高版本不需要这个过程,纯 NFSv4 环境中不需要 mountdstatdlockd 的其他端口。

8.6.3.1. 发现 NFS 导出

有两种方法可以发现 NFS 服务器导出了哪些文件系统。
  • 在支持 NFSv3 的任何服务器上,使用 showmount 命令:
    $ showmount -e myserver
    Export list for mysever
    /exports/foo
    /exports/bar
  • 在支持 NFSv4 的任何服务器上,挂载 根目录并查找。
    # mount myserver:/ /mnt/
    # cd /mnt/
    exports
    # ls exports
    foo
    bar
在同时支持 NFSv4 和 NFSv3 的服务器上,这两种方法都可以工作,并给出同样的结果。
注意
在较旧的 NFS 服务器上的 Red Hat Enterprise Linux 6 之前,具体取决于它们的配置方式,可以通过不同的路径将文件系统导出到 NFSv4 客户端。由于这些服务器默认没有启用 NFSv4,因此这不应有问题。

8.6.4. 通过防火墙访问 RPC 配额

如果您导出使用磁盘配额的文件系统,您可以使用配额远程过程调用(RPC)服务来给 NFS 客户端提供磁盘配额数据。

过程 8.1. 使 RPC 配额访问防火墙不可行

  1. 要启用 rpc-rquotad 服务,请使用以下命令:
    # systemctl enable rpc-rquotad 
  2. 要启动 rpc-rquotad 服务,请使用以下命令:
    # systemctl start rpc-rquotad 
    请注意,如果启用 rpc-rquotad,则自动启动 nfs-server 服务。
  3. 要使配额 RPC 服务在防火墙后面访问,需要打开 UDP 或 TCP 端口 875。默认端口号定义在 /etc/services 文件中。
    您可以通过将 -p port-number 附加到 /etc/sysconfig/rpc-rquotad 文件中的 RPCRQUOTADOPTS 变量来覆盖默认端口号。
  4. 重启 rpc-rquotad 以使 /etc/sysconfig/rpc-rquotad 文件中的更改生效:
    # systemctl restart rpc-rquotad

从远程主机设置配额

默认情况下,配额只能由远程主机读取。要允许设置配额,请将 -S 选项附加到 /etc/sysconfig/rpc-rquotad 文件中的 RPCRQUOTADOPTS 变量中。
重启 rpc-rquotad 以使 /etc/sysconfig/rpc-rquotad 文件中的更改生效:
# systemctl restart rpc-rquotad

8.6.5. 主机名格式

主机可以采用以下形式:
单台机器
完全限定域名(可由服务器解析)、主机名(可由服务器解析)或 IP 地址。
使用通配符指定的一系列机器
使用 *? 字符指定字符串匹配项。通配符不能用于 IP 地址;但是,如果反向 DNS 查找失败,则可能会意外起作用。当在完全限定域名中指定通配符时,点(.)不会包含在通配符中。例如: *.example.com 包含 one.example.com,但不包括 include one.two.example.com
IP 网络
使用 a.b.c.d/z,其中 a.b.c.d 是网络,z 是子网掩码的位数(如 192.168.0.0/24)。另一种可接受的格式是 a.b.c.d/netmask,其中 a.b.c.d 是网络,netmask 是子网掩码(例如 192.168.100.8/255.255.255.0)。
Netgroups
使用格式 @group-name ,其中 group-name 是 NIS netgroup 名称。

8.6.6. 启用通过 RDMA(NFSoRDMA) 的 NFS

如果存在支持 RDMA 的硬件,则远程直接内存访问(RDMA)服务会在 Red Hat Enterprise Linux 7 中自动工作。
通过 RDMA 启用 NFS:
  1. 安装 rdmardma-core 软件包。
    /etc/rdma/rdma.conf 文件包含默认设置 XPRTRDMA_LOAD=yes 的行,它请求 rdma 服务加载 NFSoRDMA 客户端 模块。
  2. 要启用自动载入 NFSoRDMA 服务器模块,请在 /etc/rdma/rdma.conf 中的新行中添加 SVCRDMA_LOAD=yes
    RPCNFSDARGS="--rdma=20049"/etc/sysconfig/nfs 文件中指定 NFSoRDMA 服务侦听客户端的端口号。RFC 5667 指定服务器在通过 RDMA 提供 NFSv4 服务时必须侦听端口 20049
  3. 编辑 /etc/rdma/rdma.conf 文件后重启 nfs 服务:
    # systemctl restart nfs
    请注意,在较早的内核版本中,编辑 /etc/rdma/rdma.conf 后需要重启系统才能使更改生效。

8.6.7. 配置只使用 NFSv4 的服务器

默认情况下,NFS 服务器在 Red Hat Enterprise Linux 7 中支持 NFSv2、NFSv3 和 NFSv4 连接。但是,您还可以将 NFS 配置为只支持 NFS 版本 4.0 及更新的版本。这可最小化系统上开放端口的数量和运行的服务,因为 NFSv4 不需要 rpcbind 服务来侦听网络。
当您的 NFS 服务器配置为只使用 NFSv4 时,尝试使用 NFSv2 或 NFSv3 挂载共享的客户端会失败,并显示类似如下的错误:
Requested NFS version or transport protocol is not supported.

过程 8.2. 配置只使用 NFSv4 的服务器

将您的 NFS 服务器配置为只支持 NFS 版本 4.0 及更新的版本:
  1. 通过在 /etc/sysconfig/nfs 配置文件中添加以下行来禁用 NFSv2、NFSv3 和 UDP:
    RPCNFSDARGS="-N 2 -N 3 -U"
    
  2. (可选)禁用对 RPCBINDMOUNTNSM 协议调用的监听,这在仅使用 NFSv4 的情况下不需要。
    禁用这些选项的影响有:
    • 尝试使用 NFSv2 或 NFSv3 从服务器挂载共享的客户端变得无响应。
    • NFS 服务器本身无法挂载 NFSv2 和 NFSv3 文件系统。
    禁用这些选项:
    • /etc/sysconfig/nfs 文件中添加以下内容:
      RPCMOUNTDOPTS="-N 2 -N 3"
      
    • 禁用相关服务:
      # systemctl mask --now rpc-statd.service rpcbind.service rpcbind.socket
  3. 重启 NFS 服务器:
    # systemctl restart nfs
    一旦启动或重启 NFS 服务器,这些改变就会生效。

验证仅 NFSv4 配置

您可以使用 netstat 实用程序验证您的 NFS 服务器是否在 NFSv4 模式中配置。
  • 以下是仅使用 NFSv4 服务器上的 netstat 输出示例;也禁用了对 RPCBINDMOUNTNSM 的监听。在这里,nfs 是唯一侦听 NFS 服务:
    # netstat -ltu
    
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State      
    tcp        0      0 0.0.0.0:nfs             0.0.0.0:*               LISTEN     
    tcp        0      0 0.0.0.0:ssh             0.0.0.0:*               LISTEN     
    tcp        0      0 localhost:smtp          0.0.0.0:*               LISTEN     
    tcp6       0      0 [::]:nfs                [::]:*                  LISTEN     
    tcp6       0      0 [::]:12432              [::]:*                  LISTEN     
    tcp6       0      0 [::]:12434              [::]:*                  LISTEN     
    tcp6       0      0 localhost:7092          [::]:*                  LISTEN     
    tcp6       0      0 [::]:ssh                [::]:*                  LISTEN     
    udp        0      0 localhost:323           0.0.0.0:*                          
    udp        0      0 0.0.0.0:bootpc          0.0.0.0:*                          
    udp6       0      0 localhost:323           [::]:*
    
  • 相比之下,在配置只使用 NFSv4 的服务器前 netstat 输出会包括 sunrpcmountd 服务:
    # netstat -ltu
    
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State      
    tcp        0      0 0.0.0.0:nfs             0.0.0.0:*               LISTEN     
    tcp        0      0 0.0.0.0:36069           0.0.0.0:*               LISTEN     
    tcp        0      0 0.0.0.0:52364           0.0.0.0:*               LISTEN     
    tcp        0      0 0.0.0.0:sunrpc          0.0.0.0:*               LISTEN     
    tcp        0      0 0.0.0.0:mountd          0.0.0.0:*               LISTEN     
    tcp        0      0 0.0.0.0:ssh             0.0.0.0:*               LISTEN     
    tcp        0      0 localhost:smtp          0.0.0.0:*               LISTEN     
    tcp6       0      0 [::]:34941              [::]:*                  LISTEN     
    tcp6       0      0 [::]:nfs                [::]:*                  LISTEN     
    tcp6       0      0 [::]:sunrpc             [::]:*                  LISTEN     
    tcp6       0      0 [::]:mountd             [::]:*                  LISTEN     
    tcp6       0      0 [::]:12432              [::]:*                  LISTEN     
    tcp6       0      0 [::]:56881              [::]:*                  LISTEN     
    tcp6       0      0 [::]:12434              [::]:*                  LISTEN     
    tcp6       0      0 localhost:7092          [::]:*                  LISTEN     
    tcp6       0      0 [::]:ssh                [::]:*                  LISTEN     
    udp        0      0 localhost:323           0.0.0.0:*                          
    udp        0      0 0.0.0.0:37190           0.0.0.0:*                          
    udp        0      0 0.0.0.0:876             0.0.0.0:*                          
    udp        0      0 localhost:877           0.0.0.0:*                          
    udp        0      0 0.0.0.0:mountd          0.0.0.0:*                          
    udp        0      0 0.0.0.0:38588           0.0.0.0:*                          
    udp        0      0 0.0.0.0:nfs             0.0.0.0:*                          
    udp        0      0 0.0.0.0:bootpc          0.0.0.0:*                          
    udp        0      0 0.0.0.0:sunrpc          0.0.0.0:*                          
    udp6       0      0 localhost:323           [::]:*                             
    udp6       0      0 [::]:57683              [::]:*                             
    udp6       0      0 [::]:876                [::]:*                             
    udp6       0      0 [::]:mountd             [::]:*                             
    udp6       0      0 [::]:40874              [::]:*                             
    udp6       0      0 [::]:nfs                [::]:*                             
    udp6       0      0 [::]:sunrpc             [::]:*