NFS(Network File System,网络文件系统)是一种在企业内部网络使用比较普遍的文件共享服务,主要用于Linux以及类UNIX系统之间的文件共享。它采用C/S工做模式,在NFS服务器上将某个目录设置为共享目录,而后在客户端能够将这个目录挂载到本地使用。NFS服务诞生于上世纪80年代,虽然在CentOS7.6系统中采用的是目前最新的NFSv4版本,但因为NFS服务自己比较简单,尤为是在权限设置方面功能比较弱,因此若是对NFS服务设置不当,将会在企业网络中产生比较严重的安全隐患。本文就NFS服务的用户身份映射问题进行了分析,并给出了推荐的配置和使用方法。文中准备了两台Linux虚拟机来搭建实验环境,虚拟机所使用的操做系统版本为CentOS7.6。其中名为Server的虚拟机IP地址是192.168.80.10,名为Client的虚拟机IP地址是192.168.80.101。vim
NFS服务在CentOS7系统中默认已经安装,但并未运行,于是首先须要在虚拟机Server中执行“systemctl start nfs”命令启动服务,而后再执行“systemctl enable nfs”命令将服务设置为开机自动运行。
在服务器端新建一个/var/share目录,并在其中建立一个测试文件test.txt。安全
[root@server ~]# mkdir /var/share [root@server ~]# echo 'hello,world!' > /var/share/test.txt
下面将/var/share目录设置为NFS共享,并容许全部客户端访问。
NFS服务的主配置文件是/etc/exports,在/etc/exports文件中,每一行定义一个共享目录。利用vi编辑器打开配置文件/etc/exports,在其中增长下面的一行:服务器
[root@server ~]# vim /etc/exports /var/share *(ro,sync)
在设置项中,“/var/share”表示要共享的目录,“”表示全部客户端均可以访问该共享目录,选项“ro”用于定义客户端的权限为read-only(只读),选项“sync”表示启用同步模式,能够将内存中的数据实时写入到磁盘中。
修改完配置文件以后,重启NFS服务生效。[root@server ~]# systemctl restart nfs
而后在客户端就能够将共享目录挂载到本地使用。网络
[root@client ~]# mkdir /mnt/nfs #建立挂载点目录 [root@client ~]# mount -t nfs 192.168.80.10:/common /mnt/nfs #挂载共享目录 [root@client ~]# ls /mnt/nfs #查看共享目录中的文件 test.txt
因为NFS服务自己并不具有用户身份验证的功能,而仅支持基于客户端IP进行认证。也就是说,咱们在对NFS服务进行权限设置时,不能针对用户来分配权限,而只能针对客户端IP进行权限分配。因此若是但愿IP地址为192.168.80.101的客户端能够对共享目录执行写入操做,那么能够在服务器端对配置文件进行以下修改,添加客户端的IP,并设置权限选项为“rw(read-write)”:编辑器
[root@server ~]# vim /etc/exports /var/share *(ro,sync) 192.168.80.101(rw,sync)
修改完成后,须要重启NFS服务生效。可是若是NFS共享正在被某些服务器使用的话,那么NFS服务是不容许随便重启的,因此在CentOS系统中提供了exportfs命令,能够在不重启NFS服务的状况下,从新加载/etc/exports文件,使得新的设置项生效。exportfs命令的经常使用选项有:-a(所有挂载或所有卸载)、-r(从新挂载)、-v(显示详细信息),一般都是将这三个选项组合使用。下面经过exportfs命令使得咱们刚才所作的设置生效。ide
[root@server ~]# exportfs -arv exporting 192.168.80.101:/var/share exporting *:/var/share
在客户端先将共享目录卸载,而后再从新挂载,以使得服务器端的设置生效。但在对共享目录进行写入测试时失败。测试
[root@Client ~]# umount /mnt/share #卸载共享目录 [root@Client ~]# mount 192.168.80.10:/var/share /mnt/share #从新挂载共享目录 [root@Client ~]# touch /mnt/share/a.txt #写入测试失败 touch: 没法建立"/mnt/share/a.txt": 只读文件系统
这是因为虽然在服务器端的配置文件/etc/exports中设置了容许用户对/var/share目录具备读写权限,但在操做系统层面,用户对/var/share目录却不具有写入权限。于是要实现对共享目录的写入操做,必需要保证在NFS服务和操做系统两个层面所有都具备写入权限才能够。
如何使得客户端能够在操做系统层面对共享目录具备写入权限,这就要涉及到用户身份映射问题。ui
NFS服务虽然不具有用户身份验证的功能,可是NFS提供了一种身份映射的机制来对用户身份进行管理。当客户端访问NFS服务时,服务器会根据状况将客户端用户的身份映射成NFS匿名用户nfsnobody。nfsnobody是由NFS服务在系统中自动建立的一个程序用户帐号,该帐号不能用于登陆系统,专门用做NFS服务的匿名用户帐号。操作系统
[root@Server ~]# grep nfsnobody /etc/passwd #查看nfsnobody用户的信息。 nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
所谓用户身份映射,是指当客户端访问NFS服务器时,会自动被视做服务器中的nfsnobody用户,并按照该用户的权限设置去执行操做。可是并不是全部的客户端都会被映射为nfsnobody用户,在/etc/exports配置文件中提供了如下选项,以决定是否将NFS客户端映射为nfsnobody用户:rest
咱们以前之因此没法在客户端执行写入操做,是由于尚未在系统层面赋予nfsnobody用户对共享目录/var/share具备写入权限。这里经过设置ACL规则赋予nfsnobody用户rwx权限。
`[root@Server ~]# setfacl -m u:nfsnobody:rwx /var/share``
而后在客户端从新挂载共享目录,并测试可否写入。
[root@Client ~]# umount /mnt/share [root@Client ~]# mount -t nfs 192.168.80.10:/var/share /mnt/share [root@Client ~]# touch /mnt/share/b.txt
能够看到此时客户端能够写入,而且所建立文件的全部者正是nfsnobody。
[root@Client ~]# ll /mnt/share/b.txt -rw-r--r--. 1 nfsnobody nfsnobody 0 3月 21 07:39 /mnt/share/b.txt
因为客户端当前所使用的用户身份是root,默认状况下,当客户端访问NFS服务器时,在服务器端会将其用户身份映射为nfsnobody,因此在服务器端只要赋予nfsnobody用户对共享目录具备写入权限,那么客户端天然就能够写入了。
下面咱们再验证一下no_root_squash设置项,即root用户不进行身份映射。
首先在服务器端修改配置文件/etc/exports,为/var/share共享目录添加no_root_squash选项。
[root@server ~]# vim /etc/exports #修改配置文件 /var/share *(rw,no_root_squash,sync) [root@Server ~]# exportfs -arv #从新加载服务 exporting *:/var/share
而后去掉对共享目录/var/share所设置的ACL规则,取消nfsnobody用户对该目录的写入权限。[root@Server ~]# setfacl -b /var/share
最后在客户端从新挂载共享目录,并测试可否写入。
[root@Client ~]# umount /mnt/share [root@Client ~]# mount -t nfs 192.168.80.10:/var/share /mnt/share [root@Client ~]# touch /mnt/share/c.txt [root@Client ~]# ll /mnt/share/c.txt -rw-r--r--. 1 root root 0 4月 14 17:08 /mnt/share/c.txt
能够发现,此时客户端仍然是能够写入的。由于对于NFS服务器而言,访问共享目录的客户端就是服务器中的root用户,对共享目录具备彻底权限。因此no_root_squash选项会产生很大的安全隐患,通常状况下都不建议采用。
若是客户端所使用的用户身份不是root,而是一个普通用户,那么默认状况下在服务器端会将其视做其它用户(other)。下面在客户端以普通用户的身份继续进行测试。
首先在服务器端修改配置文件/etc/exports,将共享目录/var/share中的no_root_squash选项去掉,从新加载服务以后,再次经过设置ACL规则的方式赋予nfsnobody用户读写执行权限。
[root@server ~]# vim /etc/exports #修改配置文件 /var/share *(rw,sync) [root@Server ~]# exportfs -arv #从新加载服务 exporting *:/var/share #经过设置ACL赋予nfsnobody用户rwx权限 [root@Server ~]# setfacl -m u:nfsnobody:rwx /var/share
在客户端从新挂载共享,并测试以root用户身份能够正常写入。
[root@Client ~]# umount /mnt/share [root@Client ~]# mount 192.168.80.10:/var/share /mnt/share [root@Client ~]# touch /mnt/share/d.txt [root@Client ~]# ll /mnt/share/d.txt -rw-r--r--. 1 nfsnobody nfsnobody 0 4月 14 17:29 /mnt/share/d.txt
下面在客户端建立一个admin用户,并设置密码。
[root@Client ~]# useradd admin [root@Client ~]# echo 123 | passwd --stdin admin
切换到admin用户身份,尝试向共享目录中写入文件,写入失败,可是能够读取目录中的内容。于是若是客户端是以普通用户的身份访问NFS共享,那么默认状况下在服务器端并不将其映射为nfsnobody,而是视做其余用户(other)。
[root@Client ~]# su - admin [admin@Client ~]$ touch /mnt/share/e.txt touch: 没法建立"/mnt/share/e.txt": 权限不够 [admin@Client ~]$ cat /mnt/share/e.txt
下面在服务器端继续修改配置文件/etc/exports,在共享设置中添加“all_squash”选项,将全部客户端用户均映射为nfsnobody。
[root@server ~]# vim /etc/exports #修改配置文件 /var/share *(rw,sync,all_squash) [root@Server ~]# exportfs -arv #从新加载服务 exporting *:/var/share
而后在客户端再次从新挂载共享(具体操做从略),此时以admin用户身份就能够写入了,而且能够发现所建立文件的全部者一样是nfsnobody。
[admin@Client ~]$ touch /mnt/share/e.txt [admin@Client ~]$ ll /mnt/share/e.txt -rw-rw-r--. 1 nfsnobody nfsnobody 0 4月 14 17:37 /mnt/share/e.txt
在使用NFS共享的过程当中,有时还可能会遇到用户身份重叠的问题。所谓用户身份重叠,是指在NFS服务采用默认设置(用户身份映射选项为root_squash)时,若是在服务器端赋予某个用户对共享目录具备相应权限,并且在客户端刚好也有一个具备相同uid的用户,那么当在客户端以该用户身份访问共享时,将自动具备服务器端对应用户的权限。下面举例予以说明。
首先在服务器端将/var/share共享还原为默认设置,而且取消/var/share目录针对nfsnobody用户的ACL规则,具体操做从略。
假设服务器端存在一个名为teacher的用户帐号,uid为1246,将该用户设置为共享目录的全部者。
[root@Server ~]# id teacher #查看teacher用户的身份信息` uid=1246(teacher) gid=1246(teacher) 组=1246(teacher #将teacher用户设置为/var/share目录的全部者 [root@Server ~]# chown teacher /var/share [root@Server ~]# ll -d /var/share drwxr-xr-x. 2 teacher root 45 4月 14 17:37 /var/share
下面在客户端进行操做。首先还是从新挂载共享目录,而后将原先admin用户的uid也改成1246。
[root@Client ~]# usermod -u 1246 admin [root@Client ~]# id admin uid=1246(admin) gid=1002(admin) 组=1002(admin)
而后以admin用户身份测试可否对共享目录执行写入操做,发现能够正常写入,而且所建立文件的全部者是admin。
[root@Client ~]# su - admin [admin@Client ~]$ touch /mnt/share/f.txt [admin@Client ~]$ ll /mnt/share/f.txt -rw-rw-r--. 1 admin admin 0 4月 14 17:47 /mnt/share/f.txt
在服务器端查看admin用户所建立的文件,发现全部者则是teacher。
[root@Server ~]# ll /var/share/f.txt -rw-rw-r--. 1 teacher 1002 0 4月 14 17:47 /var/share/f.txt
这是由于对于Linux系统而言,区分不一样用户的惟一标识就是uid,至于用户名只是为了方便人类理解。因此在系统层面,不管是teacher用户仍是admin用户,只要他们的uid同样,就认为是同一个用户。但也正是由于这个缘由,才会致使出现用户身份重叠的问题,对于NFS服务而言,这也是一个比较严重的安全隐患。
如何避免用户身份重叠呢?能够从如下两个方面着手: