内容简介:NFS(Network File System,网络文件系统)是一种在企业内部网络使用比较广泛的文件共享服务,主要用于Linux以及类UNIX系统之间的文件共享。它采用C/S工作模式,在NFS服务器上将某个目录设置为共享目录,然后在客户端可以将这个目录挂载到本地使用。NFS服务诞生于上世纪80年代,虽然在CentOS7.6系统中采用的是目前最新的NFSv4版本,但由于NFS服务本身比较简单,尤其是在权限设置方面功能比较弱,所以如果对NFS服务设置不当,将会在企业网络中产生比较严重的安全隐患。本文就NFS服务
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。
[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命令使得我们刚才所做的设置生效。
[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服务和操作系统两个层面全部都具有写入权限才可以。
如何使得客户端可以在操作系统层面对共享目录具有写入权限,这就要涉及到用户身份映射问题。
2. 用户身份映射的原理
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用户:
- 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``
然后在客户端重新挂载共享目录,并测试能否写入。
[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选项会产生很大的安全隐患,一般情况下都不建议采用。
4. 普通用户的身份映射
如果客户端所使用的用户身份不是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
5. 用户身份重叠
在使用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服务而言,这也是一个比较严重的安全隐患。
如何避免用户身份重叠呢?可以从以下两个方面着手:
- 一是在设置NFS共享时,建议采用“all_squash”选项,将所有客户端用户均映射为nfsnobody。这样就可以有效避免用户身份重叠的问题。
- 二是应严格控制NFS共享目录的系统权限,尽量不用为普通用户赋予权限。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- MyBatis从入门到精通(十一):MyBatis高级结果映射之一对多映射
- MyBatis从入门到精通(九):MyBatis高级结果映射之一对一映射
- 【mybatis xml】数据层框架应用--Mybatis(三)关系映射之一对一关系映射
- Hibernate 关系映射整理
- SpringMVC——请求映射
- Hibernate 关系映射整理
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Types and Programming Languages
Benjamin C. Pierce / The MIT Press / 2002-2-1 / USD 95.00
A type system is a syntactic method for automatically checking the absence of certain erroneous behaviors by classifying program phrases according to the kinds of values they compute. The study of typ......一起来看看 《Types and Programming Languages》 这本书的介绍吧!