NFS(Network File System),它的目的就是想让不同的机器,不同的操作系统可以彼此共享数据文件,目前在Unix like当中用来作为文件服务器是一个相当不错的解决方案,基本上Unix like主机连接到另一台Unix like主机来共享彼此的文件时,使用NFS要比SAMBA服务器快速且方便的多。此外,NFS的配置很简单,只要记得启动Remote Procedure Call(rpc,就是rpcbind这个软件)就能够搭建起来。

1.NFS的由来与功能

NFS共享文件系统的搭建很简单,不过最大的问题就是权限。因为在服务器端和客户端必须具备相同的账号才能够访问某些目录或文件,另外NFS启动需要通过远程调用RPC,也就是说并不是只启动NFS,还要启动rpc这个服务才行。

1.1 什么是NFS(Network File System)

NFS就是Network File System的缩写,最初由sun公司发展出来。它最大的功能就是可以通过网络,让不同的机器、不同的操作系统可以共享彼此的文件(share files)。所以也可以简单的将它看做是一个文件服务器(file server).NFS服务器可以让PC将网络中的NFS服务器共享的目录挂载到本地端的文件中,而且在本地段的系统看来,远程主机的目录就好像是自己的一个磁盘分区(partition)一样,在使用上相当便利。其结构图如下图所示:

文件服务器之NFS服务器

就如同上面的图示一样,当NFS服务器配置好共享出来的/home/sharefile这个目录后,其他的NFS客户端就可以将这个目录挂载到自己的文件系统的某个挂载点(挂载点可以自定义)上,例如上图中的NFS Client1与NFS Client2挂载的目录就不同。只要在NFS Client1系统中进入/home/data/sharefile内,就可以看到NFS服务器系统内的/home/sharefile目录下的所有数据(当然要有足够的权限)。这个/home/data/sharefile就好像NFS Client1机器里面的一个partition,只要权限足够,那么就可以使用cp、cd、mv、rm等磁盘或文件相关的命令。

既然NFS是通过网络来进行数据传输的,那么NFS使用哪个端口来进行数据传输呢?基本上这个服务的端口开在2049,但是由于文件系统非常复杂,因此NFS还需要其他程序去启动额外端口,但这些额外端口启动的端口是什么呢?答案“不知道”。因为默认NFS用来传输的端口是随机选择的,小于1024的端口,那客户端怎么知道服务器端使用哪个端口呢?此时就需要用远程过程调用(Remote Procedure Call,RPC)协议来辅助了。

1.2 什么是RPC(Remote Procedure Call)

RPC最主要的功能就是指定每个NFS功能所对应的port number,并且通知客户端,让客户端可以连接到正确的端口上去,那rpc又是如何知道每个NFS的端口的呢?这是因为当服务器在启动NFS时会随机选取数个端口,并主动向RPC注册,因此RPC可以知道每个端口对应的NFS功能。然后RPC又是固定使用port 111来监听客户端的需求并向客户端相应正确的端口。因此使NFS得启动更为便捷。

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

1.3 NFS启动的RPC deamons

我们现在知道NFS服务器在启动的时候需要向rpc注册,所以NFS服务器也称为RPC server之一。那么NFS服务器主要的任务是进行文件系统的共享,而文件系统的共享是与权限有关的,所以NFS服务器至少需要两个daemons,一个管理客户端是否能够登录的问题,一个管理客户端能够取得的权限。如果需要quota的话,那么NFS还需要加载其他的RPC程序,NFS服务器有一下几个daemon。

rpc.nfsd

最主要的NFS服务提供程序,这个daemon主要的功能是管理客户端是否能够使用服务器文件系统的挂载信息等,其中还包含判断这个登录用户的ID。

rpc.mountd

这个daemon主要功能,则是在于管理NFS的文件系统。当客户端顺利通过rpc.nfsd登录服务器之后,在它可以使用NFS服务器提供的文件之前,还会经过文件权限的热证程序。它会去读NFS的配置文件/etc/exports来对比客户端的权限,当通过这一关之后客户端就可以取得使用NFS文件的权限了。

rpc.lockd(非必要)

这个daemon可以用来管理文件锁定(lock)方面。文件为何要锁定呢?因为既然共享的NFS文件可以让客户端使用,那么当多个客户端同时尝试写入某个文件时,就可能对文件造成一定的问题。rpc.lockd则可以用来客服这些问题。但rpc.lockd必须要同时在客户端和服务器端都开启才行,此外,roc.lockd也常与rpc.statd同时启动。

rpc.stats(非必要)

这个daemon可以用来检查文件的一致性,与rpc.lockd有关。若发生因为客户端同时使用同一文件造成可能有所损坏时,rpc.statd可以用来检测并尝试回复该文件,与rpc.lockd一样,这个功能必要要在服务端和客户端同时启动才会生效。

上述的几个RPC 所需要的程序,其实都已经写入两个基本的服务器启动脚本中了,那就是bfs和nfslock,也就是/etc/init.d/nfs和/etc/init.d/nfslock,与服务器相关的写入nfs服务中,而与客户端的rpc.lockd相关,就设置于nfslock服务中。

1.4 NFS的文件系统的访问权限

不知道大家想没想过一个问题,假如在NFS Client1上面以dmtsai这个用户身份去访问/home/data/sharefile/这个来自NFS Server所提供的文件系统,请问NFS Server所提供的文件系统会让我们以什么身份去访问?是dmtzai还是其他什么?

当以dmtsai这个一般身份用户去访问来自服务器端的文件时,需要注意的是:文件系统的inode所记录的属性为UID、GID,而非账号与属组名。那一般linux主机会主动以自己的/etc/passwd、/etc/group来查询对应的用户名,组名。所以当dmtsai进入到该目录后,会参照NFS Client1的用户名与组名,但是由于该目录的文件来自于NFS Server,所以可能会出现以下几种情况。

(1)NFS Server/NFS Client刚好有相同的账号与属组名

此时用户可以直接以dmtsai的身份访问服务器所提供的共享文件系统。

(2)NFS Server的502这个UID账号对应的账号为vbird

若NFS服务器上的/etc/passwd里面UID 502的用户为vbird,则客户端的dmtsai可以访问服务器端的vbird这个用户的文件,只因为两者有相同的UID而已。这样就不能保证客户端的UID对应的账号会与服务器相同,那nfs服务器所提供的数据岂不就可能会被错误的用户乱改?

(3)NFS Server并没有502这个UID

另一种情况是,在服务器端并没有502这个UID的存在,则此时dmtsai的身份在该目录下就会被压缩成匿名用户,一般NFS的匿名者把65534作为其ID,早期的linux中这个65534的账号名称通常是nobody,Centos则取名为nfsnobody。但有时也有特殊的情况,例如在服务器共享/tmp目录的时候,dmtsain的身份还是会保持502,但建立的各项数据在服务器端来看,就会属于无属主的数据。

(4)如果用户身份是root

有个比价特殊的用户,那就是每个linux主机都有的UID为0的root。如果客户端可以用root的身份去访问服务器的文件系统,那服务器的数据哪会有什么安全性保护?所以在默认情况下,root的身份会被主动压缩成为匿名用户。

总之,客户端用户能做的事情是与UID及其GID有关的,那当客户端与服务器端的UID即账号的对应不一致时,可能就会造成文件系统使用上的混乱,这是NFS文件系统在使用上的一个弊端,而在了解用户账号与UID及文件系统的关系之后,要实际在客户端以NFS使用服务器端的文件系统时,还需要具备:

(1)NFS服务器已经开放可写入的权限(与/etc/exports设置有关)。

(2)实际的文件权限具有可写入(w)的权限。

当满足了以下的文件:①用户账号,即UID的相关身份;②NFS服务器允许写入的权限;③文件系统确实是有w的权限时,才具有该文件的可写入权限,尤其是身份(UID)确认环节,很容易弄错。

2.NFS Server端的配置

2.1 所需要的软件

RPC主程序:rpcbind

NFS主程序:nfs-utils

用rpm或者yum安装

[root@nfs_server ~]# yum install nfs-utils rpcbind -y
[root@nfs_server ~]# rpm -qa|grep nfs
nfs-utils-lib-1.1.5-13.el6.x86_64
nfs-utils-1.2.3-78.el6_10.1.x86_64
[root@nfs_server ~]# rpm -qa|grep rpcbind
rpcbind-0.2.0-16.el6.x86_64

2.2 NFS软件的结构

(1)主要配置文件:/etc/exports

这个文件时NFS的主要配置文件。不过系统并没有默认值,所以这个文件不一定存在,可能要用vim创建。

(2)NFS文件系统维护命令:/usr/sbin/exportfs

[root@nfs_server ~]# which exportfs
/usr/sbin/exportfs

这个是维护NFS共享资源的命令,可以利用这个命令重新共享/etc/exports更新的目录资源、将NFS Server共享的目录卸载或重新共享等。

(3)共享资源的日志文件:/var/lib/nfs/*tab

在NFS服务器中,日志文件都放置到/var/lib/nfs/目录中、在该目录下有两个比较重要的日志文件,一个是etab,主要记录了NFS所共享出来的目录的完整权限的设置值;另一个就是xtab,则记录了曾经链接到此NFS服务器的相关客户端的数据。

[root@nfs_server ~]# ll /var/lib/nfs/*tab
 -rw-r--r-- 1 root root 0 Oct  9 23:50 /var/lib/nfs/etab
 -rw-r--r-- 1 root root 0 Oct  9 23:50 /var/lib/nfs/rmtab
 -rw-r--r-- 1 root root 0 Oct  9 23:50 /var/lib/nfs/xtab

(4)客户端查询服务器共享资源的命令:/usr/sbin/showmount

这是一个重要的NFS命令。export用在NFS Server端,而showmount则主要用在客户端。showmount可以用来查看NFS共享出来的目录资源。

2.3 /etc/exports配置文件的语法与参数

在开始NFS服务器的配置之前要了解的是,NFS会直接使用到内核功能,所以内核必须支持NFS才行。万一如果所有的核心版本小于2.2版本,那么就要注意了可能忘记选择NFS的内核支持。

还好Centos或者是其他版本的linux,默认内核通常是支持NFS功能的,所以只要确认内核的版本是当前的2.6.X版本。

[root@nfs_server ~]# uname -r
 2.6.32-696.el6.x86_64

至于NFS服务器的搭建很简单,只要编辑好主配置文件/etc/exports之后,先启动rpcbind(如果已经启动了,就不要重新启动),然后再启动NFS,nfs服务器就搭建成功了。下面看一下文件的配置:

[root@nfs_server ~]# cat /etc/exports
/tmp      192.168.136.0/24(rw) localhost(rw) *.ev.ncku.edu.tw(ro,sync)

[共享目录tmp]  [第一台主机(权限)][第二台主机可以用主机名(rw)]  [可用通配符表示]

上面的例子是将/tmp分别分享给3个不同的主机或网络。主机后面要用小括号“()”定义权限参数,若权限参数不止一个时,则以逗号“,”分开,并且主机名与小括号是连在一起的,这个文件内也可以用井号“#”来注释。

主机名的设置有下面几种方式:

(1)可以使用完整的IP或者是网络号,例如192.168.136.0或者192.168.136.0/24,或192.168.136.0/255.255.255.0都可以。

(2)可以使用主机名,但这个主机名必须在/etc/hosts内,或者使用DNS找到该名称才行,反正重点是可找到IP就行。如果是主机名的话,那么可以支持通配符。例如"*"或“?”都可以。

常用权限参数如下图所示:

文件服务器之NFS服务器

例题1:

让root保留root的权限

假如想讲/tmp共享出去给大家使用,由于这个目录本来就是大家都可以读写的,一次想让所有人都可以访问。此外,要让root写入的文件还具有root的权限,那应该如何设计配置文件呢?

答:

[root@nfs_server ~]# cat /etc/exports
/tmp192.168.136.0/24(rw) localhost(rw) *.ev.ncku.edu.tw(ro,sync)
#任何人都可以用/tmp,用通配符来处理主机名,重点在no_root_squash
/tmp*(rw,no_root_squash)

主机名可以使用通配符,上例表示无论来自哪里的用户都可以使用/tmp目录。再次提醒,*(rw,no_root_squash)这个设置值中间是没有空格符的。而/tmp和*(rw,no_root_squash)则是用空格符来隔开的。特别注意no_root_squash的功能,在这个例子中,如果你是客户端,而且你是以root的身份登录你的linux主机,那么当你挂载这台主机的/tmp目录后,在使用该目录时将具有root的权限。

例题2:

同一目录针对不同范围开放不同权限

加入要将一个公共的目录/home/public开放,但是需要限定在局域网192.168.136.0/24这个网络且加入linzhongniao组的用户才能够读写,其他来源的用户只能读取。

答:

[root@nfs_server ~]# mkdir -p /home/public
  oot@nfs_server ~]# setfa
setfacl   setfattr  
[root@nfs_server ~]# setfacl -m g:linzhongniao:rwx /home/public/
[root@nfs_server ~]# cat /etc/exports
#多个范围用空格分开
/home/public 192.168.136.0/24(rw) *(ro) 

上面的例子说明,当ip为192.168.136.0/24这个网段的时候,在客户端挂载了/home/public后,针对这个挂载的目录就具有可以读写的权限,至于不在这个网段的用户,对这个目录只具有可以读写的权限。

注意:通配符只能用在主机名的分辨上,IP或网段只能用192.168.136.0/24的形式,不可以使用192.168.136.*这种格式表示。

例题3:

仅给某一个主机使用的目录设置

假如要将一个私人的目录/home/test开放给192.168.136.114这个客户端的机器来使用,该如何设置?假设具有完整权限的用户是dmtsai。

答:

[root@nfs_server ~]# mkdir -p /home/test
[root@nfs_server ~]# setfacl -m u:dmtsai:rwx /home/test
[root@nfs_server ~]# cat /etc/exports
#只要设置的ip正确即可
/home/test 192.168.136.114(rw) 

例题4:

开放匿名访问的情况

假如要让*.centos.vbird网络的主机,登录到NFS主机时,可以访问/home/linux,但是在写入数据时,希望他们的UID与GID都变成45这个身份的用户,假设NFS服务器上的UID45和GID45的用户/组名为nfsanon。

[root@nfs_server ~]# cat /etc/exports
#如果要开放匿名访问,那么重点是all_squash,并且要配合anonuid
/home/linux *.centos.vbird(rw,all_squash,anonuid=45,anongid=45) 

注意all_squash与anonuid、anongid的功能。如此一来当*.centos.vbird登录这台NFS主机,并且在/home/linux写入文件时,该文件的属主与属组就会变成/etc/passwd里面对应的UID为45的那个身份的用户了。

2.4 启动NFS

[root@nfs_server ~]# cat /etc/exports
/wwwdir 192.168.136.0/24(rw,no_root_squash,sync)
[root@nfs_server ~]# /etc/init.d/rpcbind start
[root@nfs_server ~]# /etc/init.d/nfs start
Starting NFS services: [  OK  ]
Starting NFS quotas:   [  OK  ]
Starting NFS mountd:   [  OK  ]
Starting NFS daemon:   [  OK  ]
Starting RPC idmapd:   [  OK  ]
[root@nfs_server ~]# chkconfig rpcbind on
[root@nfs_server ~]# chkconfig nfs on
[root@nfs_server ~]# chkconfig nfslock on

rpcbind不需要配置,直接启动即可。启动之后会出现一个port 111的sunrpc的服务,那就是rpcbind。至于nfs则会启动至少两个以上的daemon,然后就开始监听client端的请求。必须要注意屏幕上的输出,如果配置文件写错的话会输出错误的地方。

此外如果想要保证NFS服务器的一致性,可能需要用到rpc.lockd及rpc.start等rpc服务,这是需要增加的服务,就是nfslock。启动之后要赶快查看/var/log/message日志文件有没有正确启动。

[root@nfs_server ~]# tail  /var/log/messages  
Nov  8 09:59:24 nfs_server kernel: e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: None
Nov  8 09:59:24 nfs_server kernel: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
Nov  8 10:45:25 nfs_server kernel: RPC: Registered named UNIX socket transport module.
Nov  8 10:45:25 nfs_server kernel: RPC: Registered udp transport module.
Nov  8 10:45:25 nfs_server kernel: RPC: Registered tcp transport module.
Nov  8 10:45:25 nfs_server kernel: RPC: Registered tcp NFSv4.1 backchannel transport module.
Nov  8 10:45:25 nfs_server kernel: Installing knfsd (copyright (C) 1996 okir@monad.swb.de).
Nov  8 10:45:25 nfs_server rpc.mountd[2808]: Version 1.2.3 starting
Nov  8 10:45:25 nfs_server kernel: NFSD: Using /var/lib/nfs/v4recovery as the NFSv4 state recovery directory
Nov  8 10:45:25 nfs_server kernel: NFSD: starting 90-second grace period

在确认正确启动之后,查看一下NFS服务器开了那些端口

[root@nfs_server ~]# netstat -lntup|grep -E "rpc|nfs"
tcp0  0 0.0.0.0:48897   0.0.0.0:*   LISTEN  2808/rpc.mountd 
tcp0  0 0.0.0.0:875 0.0.0.0:*   LISTEN  2803/rpc.rquotad
tcp0  0 0.0.0.0:111 0.0.0.0:*   LISTEN  1382/rpcbind
tcp0  0 0.0.0.0:44691   0.0.0.0:*   LISTEN  2808/rpc.mountd 
tcp0  0 0.0.0.0:48952   0.0.0.0:*   LISTEN  2808/rpc.mountd 
tcp0  0 0.0.0.0:59065   0.0.0.0:*   LISTEN  1404/rpc.statd  
tcp0  0 :::35080:::*LISTEN  1404/rpc.statd  
tcp0  0 :::111  :::*LISTEN  1382/rpcbind
tcp0  0 :::44050:::*LISTEN  2808/rpc.mountd 
tcp0  0 :::33399:::*LISTEN  2808/rpc.mountd 
tcp0  0 :::41721:::*LISTEN  2808/rpc.mountd 
udp0  0 0.0.0.0:709 0.0.0.0:*   1382/rpcbind
udp0  0 127.0.0.1:732   0.0.0.0:*   1404/rpc.statd  
udp0  0 0.0.0.0:875 0.0.0.0:*   2803/rpc.rquotad
udp0  0 0.0.0.0:111 0.0.0.0:*   1382/rpcbind
udp0  0 0.0.0.0:34709   0.0.0.0:*   2808/rpc.mountd 
udp0  0 0.0.0.0:42402   0.0.0.0:*   2808/rpc.mountd 
udp0  0 0.0.0.0:42285   0.0.0.0:*   1404/rpc.statd  
udp0  0 0.0.0.0:44983   0.0.0.0:*   2808/rpc.mountd 
udp0  0 :::709  :::*1382/rpcbind
udp0  0 :::33508:::*2808/rpc.mountd 
udp0  0 :::111  :::*1382/rpcbind
udp0  0 :::47999:::*2808/rpc.mountd 
udp0  0 :::36500:::*2808/rpc.mountd 
udp0  0 :::38456:::*1404/rpc.statd   

我们看启动了好多端口,不过最主要的端口是:

rpcbind启动的prot在111端口,同时启动在UDP和TCP。

[root@nfs_server ~]# netstat -lntup|grep -E "rpc|nfs"|grep "111"
tcp0  0 0.0.0.0:111 0.0.0.0:*   LISTEN  1382/rpcbind
tcp0  0 :::111  :::*LISTEN  1382/rpcbind
udp0  0 0.0.0.0:111 0.0.0.0:*   1382/rpcbind
udp0  0 :::111  :::*1382/rpcbind  

NFS本身的服务启动在port 2049上。

其他的rpc.*服务启动的port则是随机产生的,因此需要向port 111注册。

怎么知道每个RPC服务的注册情况呢?可以用rpcinfo命令查看

[root@nfs_server ~]# rpcinfo -p [IP|hostname]
[root@nfs_server ~]# rpcinfo -t|-u  [IP|hostname] 程序名称例如nfs
 -p:针对某IP(未写则默认为本机) 显示出所有的port与program(程序)的信息。
 -t:针对某主机的某个程序检查其TCP数据包所在的软件版本。
 -u:针对某主机某个程序检查其UDP数据包所在的软件版本。

#1.显示出目前这台主机的rpc状态
[root@nfs_server ~]# rpcinfo -p localhost
   program vers proto   port  service
1000004   tcp111  portmapper
1000003   tcp111  portmapper
1000002   tcp111  portmapper
1000004   udp111  portmapper
1000003   udp111  portmapper
1000002   udp111  portmapper
1000241   udp  42285  status
1000241   tcp  59065  status
1000111   udp875  rquotad
1000112   udp875  rquotad
1000111   tcp875  rquotad
1000112   tcp875  rquotad
1000051   udp  42402  mountd
1000051   tcp  44691  mountd
1000052   udp  34709  mountd
1000052   tcp  48952  mountd
1000053   udp  44983  mountd
1000053   tcp  48897  mountd
1000032   tcp   2049  nfs
1000033   tcp   2049  nfs
1000034   tcp   2049  nfs
1002272   tcp   2049  nfs_acl
1002273   tcp   2049  nfs_acl
1000032   udp   2049  nfs
1000033   udp   2049  nfs
1000034   udp   2049  nfs
1002272   udp   2049  nfs_acl
1002273   udp   2049  nfs_acl
1000211   udp  45895  nlockmgr
1000213   udp  45895  nlockmgr
1000214   udp  45895  nlockmgr
1000211   tcp  40840  nlockmgr
1000213   tcp  40840  nlockmgr
1000214   tcp  40840  nlockmgr
程序代号   NFS版本 数据包类型  端口   服务名称

#2.针对nfs这个程序检查其相关的软件的软件版本信息(仅查看tcp数据包)
[root@nfs_server ~]# rpcinfo -t localhost nfs
program 100003 version 2 ready and waiting
program 100003 version 3 ready and waiting
program 100003 version 4 ready and waiting
可以发现提供NFS的共有三种,分别是2、3、4、版

上面的信息中需要除了程序名称与对应的端口可以与netstat -lntup输出的结果作对比之外,还需要注意到NFS的版本支持。新的NFS版本传输速度较快,由上表看,我们的NFS支持到第四版。如果rpcinfo无法输出,那就表示注册的数据有为题,可能需要重新启动rpcbind与nfs。

2.5 NFS的连接查看

在NFS服务器设置妥当之后,我们可以在Server端自我测试一下是否可以连接。具体做法就是用showmount这个命令查看

[root@nfs_server ~]# showmount [-a|-e] [hostname|IP]
选项与参数:
-a:显示当前主机与客户端的NFS连接共享的状态
-e:显示某台主机的/etc/exports所共享的目录数据

#显示配置好的exports共享目录信息
[root@nfs_server ~]# showmount -e localhost
Export list for localhost:
/wwwdir 192.168.136.0/24

当要扫描某一台主机提供的NFS共享目录时,就使用showmount -e IP(或hostname)即可,这也是NFS客户端最常用的命令,另外NFS关于目录权限设置的数据非常多。/etc/exports只是比较特别的权限参数而已,还有许多默认参数。这些默认参数在哪里?检查一下/var/lib/nfs/etab就知道了。

[root@nfs_server ~]# tail /var/lib/nfs/etab 
/wwwdir 192.168.136.0/24(rw,sync,wdelay,hide,nocrossmnt,secure,no_root_squash,no_all_squash,no_subtree_check,secure_locks,acl,anonuid=65534,anongid=65534,sec=sys,rw,no_root_squash,no_all_squash)
#上面可以看出除了rw、sync等。其实还有anonuid及anongid等的设置

通过上面的案例分析anonuid和anongid对比/etc/passwd以及/etc/group,会发现记录的用户和组是nfsnobody,这个账号在不同的版本中可能是不一样。另外如果有其他客户端挂载服务器端的NFS文件系统,那么该客户端与文件系统信息就会被记录到/var/lib/nfs/xtab里去。

[root@nfs_server ~]# grep "65534" /etc/passwd
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
[root@nfs_server ~]# grep "65534" /etc/group
nfsnobody:x:65534:

如果想要重新处理/etc/exports文件,当重新设置完/etc/exports后需不需要重新启动NFS?不需要。如果重新启动NFS的话,要得再向RPC注册,很麻烦。这个时候就可以通过exportfs这个NFS文件系统维护命令来处理。

[root@nfs_server ~]# exportfs [-a|-r|-u|-v]
选项参数:
 -a:全部挂载(或卸载)/etc/exports中的设置
 -r:重新挂载/etc/exports里面的设置,此外也更新/etc/exports及/var/lib/nfs/xtab的内容
 -u:卸载某一个目录
 -v:在export的时候,将共享的目录显示在屏幕上

#重新挂载一次/etc/exports的设置
[root@nfs_server ~]# exportfs -arv
exporting 192.168.136.0/24:/wwwdir

#将已经共享的NFS目录资源全部卸载
[root@nfs_server ~]# exportfs -auv
#这时如果再使用showmount -e localhost就看不到任何资源了

这样就可以重新exportfs我们记录在/etc/exports文件中的目录数据了。但是要特别留意,如果仅处理配置文件,但并没有相对应的目录等,就会出现警告信息,所以要先创建共享目录。

2.6 NFS的安全性

(1)防火墙的设置问题与解决方案

一般来说NFS服务器是对内部网络开放的,不会对内特网开放。然而,如果有特殊需求的话,可能会跨不同的网络。但是NFS的防火墙很不好弄,为什么呢?因为除了固定的port111、2049之外,还有很多由rpc.mountd、rpc.rquotad等服务开启的端口不固定,所以iptables就很难设定规则,那怎么办呢?

为了解决这个问题,Centos6.x提供了一个固定NFS服务端口的配置文件,那就是/etc/sysconfig/nfs。在这个文件中就能够制定特定的端口,这样每次启动NFS时,相关服务启动的端口就会固定,这样就能设置防火墙了。那么需要修改的RPC服务有哪些呢?主要有mountd、rquotad、nlockmgr这3个。

[root@nfs_server ~]# sed -i 's@#RQUOTAD_PORT=875@RQUOTAD_PORT=875@g' /etc/sysconfig/nfs 
[root@nfs_server ~]# sed -i 's@#LOCKD_TCPPORT=32803@LOCKD_TCPPORT=32803@g' /etc/sysconfig/nfs   
[root@nfs_server ~]# sed -i 's@#LOCKD_UDPPORT=32769@LOCKD_UDPPORT=32769@g' /etc/sysconfig/nfs   
[root@nfs_server ~]# sed -i 's@#MOUNTD_PORT=892@MOUNTD_PORT=892@g' /etc/sysconfig/nfs   
[root@nfs_server ~]# grep -nE "RQUOTAD_|LOCKD_T|LOCKD_U|MOUNTD_P" /etc/sysconfig/nfs  
12:RQUOTAD_PORT=875
20:LOCKD_TCPPORT=32803
22:LOCKD_UDPPORT=32769
57:MOUNTD_PORT=892
把前面的注释去掉,端口的值可以自行设定也可以不变

[root@nfs_server ~]# /etc/init.d/nfs restart
Shutting down NFS daemon:  [  OK  ]
Shutting down NFS mountd:  [  OK  ]
Shutting down NFS quotas:  [  OK  ]
Shutting down NFS services:[  OK  ]
Shutting down RPC idmapd:  [  OK  ]
Starting NFS services: [  OK  ]
Starting NFS quotas:   [  OK  ]
Starting NFS mountd:   [  OK  ]
Starting NFS daemon:   [  OK  ]
Starting RPC idmapd:   [  OK  ]
[root@nfs_server ~]# rpcinfo -p|grep -E "rquota|mount|nlock"
1000111   udp875  rquotad
1000112   udp875  rquotad
1000111   tcp875  rquotad
1000112   tcp875  rquotad
1000051   udp892  mountd
1000051   tcp892  mountd
1000052   udp892  mountd
1000052   tcp892  mountd
1000053   udp892  mountd
1000053   tcp892  mountd
1000211   udp  32769  nlockmgr
1000213   udp  32769  nlockmgr
1000214   udp  32769  nlockmgr
1000211   tcp  32803  nlockmgr
1000213   tcp  32803  nlockmgr
1000214   tcp  32803  nlockmgr

假设想要开放192.168.136.0/24这个网段的用户能够使用这台服务器的NFS资源,需要这样配置

[root@nfs_server ~]# iptables -A INPUT -i eth0 -p tcp -s 192.168.136.0/24 -m multiport --dport 111,2049,875,32803,32767,892 -j ACCEPT
[root@nfs_server ~]# iptables -A INPUT -i eth0 -p udp -s 192.168.136.0/24 -m multiport --dport 111,2049,875,32803,32767,892 -j ACCEPT

(2)使用/etc/exports设置更安全的权限

这就要逻辑的思考了,但是要在便利与安装之间找到平衡点,善用root_squash和all_squash等功能,再利用anonuid等的设置来规范主机的用户部分。

(3)分区计划

如果有多台linux主机,并且打算彼此共享目录,那么在安装的时候可以规划处一块分区作为预留之用。

3.NFS服务器关机注意事项

当NFS使用的这个RPC服务在客户端连接上服务器时,那么服务器想要关机。那可能就会成为“不可能的服务”。如果服务器上面还有客户端连接,那么可能需要等待几个钟头才能够正常关机。所以,建议NFS服务器想要关机之前,先关掉rpcbind和nfs的这两个进程,如果无法将这两个进程关掉,那么先用netstat -lutp找出PID,然后再kill将它关掉,这样才能保证正常关机。

当然还可以利用showmount -a localhost来查出哪个客户端还在连接,可以告诉他们,让他们先挂断服务。

4.NFS客户端的设置

既然NFS服务器最主要的工作就是共享系统给网络上其他的客户端,所以客户端当然需要挂载NFS服务器的文件系统,那么NFS服务器可以通过防火墙来保护自己,那么客户端挂载文件系统之后不需要保护自己吗?

4.1 手动挂载NFS服务器共享的资源

客户端挂载文件系统,可以这样做:

(1)确认本地端已经启动了rpcbind服务。

(2)扫描NFS服务器共享的目录有哪些,并了解我们是否可以使用(showmount)

(3)在本地端建立预计要挂载的目录(mkdir)

(4)利用mount将远程主机直接挂载到相关目录

假如客户端在192.168.136.117(ping)这台机器上,而nfs服务器在192.168.136.118这台机器上,那么赶紧来检查一下我们是否已经启动rpcbind服务,另外看看nfs服务器主机有什么可用的目录。

#1.客户端启动必备的服务
[root@ping ~]# /etc/init.d/rpcbind start
Starting rpcbind:  [  OK  ]
[root@ping ~]# /etc/init.d/nfslock start
Starting NFS statd:[  OK  ]
#客户端已经启动nfslock的话,客户端也要启动才能生效

#2.查看服务器给我们提供了哪些可以使用的资源
[root@ping ~]# showmount -e 192.168.136.118
Export list for 192.168.136.118:
/wwwdir 192.168.136.0/24 <==这是一会儿要挂载的目录

接下来想要姜元成主机的/wwwdir挂载到本地端主机的/home/nfs/public目录下,所以就需要在本地端主机先建立起这个挂载点的目录,然后就可以用mount这个命令直接挂载了。

#3.挂载远程主机的/wwwdir目录
[root@ping ~]# mkdir -p /home/nfs/public
[root@ping ~]# mount -t nfs 192.168.136.118:/wwwdir /home/nfs/public
#语法:-t nfs用于指定文件系统类型
192.168.136.118:/wwwdir  指定某一台主机的某个目录
/home/nfs/public   客户端要挂载的目录、

#4.使用df或者mount查看挂载之后的情况
[root@ping ~]# df
Filesystem   1K-blocksUsed Available Use% Mounted on
/dev/sda4  8717516 1162724   7105308  15% /
tmpfs   502056   0502056   0% /dev/shm
/dev/sda1   194241   34853149148  19% /boot
/dev/sda2  9948012  111408   9324604   2% /var
 192.168.136.118:/wwwdir
   8717568 1162752   7105280  15% /home/nfs/public

如何将挂载的目录卸载呢?可以用umount命令

[root@ping ~]# umount /home/nfs/public/

4.2 客户端的挂载参数与开机挂载

除了NFS服务器需要保护之外,客户端也需要自我保护,这可以通过mount挂载指定参数实现,下图列出了mount命令的主要参数

文件服务器之NFS服务器

常用选项:

-t 后面指定常用文件系统类型,ext, ext2, ext3, ext4,xfs

-o 选项的选择,后面指定要挂载的参数

-a 所有的,挂载挂载/etc/fstab中提到的所有(给定类型的)文件系统。

如果NFS服务器所提供的只是类似/home下面的个人数据,应该不需要可执行、SUID与设备文件,因此在挂载的时候,可以使用下面的命令:

[root@ping ~]# mount -t nfs -o nosuid,noexec,nodev,rw 192.168.136.118:/wwwdir /home/nfs/public
[root@ping ~]# mount |grep "addr"
 192.168.136.118:/wwwdir on /home/nfs/public type nfs (rw,noexec,nosuid,nodev,vers=4,addr=192.168.136.118,clientaddr=192.168.136.117)

这样挂载这个文件系统就只能进行数据访问,相对来说,对于客户端是比较安全的,所以nousid、noexec、nodev等参数要牢记。

4.3 关于NFS特殊的挂载参数

除了上面的mount参数之外,针对NFS服务器,linux还提供了不少有用的额外参数,这些参数很有用,举例来说由于文件系统对linux系统非常重要,因为在进行任何操作时,只要用到文件系统,那么整个目录树系统就会主动的去查询全部的挂载点。如果nfs服务器与客户端之间的连接因为网络问题,或者是服务器端先关机了没有通知客户端,那么客户端在使用文件系统命令的时候就非常慢,因为必须等到文件系统查找等待时间后,系统才能够继续工作。

为避免出现这些问题,还有一些额外的参数可用,如图所示:

文件服务器之NFS服务器

更多的参数可以man nfs ,通常如果NFS是用在高速运行的环境中的话,建议加上这些参数

[root@ping ~]# umount /home/nfs/public
[root@ping ~]# mount -t nfs -o nosuid,noexec,nodev,rw,bg,soft,rsize=1000,wsize=1000 192.168.136.118:/wwwdir /home/nfs/public

4.4 使NFS开机挂载

我们知道开机就挂在的挂载点与相关参数是写入/etc/fstab文件中的,那NFS能不能写入/etc/fstab中呢?非常可惜的是,不可以,为什么呢?分析开机启动流程,我们可以发现网络的启动是在本机挂载之后,因此当你利用/etc/fstab尝试挂载NFS时,系统由于尚未启动网络,所以无法挂载成功。那怎么办呢?写入到/etc/rc.d/rc.local即可。

[root@ping ~]# echo "mount -t nfs -o nosuid,noexec,nodev,rw,bg,soft,rsize=1000,wsize=1000 192.168.136.118:/wwwdir /home/nfs/public" >>/etc/rc.local 

4.5 自动挂载autofs的使用

在一般NFS文件系统的使用过程中,如果客户端要使用服务器所提供的NFS文件系统,要么就是在/etc/rc.d/rc.local中设置开机时挂载,要么就需要登录后手动挂载,此外客户端需要预先手动建立好挂载点目录,然后挂载上来,但是这样会有一些小问题。

(1)NFS文件系统与网络连接的困扰

NFS服务器与客户端的连接或许不会永远存在,而RPC这个服务如果挂载了NFS服务器后,任何一方脱机都可能造成另一方总是在等待超时。而且挂载的NFS文件系统可能又不经常被使用,若不挂在的话需要使用时又得通知管理员,这样很不方便。

那么为了解决这个问题,可不可以让客户端在使用NFS文件系统的需求是才让系统自动挂载?

当NFS文件系统使用完毕后,可不可以让NFS自动卸载,以避免可能的RPC错误?

那么有没有办法实现上面的功能呢?有的,可以用autofs这个服务来实现。

(2)autofs的配置的概念

autofs这个服务在客户端计算机上面,会持续的检测某个指定的目录,并预先设置当使用到该目录下的某个子目录时,将会取得来自服务器端的NFS文件系统资源,并自行自动挂载的操作。拓扑图如下图所示:

文件服务器之NFS服务器

如上图所示,我们的autofs的主要配置文件为/etc/auto.master。这个文件中的内容很简单我们只要定义出需要挂载的目录(/home/nfsfile)即可,这个目录就是autofs要持续监测的目录,在/etc/auto.nfs(这个文件名可以自定义)里面则可以定义出每个子目录所欲挂载的NFS目录资源。

举例来说,当我们在客户端要使用/home/nfsfile/wwwdir的数据时,此时autofs才会去192.168.136.118服务器上挂载/wwwdir,当隔了5分钟没有使用该目录下的数据后,则客户端将会主动卸载/home/nfsfile/wwwdir。

(3)安装autofs

[root@ping ~]# yum install autofs -y

(4)建立主配置文件/etc/auto.master,并指定检测的特定目录

这个主要配置文件的内容很简单,只要在要被检测的目录及数据对应文件即可,数据对应文件文件名是可以自行定义的,在这个例子中我使用/etc/auto.nfs来命名。

[root@ping ~]# cp /etc/auto.master{,.bak}
[root@ping ~]# >/etc/auto.master
[root@ping ~]# echo "/home/nfsfile /etc/auto.nfs" >>/etc/auto.m
auto.master  auto.master.bak  auto.misc
[root@ping ~]# echo "/home/nfsfile /etc/auto.nfs" >>/etc/auto.master
[root@ping ~]# cat /etc/auto.master
/home/nfsfile /etc/auto.nfs

提示:需要注意的是/home/nfsfile目录不需要实现存在,因为autofs会主动建立该目录。如果提前建立了反而会出现问题。

(5)建立数据对应文件内(/etc/auto.nfs)的挂载信息与服务器对应的资源

自行设置/etc/auto.nfs文件

格式:

[本地端子目录] [-挂载参数] [服务器所提供的目录]

选项与参数:

[本地端子目录] :指的是在/etc/auto.master内指定的目录及子目录

[-挂载参数]:就是前一小节提到的rw、bg、soft等参数,可有可无

[服务器所提供的目录]:例如192.168.136.118:/wwdir等

[root@ping ~]# echo "wwwdir -rw,bg,no_root_squash 192.168.136.118:/wwwdir" >>/etc/auto.nfs
[root@ping ~]# cat /etc/auto.nfs
wwwdir -rw,bg,no_root_squash 192.168.136.118:/wwwdir

(6)实际操作与查看

启动autofs

[root@ping ~]# /etc/init.d/autofs start
Loading autofs4:   [  OK  ]
Starting automount:[  OK  ]

现在我们之前并没有挂载NFS服务器的资源目录,好了我们来看一下几个重要的数据吧。先看看/home/nfsfile会不会主动被建立?然后如果进入/home/nfsfile/wwwdir目录文件系统如何变化?

[root@ping ~]# ls -ld /home/nfsfile/
drwxr-xr-x 2 root root 0 Nov  9 21:54 /home/nfsfile/
[root@ping ~]# cd /home/nfsfile/wwwdir
#注意这个地方如果只进入到/home/nfsfile/目录ls或者按tab键是找不到目录wwwdir的,只能够手敲出来,这时cd进入目录才自动挂载。
[root@ping wwwdir]# mount|grep "nfsfile"
192.168.136.118:/wwwdir on /home/nfsfile/wwwdir type nfs (rw,no_root_squash,sloppy,vers=4,addr=192.168.136.118,clientaddr=192.168.136.117)
[root@ping wwwdir]# df /home/nfsfile/wwwdir/
Filesystem   1K-blocksUsed Available Use% Mounted on
192.168.136.118:/wwwdir
   8717568 1162752   7105280  15% /home/nfsfile/wwwdir