一)NFS的概念
NFS(Network File System)是RPC Server的一种。
RPC就是Remote Procedure Call,它在系统中就是Portmap这个软件。
# netstat -tulnp
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
...
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN portmap
...
到底RPC这个程序有什么作用呢?
1)作为NFS的client端,可能有很多不同的程序要求向NFS server提交服务请求(比如要求传输某个文件)。这些程序首先与server端得RPC通信。
2)运行在NFS server端的RPC管理本机的端口对应关系,并在接收到客户端程序的请求后向客户端汇报端口情况。
同时,在server端,还运行着NFS daemon程序,它们启动时要向RPC注册,从而使RPC能够了解NFS这个服务的各项功能的端口号,PID,NFS在主机所监听的IP等。
3)客户端得到RPC送来的端口信息后,就能直接与NFS daemon程序通信。后者主要负责:a)分析客户端权限;b)访问系统文件。
二)NFS Daemons
1. rpc.nfsd
功能是管理Client端是否能够登入主机,其中包括登入者的ID判断。
2. rpc.mountd
管理NFS的文件使用权限。它会去读NFS的配置文件/etc/exports来比对Client的权限,当通过这一关之后,Client端就可以取得使用NFS文件的权限。
三)NFS的文件存取权限
用来访问NFS Server的客户端的用户账号和NFS Server自身的用户配置可能不同,这带来了安全隐患。一般情况下linux主机会自动以自己的/etc/passwd、/etc/group来比对查询对应的用户名、组名。那么会出现以下几种情况。
1 NFS Server / NFS Client 刚好有相同的账号和组。此时用户可以直接以自己的身份对服务器所提供的文件系统进行存取。
2 NFS Server / NFS Client 两侧UID相同但用户名不同,这个非常危险,相当于说从NFS Client 上登录的用户会以一个完全不同的身份来存取文件,权限控制紊乱了。
3 NFS Server并没有客户端的UID。那么从NFS Client上登录的用户身份在该目录下会被压缩成匿名者,一般NFS的匿名者会把65534作为其UID。在CentOS中,匿名者取名为nfsnobody。
4 如果用户身份是root。在默认情况下,root的身份会被主动压缩成为匿名者。
在客户端以NFS方式去用服务器端的文件系统时,需要以下两个权限。
a. NFS服务器有开放写入的权限(在/etc/exports中设置);
b. 实际的文件权限具有可写入的权限。
当你满足三个条件,才能具有某文件的写入权限。
1) 用户账号,也即UID的相关身份;
2) NFS服务器允许有写入的权限;
3) 文件系统确实具有w的权限。
NFS通常需要与NIS这个可以确认客户端与服务器端身份一致性的服务搭配使用,以避免身份的错乱。
四)服务器端的设置
1. 需要的软件
a. NFS主程序 nfs-utils
b. RPC主程序 portmap
[root@localhost nfs]# rpm -qa | grep portmap
portmap-4.0-65.2.2.1
[root@localhost nfs]# rpm -qa | grep nfs
nfs-utils-1.0.9-44.el5
nfs-utils-lib-1.0.8-7.6.el5
nfs-utils-lib-devel-1.0.8-7.6.el5
2. 启动服务
一般portmap是开机启动的,但是nfs不是。
[root@localhost nfs]# chkconfig --list nfs
nfs 0:off 1:off 2:off 3:off 4:off 5:off 6:off
[root@localhost nfs]# service nfs restart
[root@localhost nfs]# netstat -ltnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:2049 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 2645/portmap
tcp 0 0 0.0.0.0:816 0.0.0.0:* LISTEN 3605/rpc.mountd
nfs启动在端口2049上,这个端口实际上是随机的,所以需要向RPC(portmap - port 111)注册。
[root@localhost nfs]# rpcinfo -p localhost
program vers proto port
100000 2 tcp 111 portmapper
100000 2 udp 111 portmapper
100024 1 udp 736 status
100024 1 tcp 739 status
100011 1 udp 799 rquotad
100011 2 udp 799 rquotad
100011 1 tcp 802 rquotad
100011 2 tcp 802 rquotad
100003 2 udp 2049 nfs
100003 3 udp 2049 nfs
100003 4 udp 2049 nfs
100021 1 udp 36253 nlockmgr
100021 3 udp 36253 nlockmgr
100021 4 udp 36253 nlockmgr
100003 2 tcp 2049 nfs
100003 3 tcp 2049 nfs
100003 4 tcp 2049 nfs
100021 1 tcp 44351 nlockmgr
100021 3 tcp 44351 nlockmgr
100021 4 tcp 44351 nlockmgr
100005 1 udp 813 mountd
100005 1 tcp 816 mountd
100005 2 udp 813 mountd
100005 2 tcp 816 mountd
100005 3 udp 813 mountd
100005 3 tcp 816 mountd
3. 配置/etc/exports
参数的说明:
rw:可读写
ro:只读
sync:数据同步写入到内存及硬盘中
async:数据先缓存在内存中,而非直接写入硬盘
no_root_squash: 登入NFS主机使用共享目录的用户,如果是root身份,那么对于这个共享目录来说,它就具有root的权限
root_squash:登入NFS主机使用共享目录的用户如果是root身份,那么这个用户的权限将被压缩成为匿名用户(nfsnobody)
all_squash:不论登入NFS的用户身份为何,它的身份都会被压缩成为匿名用户(nfsnobody)
anonuid:发生身份“压缩”时,可指定目标用户的UID,来代替nfsnobody
anongid:与anonuid同理,只是这里变成gid
4. NFS联机观察
1) showmount
[root@localhost nfs]# showmount -e localhost
Export list for localhost:
/tmp *
/home/linux *.linux.org
/home/test 192.168.220.128
/home/public (everyone)
2) /var/lib/nfs/etab
[root@localhost nfs]# tail /var/lib/nfs/etab
/home/public 192.168.220.0/24(rw,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,no_subtree_check,secure_locks,acl,mapping=identity,anonuid=65534,anongid=65534)
/home/test 192.168.220.128(rw,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,no_subtree_check,secure_locks,acl,mapping=identity,anonuid=65534,anongid=65534)
/home/linux *.linux.org(rw,sync,wdelay,hide,nocrossmnt,secure,root_squash,all_squash,no_subtree_check,secure_locks,acl,mapping=identity,anonuid=500,anongid=500)
/home/public *(ro,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,no_subtree_check,secure_locks,acl,mapping=identity,anonuid=65534,anongid=65534)
/tmp *(rw,sync,wdelay,hide,nocrossmnt,secure,no_root_squash,no_all_squash,no_subtree_check,secure_locks,acl,mapping=identity,anonuid=65534,anongid=65534)
3)exportfs
-a:全部挂载或者卸载/etc/exports文件内的设置
-r:重新挂载/etc/exports里的设置,此外,也同步更新/etc/exports及/var/lib/nfs/xtab的内容
-u:卸载某个目录,可以和-a一块使用
-v:在exportfs的时候,将共享目录显示在屏幕上
[root@localhost nfs]# exportfs -auv
[root@localhost nfs]# showmount -e localhost
Export list for localhost:
[root@localhost nfs]# tail /var/lib/nfs/etab
[root@localhost nfs]#
[root@localhost nfs]# exportfs -arv
exporting 192.168.220.0/24:/home/public
exporting 192.168.220.128:/home/test
exporting *.linux.org:/home/linux
exporting *:/home/public
exporting *:/tmp
五)NFS客户端的设置
步骤:
1)确认本地端已经启动了portmap服务
2)扫描NFS服务器共享的目录有哪些,并了解我们是否可以使用(showmount)
3)在本地端建立预计要挂载点目录(mkdir)
4) 利用mount将远程主机直接挂载到相关目录