CentOS 7 NFS设置

CentOS 7使用systemctl管理和设置NFS,以下按照服务端和客户端设置分别介绍。

设置Linux服务端

将移动硬盘挂载到 /data 目录

mount /dev/sdb1 /data

使用以下命令安装 NFS 支持

yum install nfs-utils

设置nfs相关服务在操作系统启动时启动

systemctl enable rpcbind
systemctl enable nfs-server
systemctl enable nfs-lock
systemctl enable nfs-idmap

启动nfs服务

systemctl start rpcbind
systemctl start nfs-server
systemctl start nfs-lock
systemctl start nfs-idmap

服务器端设置NFS卷输出,即编辑 /etc/exports 添加:

/data    192.168.122.0/24(rw,sync,no_root_squash,no_subtree_check)

/data – 共享目录

192.168.122.0/24/24 – 允许访问NFS的客户端IP地址段(这里使用是针对libvirt虚拟化NAT网段)

rw – 允许对共享目录进行读写

sync – 实时同步共享目录

no_root_squash – 允许root访问

no_all_squash - 允许用户授权

no_subtree_check - 如果卷的一部分被输出,从客户端发出请求文件的一个常规的调用子目录检查验证卷的相应部分。如果是整个卷输出,禁止这个检查可以加速传输。

no_subtree_check - If only part of a volume is exported, a routine called subtree checking verifies that a file that is requested from the client is in the appropriate part of the volume. If the entire volume is exported, disabling this check will speed up transfers. Setting Up an NFS Server

NFS服务器排查

启动 nfs-server 时候报错

# systemctl start nfs-server
Job for nfs-server.service failed. See 'systemctl status nfs-server.service' and 'journalctl -xn' for details.

# systemctl status nfs-server.service
nfs-server.service - NFS server and services
Loaded: loaded (/usr/lib/systemd/system/nfs-server.service; enabled)
Active: failed (Result: exit-code) since Wed 2015-09-16 16:54:14 CST; 51s ago
Process: 17476 ExecStartPre=/usr/sbin/exportfs -r (code=exited, status=1/FAILURE)

Sep 16 16:54:14 ats-30-1 systemd[1]: Starting NFS server and services...
Sep 16 16:54:14 ats-30-1 exportfs[17476]: exportfs: /iso requires fsid= for NFS export
Sep 16 16:54:14 ats-30-1 systemd[1]: nfs-server.service: control process exited, code=exited status=1
Sep 16 16:54:14 ats-30-1 systemd[1]: Failed to start NFS server and services.
Sep 16 16:54:14 ats-30-1 systemd[1]: Unit nfs-server.service entered failed state.
Hint: Some lines were ellipsized, use -l to show in full.

参考 Using exportfs with NFSv4

An NFSv4 client now has the ability to see all of the exports served by the NFSv4 server as a single file system, called the NFSv4 pseudo-file system. On Red Hat Enterprise Linux, the pseudo-file system is identified as a single, real file system, identified at export with the fsid=0 option.

修改 /etc/exportfs,添加 fsid=0

/iso    *(fsid=0,rw,sync,no_subtree_check,all_squash,anonuid=36,anongid=36)

NFS客户端挂载

Linux挂载NFS的客户端非常简单的命令,先创建挂载目录,然后用 -t nfs 参数挂载就可以了

mount -t nfs  192.168.122.1:/data /data

如果要设置客户端启动时候就挂载NFS,可以配置 /etc/fstab 添加以下内容

192.168.122.1:/data    /data  nfs auto,rw,vers=3,hard,intr,tcp,rsize=32768,wsize=32768      0   0

然后在客户端简单使用以下命令就可以挂载

mount /data

如果出现以下类似报错,则检查一下系统是否缺少mount.nfs程序,如果缺少,则表明尚未安装nfs-utils工具包,需要补充安装后才能作为客户端挂载NFS

mount: wrong fs type, bad option, bad superblock on 192.168.122.1:/data,
       missing codepage or helper program, or other error
       (for several filesystems (e.g. nfs, cifs) you might
       need a /sbin/mount.<type> helper program)

       In some cases useful info is found in syslog - try
       dmesg | tail or so.

通过防火墙挂载NFS服务

在生产环境,可能会因为安全需求在NFS服务器和客户端之间部署防火墙。此时,NFS客户端挂载的时候会有如下输出报错

mount.nfs: Connection timed out

参考 Running NFS Behind a Firewall 设置防火墙允许访问NFS服务器的服务端口,注意,需要配置NFS服务使用固定端口。

可以在Linux NFS服务器上执行以下命令获得NFS端口信息

rpcinfo -p
   program vers proto   port  service
    100000    4   tcp    111  portmapper    <= rpcbind 服务
    100000    3   tcp    111  portmapper    <= rpcbind 服务
    100000    2   tcp    111  portmapper    <= rpcbind 服务
    100000    4   udp    111  portmapper    <= rpcbind 服务
    100000    3   udp    111  portmapper    <= rpcbind 服务
    100000    2   udp    111  portmapper    <= rpcbind 服务
    100024    1   udp  33948  status        <= rpc.statd 服务
    100024    1   tcp  35264  status        <= rpc.statd 服务
    100005    1   udp  20048  mountd        <= rpc.mount 服务
    100005    1   tcp  20048  mountd        <= rpc.mount 服务
    100005    2   udp  20048  mountd        <= rpc.mount 服务
    100005    2   tcp  20048  mountd        <= rpc.mount 服务
    100005    3   udp  20048  mountd        <= rpc.mount 服务
    100005    3   tcp  20048  mountd        <= rpc.mount 服务
    100003    3   tcp   2049  nfs
    100003    4   tcp   2049  nfs
    100227    3   tcp   2049  nfs_acl
    100003    3   udp   2049  nfs
    100003    4   udp   2049  nfs
    100227    3   udp   2049  nfs_acl
    100021    1   udp  48508  nlockmgr
    100021    3   udp  48508  nlockmgr
    100021    4   udp  48508  nlockmgr
    100021    1   tcp  38808  nlockmgr
    100021    3   tcp  38808  nlockmgr
    100021    4   tcp  38808  nlockmgr
  • rpc.mount服务端口

通过 lsof | grep rpc.mount 命令检查,可以看到rpc.mount服务使用的端口是

rpc.mount 27681          root    7u     IPv4           18221951        0t0        UDP *:mountd
rpc.mount 27681          root    8u     IPv4           18221953        0t0        TCP *:mountd (LISTEN)

这里*:mountd可以从/etc/serives配置文件中找出对应的端口是20048

#grep mountd /etc/services
mountd          20048/tcp               # NFS mount protocol
mountd          20048/udp               # NFS mount protocol
  • rpc.statd服务端口

lsof | grep rpc.statd命令检查可以看到

rpc.statd 27663       rpcuser    8u     IPv4           18236210        0t0        UDP *:33948
rpc.statd 27663       rpcuser    9u     IPv4           18236212        0t0        TCP *:35264 (LISTEN)
  • rpcbind服务端口

`lsof | grep rpcbind命令可以查看到

rpcbind   43419           rpc    4u     IPv4              28734        0t0        TCP *:sunrpc (LISTEN)
rpcbind   43419           rpc    7u     IPv4           11838817        0t0        UDP *:sunrpc
rpcbind   43419           rpc    8u     IPv4           11838818        0t0        UDP *:766
#grep sunrpc /etc/services
sunrpc          111/tcp         portmapper rpcbind      # RPC 4.0 portmapper TCP
sunrpc          111/udp         portmapper rpcbind      # RPC 4.0 portmapper UDP

设置RPC服务使用端口

由于NFS需要rpcbind,动态分配RPC服务端口会导致无法配置防火墙规则。

默认情况下,NFS使用的rpcbind使用动态设置RPC服务端口,需要修改以下配置:

  • 配置/etc/sysconfig/nfs文件来设置RPC服务使用的端口:

# 需要固定端口设置项前面的"#"符号需要去除,以便激活静态配置端口

# Optional arguments passed to rpc.mountd. See rpc.mountd(8)
RPCMOUNTDOPTS=""
# Port rpc.mountd should listen on. 
MOUNTD_PORT=892

# Optional arguments passed to rpc.statd. See rpc.statd(8)
STATDARG=""
# Port rpc.statd should listen on.
STATD_PORT=662

# Outgoing port statd should used. The default is port
# is random
STATD_OUTGOING_PORT=2020
  • 配置 /etc/modprobe.d/lockd.conf 中设置nlockmgr服务端口

options lockd nlm_tcpport=32768
options lockd nlm_udpport=32768
options nfs callback_tcpport=32764  # 可选参数

这里callback_tcpport是用于NFSv4.0 callback,也就是设置/proc/sys/fs/nfs/nfs_callback_tcpport,并且还需要设置防火墙允许服务器能够连接客户端的端口32764。不过,对于NFSv4.1或更高版本,不需要此步骤,并且在纯NFSv4环境,也不需要mountd,statdlockd的端口。

lockd.conf配置参考 Debian SecuringNFS

这个参数也可以通过/etc/sysctl.conf或者/etc/sysctl.d/nfs-static-ports.conf内核参数传递 - 在CentOS 7上,内核参数fs.nfs.nlm_tcpportfs.nfs.nlm_udpport默认都是0

fs.nfs.nfs_callback_tcpport = 32764
fs.nfs.nlm_tcpport = 32768
fs.nfs.nlm_udpport = 32768
  • 重新加载NFS配置和服务(貌似status服务和nlockmgr服务端口不生效)

systemctl restart nfs-config
systemctl restart nfs-server

再次使用rpcinfo -p确认端口配置是否生效。

  • 改为重启以下服务,此时检查发现status端口正确改成662,但是nlockmgr因为内核没有重新加载模块,所以端口没有修改

systemctl restart nfs-idmap
systemctl restart nfs-lock
systemctl restart nfs-server
systemctl restart rpcbind
  • 通过sysctl修改nlockmgr端口,但是发现如果不重新加载内核模块是不能订正nlockmgr端口

sysctl -w fs.nfs.nlm_tcpport=32768
sysctl -w fs.nfs.nlm_udpport=32768

暂时没有找到解决方法,所以还是通过重启操作系统来使得nlockmgr端口调整到32768

配置防火墙端口

NFS的TCP和UDP端口2049

rpcbind/sunrpc的TCP和UDP端口111

设置 MOUNTD_PORT 的TCP和UDP端口

设置 STATD_PORT 的TCP和UDP端口

设置 LOCKD_TCPPORT 的TCP端口

设置 LOCKD_UDPPORT 的UDP端口

  • 使用firewalld的配置方法:

在 Linux NFS 服务器上使用以下命令开启iptables防火墙允许访问以上端口

firewall-cmd --permanent --add-port=2049/tcp
firewall-cmd --permanent --add-port=2049/udp
firewall-cmd --permanent --add-port=111/tcp
firewall-cmd --permanent --add-port=111/udp
firewall-cmd --permanent --add-port=892/tcp
firewall-cmd --permanent --add-port=892/udp
firewall-cmd --permanent --add-port=662/tcp
firewall-cmd --permanent --add-port=662/udp
firewall-cmd --permanent --add-port=32768/tcp
firewall-cmd --permanent --add-port=32768/udp

在 Linux NFS 服务器上使用以下命令重新加载防火墙规则

firewall-cmd --reload
  • 使用iptables的配置方法:

iptables -A INPUT -p tcp -m tcp --dport 2049 -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 2049 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 111 -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 111 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 892 -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 892 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 662 -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 662 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 32803 -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 32769 -j ACCEPT

如果要指定接口,也可以加上参数如-i virbr0-nic,例如iptables -A INPUT -i virbr0-nic -p tcp -m tcp --dport 2049 -j ACCEPT

参考

https://www.howtoforge.com/samba-server-installation-and-configuration-on-centos-7

https://www.unixmen.com/install-configure-samba-server-centos-7/

Last updated