一、 nfs(网络文件系统)原理
nfs网络文件系统挂载的原理示意图如图12-1所示。其中,NFS服务器设定好了分享出来的/home/shares(可以是其他目录)这个目录后,其他的客户端就可以将这个目录挂载到自己系统上的/mnt/nfs挂载点(挂载点可以自定),只要在PC1系统中进入/mnt/nfs目录内,就可以看到nfs服务器系统内的/home/shares目录下的所有数据(要有相应的权限),/home/shares就好像自己PC中的一个分区(但不占用磁盘空间)。用户可以使用cp、cd、 mv、rm等磁盘或文件相关的指令进行操作。
图12-1 NFS网络文件共享示意图 |
虽然nfs有属于自己的协议和端口号,但是在传送数据或其他相关信息时,NFS使用的是远程过程调用(Remote Procedure Call,RPC)协议来协助NFS本身的运作。
rpc远程进程调用
rpc即远程进程调用。当使用某些服务来进行远程联机的时候,主机的IP地址、服务的端口号及对应到的服务PID等信息都需要管理与对应,管理端口的对应与服务相关性的工作就是rpc的任务。
nfs本身的服务并没有提供数据传递的协议,因此,nfs使用rpc来实现网络传输功能。nfs本身就是一个使用rpc的程序,换句话说,nfs是rpc服务器。当然,不但运行nfs的服务器需要启动rpc的服务,要挂载nfs文件系统的客户端,也需要同步启动rpc,这样服务器端与客户端才能由rpc的协议进程序端口的对应,Linux系统默认时启动这一服务。
rpc与rpc对应的端口号是111
二、nfs服务的配置
服务器端软件:安装nfs-utils和rpcbind(portmap)
客户端软件:nfs-utils
服务器端:rpc服务重启时,清理了缓存,所以nfs要重启。Nfs重启时,rpc不需要重启
命令:
yum –y install rpcbind nfs-utils
service rpcbind start
service nfs start
chkconfig nfs on //服务开机自启
exports //查看共享目录和对应主机
showmount -e 远程主机 //查看远程主机提供挂载目录的信息mount 192.168.122.1:/share /mnt //挂载
/etc/exports 文件格式
/share(服务器对外提供的共享目录) 192.168.122.1 192.168.122.2 (允许哪些主机挂载,可挂载多台,以空格为分隔符)
/etc/fstab 开机自动挂载文件
# /etc/fstab
# Created by anaconda on Mon Oct 31 23:44:57 2016
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
/dev/mapper/VolGroup-lv_root / ext4 defaults 1 1
UUID=179df2d0-30d1-4442-bc21-62966d4db830 /boot ext4 defaults 1 2
/dev/mapper/VolGroup-lv_swap swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
192.168.122.1:/share /yum nfs defaults 0 0
三、实验过程
servera做服务端。Serverb做客户端
servera创建一个共享目录/share,serverb远程挂载
开始时,在/etc/exports 文件中写
客户端为root时:
/share 192.168.122.0/24(ro,async)
serverb挂载到/test目录下,在/test目录下操作
可以cp,不可以touch,报错是
Read only File system
之后在servera端将 /share 192.168.122.0/24(ro,async) 改为
/share 192.168.122.0/24(rw,async)
可以cp,不可以touch,报错是
sermission denied
这时候,去servera端将/share目录权限改成777 chmod 777 /share
这时候可以创建,并可以看到该文件的所有者是nfsnobody,uid是65534
结论:root在服务端被映射成nfsnobody,此时将目录权限改成正常权限,并且让客户端用户有写的权限有两种方法:
●将 /share 192.168.122.0/24(rw,async) 改成
/share 192.168.122.0/24(rw,async,no_root_squash)
●将nfsnobody加入/share 的控制访问链表,其权限为rwx
客户端为普通用户mark,uid为500:
此时 /etc/exports 是
/share 192.168.122.0/24(rw,no_root_squash,async)
在 /test 目录下,可以cp,不可以touch,报错是 Permission denied
这是将 /share 目录权限改为777,可以创建,并且该文件的所有者是 uid为500的用户
结论:普通用户在服务端映射的是相同uid的用户的身份,此时将目录改为正常权限,将uid等于500的用户加入/share 的访问控制链表,即可。
四、结论
总结:客户端用户在服务端共享目录下的权限,来自三个方面:
1.服务本身的权限
2.目录本身的权限
3.用户对这个目录的权限
客户端与服务端用户的映射关系
普通用户:
●如果明确设定了普通用户被压缩的身份,那么此时客户端用户的身份转换为指定用户,(rw,all_squash,anonuid=500,anongid=500)
●如果NFS server上面有同名用户,那么此时客户端登录账户的身份转换为NFS server上面的同名用户(rw,)
●如果没有明确指定,也没有同名用户,那么此时 用户身份被压缩成nfsnobody
Root用户:
●如果设置no_root_squash,那么此时root用户的身份被映射为为NFS server上面的root。
●如果设置了all_squash、anonuid、anongid,此时root 身份被压缩为指定匿名用户。
●如果没有明确指定,此时root用户被压缩为nfsnobody。
附:/etc/exports文件中的一些参数
rw:read-write,可读写; 注意,仅仅这里设置成读写客户端还是不能正常写入,还要正确地设置共享目录的权限,参考问题7
ro:read-only,只读;
sync:文件同时写入硬盘和内存;
async:文件暂存于内存,而不是直接写入硬盘;
no_root_squash:NFS客户端连接服务端时如果使用的是root的话,那么对服务端分享的目录来说,也拥有root权限。显然开启这项是不安全的。
root_squash:NFS客户端连接服务端时如果使用的是root的话,那么对服务端分享的目录来说,拥有匿名用户权限,通常他将使用nobody或nfsnobody身份;
all_squash:不论NFS客户端连接服务端时使用什么用户,对服务端分享的目录来说都是拥有匿名用户权限;
anonuid:匿名用户的UID值,通常是nobody或nfsnobody,可以在此处自行设定;
anongid:匿名用户的GID值。
一个问题:在共享存储主机上对外共享的目录文件的所属者、所属组没有问题。但是到了客户端上全部变为nobody。通过修改该文件,得以解决。
[root@storage ~]# vim /etc/idmapd.conf
[Mapping]
Nobody-User = nobody
Nobody-Group = nobody
[Translation]
# Translation Method is an comma-separated, ordered list of
# translation methods that can be used. Distributed methods
# include "nsswitch", "umich_ldap", and "static". Each method
# is a dynamically loadable plugin library.
# New methods may be defined and inserted in the list.
# The default is "nsswitch".
Method = nsswitch
# Optional. This is a comma-separated, ordered list of
# translation methods to be used for translating GSS
# authenticated names to ids.
# If this option is omitted, the same methods as those
# specified in "Method" are used.
#GSS-Methods = <alternate method list for translating GSS names>
#-------------------------------------------------------------------#
# The following are used only for the "static" Translation Method.
[General]
#Verbosity = 0
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
sity = 0
# The following should be set to the local NFSv4 domain name
# # The default is the host's DNS domain name.
# Domain = 361way.com
# The default is the host's DNS domain name.
Domain = 361way.com
# service rpcidmapd restart # 重启idmapd服务