正确使用阿里云NAS文件存储服务系列之文件权限校验

1、简介

阿里云在3月份推出了NAS服务,可以让用户无需对现有应用做任何修改,就可以使用具备无限容量及性能扩展、单一命名空间、多共享、高可靠和高可用等特性的分布式文件系统。目前阿里云NAS服务只支持NFS,后续会支持更多的协议。

由于NFS协议经过了较长时间的发展,目前已经发展了多个版本,不同版本间可能会有不同的处理方式。另外,Linux kernel不同的版本下对于NFS协议的实现可能也会有稍微差别。为了帮助用户更好地使用阿里云NAS文件存储服务,我们推出系列文档来介绍阿里云NAS的使用。

首先介绍阿里云NAS服务文件权限校验的使用。阿里云NAS目前使用标准的NFS协议,支持标准的UNIX文件权限校验方法。由于NFS协议不同的版本实现方式不太相同,所以对于某些版本的NFS Client一些功能不能完全支持。

由于NFS V4版本的实现机制,在较早版本的NFS Client上,如果使用NFS V4挂载,会存在两个问题:①client不能正确显示文件owner和group,会显示成匿名用户;②调用chown和chgrp时,会把文件的owner和group修改成匿名用户。所以建议用户使用阿里云NAS服务时,尽量选择高版本的Kernel。如果必须使用存在上述问题的Kernel时,可以使用NFS V3方式挂载来避免上述问题。

接下来首先分析上述问题的原因,然后通过选择阿里云两个版本(CentOS 5.10和CentOS 6.5)的ecs vm来验证上述问题。

2、NFS协议文件权限校验机制

NFS协议支持Linux文件系统本身的权限校验。在NFS3协议中,使用AUTH_SYS方式进行权限验证。NFS请求把nfs client本地的user ID(uid)和一组组ID(gids)发送给nfs server。在NFS Server上按UNIX权限校验方式进行权限检查,把结果返回给nfs client。Nfs client和nfs server之间传送文件owner和group信息时使用数字uid和gids。这样的缺点是要求不同的client必须有相同的user-uid映射关系,如果两个client上,不同的用户有相同的uid,它们在nfs server上的权限验证是相同的,对于所有的文件有相同的权限。NFS V3文件权限校验方式如下图所示。

Linux使用uid来表示进程,对于每一个NFS请求,NFS client都会把当前的euid和egids发送到nfs server。linux系统中每个进程都有2个ID,分别为用户ID(uid)和有效用户ID(euid),UID表示进程的创建者(创建简称的用户uid),而EUID表示进程对于文件和资源的访问权限(等同于哪个用户的权限)。


正确使用阿里云NAS文件存储服务系列之文件权限校验_第1张图片

 

为了解决不同的client有不同的name-uid的映射关系,在nfs v4协议中,通过idmap服务,client和server传输文件的owner信息时,使用字符串,而不再使用数字uid和gids,比如user@nfs_domain,group@nfs_domain。NFS Server收到字符串的owner和group时,再把字符串信息转换成数字uid和gids。使用字符串代替数字uid和gids,增加了灵活性,通过idmap服务允许client和server接入NIS和LDAP服务。具体流程见下图。

正确使用阿里云NAS文件存储服务系列之文件权限校验_第2张图片


对于公有云的NAS服务,是没有用户的name->uid的映射关系的,所以要求用户只能发送数字的uid和gids,如果用户发送过来的文件owner信息是string,在server端也只能把用户映射成nobody。但糟糕的是较早版本的nfs client中,nfs v4协议发送文件的owner信息时,必须使用idmap转换成string,如果用户不使用idmap服务,nfs client就会把数字uid映射成nobody发送过来。另外,对于server发送过来的数字uid和gid,也会映射成nobody。

这个是较早版本的NFS client实现方式:


    if (iap->ia_valid & ATTR_UID) {
        owner_namelen = nfs_map_uid_to_name(server->nfs_client, iap->ia_uid, owner_name);
        if (owner_namelen < 0) {
            dprintk("nfs: couldn't resolve uid %d to string\n",
                    iap->ia_uid);
            strcpy(owner_name, "nobody");
            owner_namelen = sizeof("nobody") - 1;
            /* goto out; */
        }
        len += 4 + (XDR_QUADLEN(owner_namelen) << 2);
    }



如果通过idmap查找name-uid映射关系失败时,会把username应射成nobody来处理。

这种强制使用idmap的行为对用户使用来说是很不友好的,而且也和以前版本的NFS协议处理方式不兼容。所以在后续的版本中,Linux kernel对这种方式进行了修改。如果用户选择关闭idmaper,则client把数字uid和gids按字符串的形式发送给Server。如果NFS server发送给client的是数字uid和gid的话,client也会接受,不会像以前强制转换成nobody处理。详情可以参考如下网址:

http://linux-nfs.vger.kernel.narkive.com/g02o9Wrr/patch-v4-0-5-allow-the-admin-to-turn-off-nfsv4-uid-gid-mapping



Trond Myklebust (5):
NFSv4: If the server sends us a numeric uid/gid then accept it
NFSv4: Send unmapped uid/gids to the server if the idmapper fails
NFSv4: cleanup idmapper functions to take an nfs_server argument
NFSv4: Propagate the error NFS4ERR_BADOWNER to nfs4_do_setattr
NFSv4: Send unmapped uid/gids to the server when using auth_sys


代码层面的修改,是在调用nfs_idmap_lookup_name时,添加了一个判断条件。


int nfs_map_uid_to_name(struct nfs_client *clp, __u32 uid, char *buf, size_t buflen)
{
-	return nfs_idmap_lookup_name(uid, "user", buf, buflen);
+	int ret;
+	ret = nfs_idmap_lookup_name(uid, "user", buf, buflen);
+	if (ret < 0)
+	ret = nfs_map_numeric_to_string(uid, buf, buflen);
+	return ret;
}

3、测试验证

按照上述分析,由于早期的kernel版本,如果不使用idmap,文件的owner会转换成nobody发送给server。由于阿里云NAS现在没有用户name->uid的映射关系,现在只支持数字的uid和gids,所以在一些较早的kernel版本上使用阿里云NAS服务,会遇到用户和组信息无法正确识别和转换的问题。使用nfs v4挂载时,较早版本的kernel主要有两个问题:① nfs client无法显示文件的uid和gid,会全部显示成匿名用户;② nfs client做chown,chgrp操作时,会把文件的owner和group修改成匿名用户。

接下来,用阿里云提供的Centos镜像的两个发行版(CentOS 5.10和CentOS 6.5)来验证上述问题。这两个发行版对应的内核版本分别为2.6.18和2.6.32。对于nfs v4,CentOS 5.10强制使用idmap,CentOS 6.5允许使用数字uid和gids。

CentOS 5.10

5254402f2415c5691937c1797935f667a90d5a2b

CentOS 6.5

302b641d93e732baf98e2ffa5cb098c665c02b2c

3.1文件owner和group显示问题

     在CentOS 5.10上创建两个普通用户Tom和Alice,然后使用NFS V4挂载。

首先创建owner为Tom的文件,使用ll命令,可以看到Tom.txt的uid和gid都是4294967294,这个数字代表匿名用户。


e1ae9068a7897f4994b871aacf33260cf05e85f9

用户Alice看到这个文件uid和gid也都是匿名用户。

1f2d6f07e06af1448b9e15abe8abb9fa77132080


按照上面的分析,这种情况下uid和gid只是没有正确显示,在server保存的uid和gid还是正确的,所以文件权限校验还是正确的。测试证明虽然显示的都是匿名用户,但用户Tom能够继续修改这个文件,而Alice是没有权限修改的。

正确使用阿里云NAS文件存储服务系列之文件权限校验_第3张图片

 

然后,我们看一下使用NFS V3挂载时,显示的文件owner和group。从下面的截图可以看出,使用NFS V3方式进行挂载是没有问题的。用户Tom和用户Alice看到的都是这个文件的owner和group是Tom。

正确使用阿里云NAS文件存储服务系列之文件权限校验_第4张图片

 

我们再在另外一台机器上(CentOS 6.5)使用NFS V4和NFS V3两种方式挂载,看一下结果。先使用NFS V4挂载,但在CentOS 6.5上看到文件Tom.txt属于用户Bill。

a2114fd80efae76f3828612970488b1c92fae8bd

 

按照上面的分析,NAS Server返回文件的owner和group是数字的uid和gid,只是linux在显示时按照/etc/passwd里面的uid-name关系来现实,所以在CentOS 6.5和CentOS 5.10上,用户Bill和用户Tom的uid和gid应该是相同的。

26145ed9995707a71315248a9bd2635712938f4c


1c0d4ffc4fd126e02449d3521714eae7aff5af1f

如果CentOS 6.5机器上没有用户的uid和gid是502,这个时候执行ls命令的时候文件的owner和group直接显示数字uid和gid。

8e6cc12f15035419caa0d0d27d50fc424acd985c

 

上面是用户在较早版本的内核上使用NFS V4新创建的一个文件,但糟糕的是对于已经存在的文件也有这样的问题。

在CentOS 5.10上使用NFS V4挂载,ls整个文件夹,所有的文件都显示匿名用户。

正确使用阿里云NAS文件存储服务系列之文件权限校验_第5张图片

在CentOS 5.10上使用NFS V3挂载,没有问题。

正确使用阿里云NAS文件存储服务系列之文件权限校验_第6张图片

Centos 6.5上NFS V3和NFS V4两种方式挂载,结果相同,都没有问题。

正确使用阿里云NAS文件存储服务系列之文件权限校验_第7张图片

 

综上所述,较早版本的Kernel上,使用NFS V4方式挂载,所有文件的uid和gid都会显示为匿名用户,不过文件的权限校验是正确的。

3.2修改文件的owner和group

除了显示的问题外,较早版本的Kernel上,使用NFS V4方式挂载,chown和chgrp也会有问题。

继续使用上面的文件,在CentOS 5.10上,使用NFS V4方式挂载,把Tom.txt文件的owner和group改为Alice。

55a240f253a717368b6b1829f2803db43043c92f

d45698a4c8048e156a356d6579b395c3d36a3fc6

执行完之后,显示确实是Alice,看起来像是成功了,但其实是不对的。

使用NFSV3 方式挂载,看到Tom.txt文件的owner和group都变成了nobody(匿名用户)。

正确使用阿里云NAS文件存储服务系列之文件权限校验_第8张图片

在CentOS 6.5上,看到同样的结果。

e0c4882c22b85ba0d343e0f073308ec615636c83

按照前面的分析,在较早版本的Kernel上,使用NFS V4挂载,调用chown会把用户的uid和gid转换成匿名用户发送给NFS Server。但为什么又显示成功了呢。这里怀疑是nfs client的cache的问题,把nfs client的inode的cache清空,确实显示成匿名用户,不再显示成Alice了。

清空inode

afaf71cbef98562dc51fbae5ed1655ba658c9816

Alice和Tom看到的都是匿名用户。

正确使用阿里云NAS文件存储服务系列之文件权限校验_第9张图片

 

综上所述,在较早版本的kernel上,使用NFS V4方式挂载时,修改文件的owner和group会把文件的owner和group都变成匿名用户。如果确实需要修改文件的owner和group呢,可以使用NFS V3方式挂载

正确使用阿里云NAS文件存储服务系列之文件权限校验_第10张图片

使用NFS V3挂载,可以修改成功,文件权限校验也是正确的。

在Centos 6.5上查看该文件的owner和group,显示为503,503即为Centos 5.10 vm上用户Alice的uid和gid。

8d9bf6e10eff67b22808e170eb3a153839e12192

使用NFS V3挂载修改owner和group后,再使用NFS V4方式挂载,依然显示成匿名用户,但权限是正确的,用户Alice可以修改这个文件。

正确使用阿里云NAS文件存储服务系列之文件权限校验_第11张图片

 

上面的问题是低版本的内核问题导致的,接下来验证一下在CentOS 6.5上,使用NFS V4方式挂载,修改文件的owner的行为。

从下面的截图可以看出用户Andy创建的文件,把owner和group修改为用户Mike后,文件的owner和group显示和文件权限校验都是没有问题的。

正确使用阿里云NAS文件存储服务系列之文件权限校验_第12张图片

在CentOS 5.10上使用NFS V3进行挂载看到文件的uid和gid是数字501,这个是CentOS 6.5 vm上用户Mike的uid和gid。

32ac34f044629a504468363d99e06948eccf7b63

最后在CentOS 5.10上使用NFS V4挂载,显示的依然是匿名用户。

7c090c200b8535cd6eebda8d8e05e002d9f04f19

4、结论

1、在CentOS 5.10上,使用NFS V4进行挂载,所有文件的owner和group都会显示为匿名用户,但权限校验是正确的。

2、在CentOS 5.10上,使用NFS V4进行挂载,调用chown和chgrp操作,会把文件的uid和gid改成匿名用户。

3、用户使用阿里云NAS服务时,尽量选择高版本的Kernel。如果必须使用存在上述问题的Kernel时,可以使用NFS V3方式挂载来避免上述问题。

 

你可能感兴趣的:(操作系统,ldap)