Linux下NFS服务器的搭建与配置

一、NFS服务简介

 NFS 就是 Network FileSystem 的缩写,最早是由sun 公司所发展出来的。 它最大的功能就是可以透过网络,让不同的机器、不同的操作系统、可以彼此分享个别的档案 (share files)。所以,你也可以简单的将它看做是一个文件服务器 (file server) !这个 NFS 服务器可以让你的 PC 将网络远程的 NFS 服务器分享的目录,挂载到本地的机器当中, 在本地的机器看起来,那个远程主机的目录就好像是自己的一个磁盘分区一样 (partition)!使用起来相当便利!

因为 NFS 支持的功能相当的多,而不同的功能都会使用不同的程序来启动, 每启动一个功能就会启用一些端口来传输数据,因此, NFS 的功能所对应的端口才没有固定住, 而是随机取用一些未被使用的小于 1024 的端口来作为传输使用。但如此一来又造成客户端想要连上服务器,就得知道服务器的相关端口。

此时我们就得需要远程过程调用 RPC服务啦!RPC 最主要的功能就是在指定每个 NFS 功能所对应的 port number ,并且返回给客户端,让客户端可以连接到正确的端口上去。 那 RPC 又是如何知道每个 NFS 的端口呢?这是因为当服务器在启动 NFS 时会随机取用数个端口,并主动的向 RPC 注册,因此 RPC 可以知道每个端口对应的 NFS 功能,然后 RPC 又是固定使用 tcp 111和udp 111 来监听客户端的需求并返回给客户端正确的端口。

所以你要注意,要启动 NFS 之前,RPC 就要先启动了,否则 NFS 无法向 RPC 注册。 另外,RPC 若重新启动时,原本注册的数据会不见,因此 RPC 重新启动后,它管理的所有服务都需要重新启动来重新向 RPC 注册。

当客户端有 NFS 档案存取需求时,他会如何向服务器端要求数据呢?

  1. 客户端会向服务器端的 RPC 发出 NFS 文件存取请求;
  2. RPC找到对应的已注册的 NFS daemon 端口后,会返回给客户端;
  3. 客户端了解正确的端口后,就可以直接与 NFS daemon 来联机。

由于 NFS 的各项功能都必须要向 RPC 来注册,这样RPC 才能了解 NFS 这个服务的各项功能的 port number, PID, NFS 在服务器所监听的 IP 等等,而客户端才能够透过 RPC 找到正确对应的端口。 也就是说,NFS 必须要有 RPC 存在时才能成功的提供服务,因此我们称 NFS 为 RPC server 的一种。事实上,有很多这样的服务器都是向 RPC 注册的,比如,NIS (Network Information Service) 也是 RPC server 的一种。

二、所需要的软件及软件结构

要设定好 NFS 服务器我们必须要有两个软件才行,分别是:

    • RPC 主程序:rpcbind

      就如同刚刚提到的,我们的 NFS 其实可以被视为一个 RPC 服务,而要启动任何一个 RPC 服务之前,我们都需要做好端口的对应规划工作才行,这个工作其实就是『 rpcbind 』这个服务所负责的!也就是说, 在启动任何一个 RPC 服务之前,我们都需要启动 rpcbind 才行! (在 CentOS 5.x 以前这个软件称为 portmap,在 CentOS 6.x 之后称为 rpcbind !)

    • NFS 主程序:nfs-utils

      就是提供 rpc.nfsd 及 rpc.mountd 这两个 NFS daemons 与其他相关说明文件、执行文件等的软件!
  • 主要配置文件:/etc/exports
    这个文件是 NFS 的配置文件!不过,系统并没有默认值,所以这个文件不一定会存在,你可能要自己去创建这个文件!
  • NFS 文件系统维护命令:/usr/sbin/exportfs
    这个是维护 NFS 分享资源的命令,我们可以利用这个指令重新分享 /etc/exports 变更的目录资源、将 NFS Server 分享的目录卸除或重新分享等等。
  • 分享资源的登录档:/var/lib/nfs/*tab
    在 NFS 服务器的登录文件都放置到 /var/lib/nfs/ 目录里面,在该目录下有两个比较重要的登录档, 一个是 etab ,主要记录了 NFS 所分享出来的目录的完整权限设定值;另一个 xtab 则记录曾经链接到此 NFS 服务器的相关客户端数据。
  • 客户端查询服务器分享资源的命令:/usr/sbin/showmount
    exportfs 是用在 NFS Server 端,而 showmount 则主要用在 Client 端。这个 showmount 可以用来查看 NFS 分享出来的目录资源!

三、系统环境


系统CentOS7.3

server ip: 192.168.1.101

四、服务器端设置

1、查看系统是否已安装NFS

[root@localhost ~]# rpm -qa | grep nfs
[root@localhost ~]# rpm -qa | grep rpcbind

2、安装所需软件

[root@localhost ~]# yum -y install nfs-utils rpcbind

3、在NFS服务端上创建共享目录/data并设置权限

[root@localhost ~]# mkdir /data
[root@localhost ~]# chmod 666 /data

4、编辑export文件

[root@localhost ~]# vim /etc/exports 

/data 192.168.1.0/24(rw,sync,no_root_squash,no_all_squash)
要输出的文件系统 输出给哪些主机 输出文件系统时使用的相关权限参数
  参数值    内容说明
  rw ro   rw该目录分享的文件是(read-write)可读可写, ro(read-only)只读,但最终能不能读写,还是与文件系统的 rwx 及身份有关。
sync async  sync代表数据会同步写入到内存与硬盘中,async代表数据会先暂存于内存当中,而非直接写入硬盘!
no_root_squash root_squash 客户端使用 NFS 文件系统的账号若为 root 时,系统该如何判断这个账号的身份?预设的情况下,客户端 root 的身份会由 root_squash 的设定压缩成 nfsnobody, 如此对服务器的系统会较有保障。但如果你想要开放客户端使用 root 身份来操作服务器的文件系统,那么这里就得要开 no_root_squash 才行!
all_squash 不论登入 NFS 的使用者身份为何, 他的身份都会被压缩成为匿名用户,通常也就是 nobody(nfsnobody) 啦!
anonuid  anongid anon 意指 anonymous (匿名者) 前面关于 *_squash 提到的匿名用户的 UID 设定值,通常为 nobody(nfsnobody),但是你可以自行设定这个 UID 的值!当然,这个 UID 必需要存在于你的 /etc/passwd 当中! anonuid 指的是 UID 而 anongid 则是群组的 GID 啰。
复制代码

配置生效

[root@localhost~]# exportfs -r

启动rpcbind、nfs服务

复制代码
[root@localhsot ~]# systemctl start rpcbind                             
[root@localhost ~]# systemctl start nfs
启动 NFS 服务:                                            [确定]
启动 NFS mountd:                                          [确定]
启动 NFS 守护进程:                                        [确定]
正在启动 RPC idmapd:                                      [确定]
复制代码

查看 RPC 服务的注册状况

复制代码
[root@localhost ~]# rpcinfo -p localhost
   program vers proto   port  service
    100000    4   tcp    111  portmapper
    100000    3   tcp    111  portmapper
    100000    2   tcp    111  portmapper
    100000    4   udp    111  portmapper
    100000    3   udp    111  portmapper
    100000    2   udp    111  portmapper
    100005    1   udp  49979  mountd
    100005    1   tcp  58393  mountd
    100005    2   udp  45516  mountd
    100005    2   tcp  37792  mountd
    100005    3   udp  32997  mountd
    100005    3   tcp  39937  mountd
    100003    2   tcp   2049  nfs
    100003    3   tcp   2049  nfs
    100003    4   tcp   2049  nfs
    100227    2   tcp   2049  nfs_acl
    100227    3   tcp   2049  nfs_acl
    100003    2   udp   2049  nfs
    100003    3   udp   2049  nfs
    100003    4   udp   2049  nfs
    100227    2   udp   2049  nfs_acl
    100227    3   udp   2049  nfs_acl
    100021    1   udp  51112  nlockmgr
    100021    3   udp  51112  nlockmgr
    100021    4   udp  51112  nlockmgr
    100021    1   tcp  43271  nlockmgr
    100021    3   tcp  43271  nlockmgr
    100021    4   tcp  43271  nlockmgr
复制代码
选项与参数:
-p :针对某 IP (未写则预设为本机) 显示出所有的 port 与 porgram 的信息;
-t :针对某主机的某支程序检查其 TCP 封包所在的软件版本;
-u :针对某主机的某支程序检查其 UDP 封包所在的软件版本;

在你的 NFS 服务器设定妥当之后,我们可以在 server 端先自我测试一下是否可以联机!就是利用 showmount 这个指令来查阅!

[root@localhost ~]# showmount -e localhost
Export list for localhost:
/data 192.168.1.0/24
选项与参数:
-a :显示目前主机与客户端的 NFS 联机分享的状态;
-e :显示某部主机的 /etc/exports 所分享的目录数据。

六、客户端配置

安装nfs-utils客户端

复制代码
[root@localhost ~]# yum -y install nfs-utils
已安装:
  nfs-utils.x86_64 1:1.2.3-70.el6_8.2                                                                                  

作为依赖被安装:
  keyutils.x86_64 0:1.4-5.el6         libevent.x86_64 0:1.4.13-4.el6         libgssglue.x86_64 0:0.1-11.el6           
  libtirpc.x86_64 0:0.2.1-11.el6_8    nfs-utils-lib.x86_64 0:1.1.5-11.el6    python-argparse.noarch 0:1.2.1-2.1.el6   
  rpcbind.x86_64 0:0.2.0-12.el6      

完毕!
复制代码

 

创建挂载目录

[root@localhost ~]# mkdir /nfs

查看服务器抛出的共享目录信息

[root@localhost ~]# showmount -e 192.168.1.101
Export list for 192.168.1.101:
/data 192.168.1.0/24

为了提高NFS的稳定性,使用TCP协议挂载,NFS默认用UDP协议

[root@localhost ~]# mount -t nfs 192.168.1.101:/data /nfs -o proto=tcp -o nolock

七、测试结果

查看挂载结果

复制代码
[root@localhost ~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root
                       18G  1.1G   16G   7% /
tmpfs                 112M     0  112M   0% /dev/shm
/dev/sda1             477M   54M  398M  12% /boot
192.168.1.101:/data
                       18G  1.1G   16G   7% /nfs
复制代码

服务端

[root@localhost ~]# echo "test" > test.txt

客户端

[root@localhost ~]# cat /test.txt 
test
[root@localhost ~]# echo "204" >> /test.txt 

服务端

[root@localhost ~]# cat /test.txt 
test
204

卸载已挂在的NFS

复制代码
[root@localhost ~]# umount /
[root@localhost ~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root
                       18G  1.1G   16G   7% /
tmpfs                 112M     0  112M   0% /dev/shm
/dev/sda1             477M   54M  398M  12% /boot
复制代码

 

到此结束

 

补充部分:

为了方便配置防火墙,需要固定nfs服务端口

NFS启动时会随机启动多个端口并向RPC注册,这样如果使用iptables对NFS端口进行限制就会有点麻烦,可以更改配置文件固定NFS服务相关端口。

复制代码
[root@localhost ~]# rpcinfo -p localhost
   program vers proto   port  service
    100000    4   tcp    111  portmapper
    100000    3   tcp    111  portmapper
    100000    2   tcp    111  portmapper
    100000    4   udp    111  portmapper
    100000    3   udp    111  portmapper
    100000    2   udp    111  portmapper
    100005    1   udp  49979  mountd
    100005    1   tcp  58393  mountd
    100005    2   udp  45516  mountd
    100005    2   tcp  37792  mountd
    100005    3   udp  32997  mountd
    100005    3   tcp  39937  mountd
    100003    2   tcp   2049  nfs
    100003    3   tcp   2049  nfs
    100003    4   tcp   2049  nfs
    100227    2   tcp   2049  nfs_acl
    100227    3   tcp   2049  nfs_acl
    100003    2   udp   2049  nfs
    100003    3   udp   2049  nfs
    100003    4   udp   2049  nfs
    100227    2   udp   2049  nfs_acl
    100227    3   udp   2049  nfs_acl
    100021    1   udp  51112  nlockmgr
    100021    3   udp  51112  nlockmgr
    100021    4   udp  51112  nlockmgr
    100021    1   tcp  43271  nlockmgr
    100021    3   tcp  43271  nlockmgr
    100021    4   tcp  43271  nlockmgr
复制代码

分配端口,编辑配置文件:

[root@localhost ~]# vim /etc/sysconfig/nfs

添加:

RQUOTAD_PORT=30001
LOCKD_TCPPORT=30002
LOCKD_UDPPORT=30002
MOUNTD_PORT=30003
STATD_PORT=30004                   

重启

复制代码
[root@localhost ~]# systemctl restart nfs 
关闭 NFS 守护进程:                                        [确定]
关闭 NFS mountd:                                          [确定]
关闭 NFS 服务:                                            [确定]
Shutting down RPC idmapd:                                  [确定]
启动 NFS 服务:                                            [确定]
启动 NFS mountd:                                          [确定]
启动 NFS 守护进程:                                        [确定]
正在启动 RPC idmapd:                                      [确定]
复制代码

查看结果

复制代码
[root@localhost ~]# rpcinfo -p localhost
   program vers proto   port  service
    100000    4   tcp    111  portmapper
    100000    3   tcp    111  portmapper
    100000    2   tcp    111  portmapper
    100000    4   udp    111  portmapper
    100000    3   udp    111  portmapper
    100000    2   udp    111  portmapper
    100005    1   udp  30003  mountd
    100005    1   tcp  30003  mountd
    100005    2   udp  30003  mountd
    100005    2   tcp  30003  mountd
    100005    3   udp  30003  mountd
    100005    3   tcp  30003  mountd
    100003    2   tcp   2049  nfs
    100003    3   tcp   2049  nfs
    100003    4   tcp   2049  nfs
    100227    2   tcp   2049  nfs_acl
    100227    3   tcp   2049  nfs_acl
    100003    2   udp   2049  nfs
    100003    3   udp   2049  nfs
    100003    4   udp   2049  nfs
    100227    2   udp   2049  nfs_acl
    100227    3   udp   2049  nfs_acl
    100021    1   udp  30002  nlockmgr
    100021    3   udp  30002  nlockmgr
    100021    4   udp  30002  nlockmgr
    100021    1   tcp  30002  nlockmgr
    100021    3   tcp  30002  nlockmgr
    100021    4   tcp  30002  nlockmgr
复制代码

可以看到,随机端口以固定

iptables策略问题完美解决!!!