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,请分别使用 anonuid
和 anongid
选项,如下所示:
export host(anonuid=uid,anongid=gid)
这里,uid 和 gid 分别是用户 ID 号和组 ID 号。
anonuid
和 anongid
选项允许您创建特殊的用户和组帐户,为远程 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_tcpport
和 nlm_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 环境中不需要
mountd
、statd
和 lockd
的其他端口。
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 配额访问防火墙不可行
- 要启用
rpc-rquotad
服务,请使用以下命令:#
systemctl enable rpc-rquotad - 要启动
rpc-rquotad
服务,请使用以下命令:#
systemctl start rpc-rquotadrpc-rquotad
,则自动启动nfs-server
服务。 - 要使配额 RPC 服务在防火墙后面访问,需要打开 UDP 或 TCP 端口
875
。默认端口号定义在/etc/services
文件中。您可以通过将-p port-number
附加到/etc/sysconfig/rpc-rquotad
文件中的RPCRQUOTADOPTS
变量来覆盖默认端口号。 - 重启
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:
- 安装 rdma 和 rdma-core 软件包。
/etc/rdma/rdma.conf
文件包含默认设置XPRTRDMA_LOAD=yes
的行,它请求rdma
服务加载 NFSoRDMA 客户端 模块。 - 要启用自动载入 NFSoRDMA 服务器模块,请在
/etc/rdma/rdma.conf
中的新行中添加SVCRDMA_LOAD=yes
。RPCNFSDARGS="--rdma=20049"
在/etc/sysconfig/nfs
文件中指定 NFSoRDMA 服务侦听客户端的端口号。RFC 5667 指定服务器在通过 RDMA 提供 NFSv4 服务时必须侦听端口20049
。 - 编辑
/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 及更新的版本:
- 通过在
/etc/sysconfig/nfs
配置文件中添加以下行来禁用 NFSv2、NFSv3 和 UDP:RPCNFSDARGS="-N 2 -N 3 -U"
- (可选)禁用对
RPCBIND
、MOUNT
和NSM
协议调用的监听,这在仅使用 NFSv4 的情况下不需要。禁用这些选项的影响有:- 尝试使用 NFSv2 或 NFSv3 从服务器挂载共享的客户端变得无响应。
- NFS 服务器本身无法挂载 NFSv2 和 NFSv3 文件系统。
禁用这些选项:- 在
/etc/sysconfig/nfs
文件中添加以下内容:RPCMOUNTDOPTS="-N 2 -N 3"
- 禁用相关服务:
#
systemctl mask --now rpc-statd.service rpcbind.service rpcbind.socket
- 重启 NFS 服务器:
#
systemctl restart nfs一旦启动或重启 NFS 服务器,这些改变就会生效。
验证仅 NFSv4 配置
您可以使用
netstat
实用程序验证您的 NFS 服务器是否在 NFSv4 模式中配置。
- 以下是仅使用 NFSv4 服务器上的
netstat
输出示例;也禁用了对RPCBIND
、MOUNT
和NSM
的监听。在这里,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
输出会包括sunrpc
和mountd
服务:#
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 [::]:*