NFS服务的用户身份映射
原文:https://blog.51cto.com/yttitan/2406403
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。
1. NFS的基本配置
NFS服务在CentOS7系统中默认已经安装,但并未运行,因而首先需要在虚拟机Server中执行“systemctl start nfs”命令启动服务,然后再执行“systemctl enable nfs”命令将服务设置为开机自动运行。
在服务器端新建一个/var/share目录,并在其中创建一个测试文件test.txt。
下面将/var/share目录设置为NFS共享,并允许所有客户端访问。
NFS服务的主配置文件是/etc/exports,在/etc/exports文件中,每一行定义一个共享目录。利用vi编辑器打开配置文件/etc/exports,在其中增加下面的一行:
在设置项中,“/var/share”表示要共享的目录,“”表示所有客户端都可以访问该共享目录,选项“ro”用于定义客户端的权限为read-only(只读),选项“sync”表示启用同步模式,可以将内存中的数据实时写入到磁盘中。
修改完配置文件之后,重启NFS服务生效。[root@server ~]# systemctl restart nfs
然后在客户端就可以将共享目录挂载到本地使用。
由于NFS服务本身并不具备用户身份验证的功能,而仅支持基于客户端IP进行认证。也就是说,我们在对NFS服务进行权限设置时,不能针对用户来分配权限,而只能针对客户端IP进行权限分配。所以如果希望IP地址为192.168.80.101的客户端可以对共享目录执行写入操作,那么可以在服务器端对配置文件进行如下修改,添加客户端的IP,并设置权限选项为“rw(read-write)”:
修改完成后,需要重启NFS服务生效。但是如果NFS共享正在被某些服务器使用的话,那么NFS服务是不允许随便重启的,所以在CentOS系统中提供了exportfs命令,可以在不重启NFS服务的情况下,重新加载/etc/exports文件,使得新的设置项生效。exportfs命令的常用选项有:-a(全部挂载或全部卸载)、-r(重新挂载)、-v(显示详细信息),通常都是将这三个选项组合使用。下面通过exportfs命令使得我们刚才所做的设置生效。
在客户端先将共享目录卸载,然后再重新挂载,以使得服务器端的设置生效。但在对共享目录进行写入测试时失败。
这是由于虽然在服务器端的配置文件/etc/exports中设置了允许用户对/var/share目录具有读写权限,但在操作系统层面,用户对/var/share目录却不具备写入权限。因而要实现对共享目录的写入操作,必须要保证在NFS服务和操作系统两个层面全部都具有写入权限才可以。
如何使得客户端可以在操作系统层面对共享目录具有写入权限,这就要涉及到用户身份映射问题。
2. 用户身份映射的原理
NFS服务虽然不具备用户身份验证的功能,但是NFS提供了一种身份映射的机制来对用户身份进行管理。当客户端访问NFS服务时,服务器会根据情况将客户端用户的身份映射成NFS匿名用户nfsnobody。nfsnobody是由NFS服务在系统中自动创建的一个程序用户账号,该账号不能用于登录系统,专门用作NFS服务的匿名用户账号。
所谓用户身份映射,是指当客户端访问NFS服务器时,会自动被视作服务器中的nfsnobody用户,并按照该用户的权限设置去执行操作。但是并非所有的客户端都会被映射为nfsnobody用户,在/etc/exports配置文件中提供了以下选项,以决定是否将NFS客户端映射为nfsnobody用户:
- root_squash,当NFS客户端以root用户身份访问时,映射为NFS服务器的nfsnobody用户。
- no_root_squash,当NFS客户端以root身份访问时,映射为NFS服务器的root用户,也就是要为超级用户保留权限。这个选项会留下严重的安全隐患,一般不建议采用。
- all_squash,无论NFS客户端以哪种用户身份访问,均映射为NFS服务器的nfsnobody用户。
其中默认值是root_squash,即当客户端以root用户的身份访问NFS共享时,在服务器端会自动被映射为匿名账号nfsnobody。
下面将分几种情况分别予以说明。
3. root用户的身份映射
我们之前之所以无法在客户端执行写入操作,是因为还没有在系统层面赋予nfsnobody用户对共享目录/var/share具有写入权限。这里通过设置ACL规则赋予nfsnobody用户rwx权限。
`[root@Server ~]# setfacl -m u:nfsnobody:rwx /var/share``
然后在客户端重新挂载共享目录,并测试能否写入。
可以看到此时客户端可以写入,并且所创建文件的所有者正是nfsnobody。
由于客户端当前所使用的用户身份是root,默认情况下,当客户端访问NFS服务器时,在服务器端会将其用户身份映射为nfsnobody,所以在服务器端只要赋予nfsnobody用户对共享目录具有写入权限,那么客户端自然就可以写入了。
下面我们再验证一下no_root_squash设置项,即root用户不进行身份映射。
首先在服务器端修改配置文件/etc/exports,为/var/share共享目录添加no_root_squash选项。
然后去掉对共享目录/var/share所设置的ACL规则,取消nfsnobody用户对该目录的写入权限。[root@Server ~]# setfacl -b /var/share
最后在客户端重新挂载共享目录,并测试能否写入。
可以发现,此时客户端仍然是可以写入的。因为对于NFS服务器而言,访问共享目录的客户端就是服务器中的root用户,对共享目录具有完全权限。所以no_root_squash选项会产生很大的安全隐患,一般情况下都不建议采用。
4. 普通用户的身份映射
如果客户端所使用的用户身份不是root,而是一个普通用户,那么默认情况下在服务器端会将其视作其它用户(other)。下面在客户端以普通用户的身份继续进行测试。
首先在服务器端修改配置文件/etc/exports,将共享目录/var/share中的no_root_squash选项去掉,重新加载服务之后,再次通过设置ACL规则的方式赋予nfsnobody用户读写执行权限。
在客户端重新挂载共享,并测试以root用户身份可以正常写入。
下面在客户端创建一个admin用户,并设置密码。
切换到admin用户身份,尝试向共享目录中写入文件,写入失败,但是可以读取目录中的内容。因而如果客户端是以普通用户的身份访问NFS共享,那么默认情况下在服务器端并不将其映射为nfsnobody,而是视作其他用户(other)。
下面在服务器端继续修改配置文件/etc/exports,在共享设置中添加“all_squash”选项,将所有客户端用户均映射为nfsnobody。
然后在客户端再次重新挂载共享(具体操作从略),此时以admin用户身份就可以写入了,并且可以发现所创建文件的所有者同样是nfsnobody。
5. 用户身份重叠
在使用NFS共享的过程中,有时还可能会遇到用户身份重叠的问题。所谓用户身份重叠,是指在NFS服务采用默认设置(用户身份映射选项为root_squash)时,如果在服务器端赋予某个用户对共享目录具有相应权限,而且在客户端恰好也有一个具有相同uid的用户,那么当在客户端以该用户身份访问共享时,将自动具有服务器端对应用户的权限。下面举例予以说明。
首先在服务器端将/var/share共享还原为默认设置,并且取消/var/share目录针对nfsnobody用户的ACL规则,具体操作从略。
假设服务器端存在一个名为teacher的用户账号,uid为1246,将该用户设置为共享目录的所有者。
下面在客户端进行操作。首先仍是重新挂载共享目录,然后将原先admin用户的uid也改为1246。
然后以admin用户身份测试能否对共享目录执行写入操作,发现可以正常写入,并且所创建文件的所有者是admin。
在服务器端查看admin用户所创建的文件,发现所有者则是teacher。
这是因为对于Linux系统而言,区分不同用户的唯一标识就是uid,至于用户名只是为了方便人类理解。所以在系统层面,无论是teacher用户还是admin用户,只要他们的uid一样,就认为是同一个用户。但也正是因为这个原因,才会导致出现用户身份重叠的问题,对于NFS服务而言,这也是一个比较严重的安全隐患。
如何避免用户身份重叠呢?可以从以下两个方面着手:
- 一是在设置NFS共享时,建议采用“all_squash”选项,将所有客户端用户均映射为nfsnobody。这样就可以有效避免用户身份重叠的问题。
- 二是应严格控制NFS共享目录的系统权限,尽量不用为普通用户赋予权限。