在本文中,我将讨论如何配置基于网络文件系统的UNIX客户端,通过RPCSEC_GSS协议使用Kerberos安全验证来实现网络文件系统下连接Windows服务器。
传统的网络文件系统客户端和服务器使用系统集成认证安全验证。它最重要的是允许客户端向网络文件系统服务器发送表明UNIX用户的用户ID或用户组ID的验证信息。每个网络文件系统请求都在传入请求中标明UNIX用户的用户ID或用户组ID。这种验证方式提供的安全性比较低,因为客户端可以通过标明一个不同用户的用户ID或用户组ID来欺骗请求。这种验证方式也是很脆弱的,因为间于客户端网络和服务器网络之间的任何第三方都可能抓取网络文件系统请求。
RPCSEC_GSS协议提供了一种通用的机制利用ONCRPC协议复合使用多种安全机制。现在的网络文件系统服务器支持在网络文件系统中利用RPCSEC_GSS协议使用两种Kerberos模式:krb5krb5ikrb5RPC请求级别上提供Kerberos验证,而krb5iKerbero v5同时含有集成认证)则可以防止网络文件系统负载被窃取。
要解释如何在UNIX客户端和运行网络文件系统的Windows服务器上设置Kerberos安全验证,最好的方式就是通过一个简单的例子来实现。在这次的教程中,我们先要明确以下的架构:
1、     名叫NFSDOMAIN.COMwindows域和活动目录运行在一台名为nfsdomain-dc.nfsdomain.com的域控制器上;
2、    运行网络文件系统服务器的Windows服务器:windowsnfsserver.nfsdomain.com
3、    UNIX客户端:unixclient.nfsdomain.com
4、    unixclient.nfsdomain.com上的UNIX用户:unixuser1,用户ID500
5、    unixclient.nfsdomain.com上的UNIX用户组:unixgroup1,用户组ID500
6、    Windows用户:NFSDOMAIN\unixuser1
7、    Windows用户组:NFSDOMAIN\unixgroup1
为了确保演示配置向导,我们假设unixclient.nfsdomain.com运行的系统是OpenSolaris
前提:
首先,我们需要确认域控制器、Windows网络文件系统服务器和UNIX客户端间DNS解析正常。
Solaris客户端的一个提醒是主机名必须设置成域全名的第一部分。在unixclient.nfsdomain.com上运行“hostname”,应该仅显示“unixclient”。如果显示的不是这样,那需要设置主机名为“unixclient”。
确认所有上面提到的用户和用户组已经创建完毕,同时NFSDOMAIN\unixuser1必须是NFSDOMAIN\unixgroup1的成员。我们必须为unixuser1设置一个密码。如果在UNIX客户端上的用户ID和用户组ID不同,就需要我们指定相应的项为对应的值,例如我们此次举例的500
UNIX客户端加入活动目录:
现在我们要配置unix客户端能从NFSDOMAIN.COM域上获取Kerberos验证凭证。这可以通过修改/etc/krb5/krb5.conf文件来实现。在该文件中,会有一些预留的键值可供编辑。我们需要修改以下部分:“默认域名default_realm”、“域控制器名称kdc”、“管理服务器名称admin_server”和“网络文件系统域名domain_realm”。我们也需要在"libdefaults"下添加两项值“default_tkt_enctypes”和“default_tgs_encrypes”。我在后面会解释为什么需要添加这两项。最后这个文件会修改成下面样子:
<Begin /etc/krb5/krb5.conf snip>
[libdefaults]
        default_realm = NFSDOMAIN.COM
        default_tkt_enctypes = arcfour-hmac-md5 des3-cbc-sha1-kd des-cbc-md5
        default_tgs_enctypes = arcfour-hmac-md5 des3-cbc-sha1-kd des-cbc-md5
 
[realms]
        NFSDOMAIN.COM = {
                      kdc = nfsdomain-dc.nfsdomain.com
                      admin_server = nfsdomain-dc.nfsdomain.com
        }
 
[domain_realm]
        nfsdomain.com = NFSDOMAIN.COM
</snip>
在这个时候,我们可以测试在unixclient客户端上使用NFSDOMAIN\unixuser1获取验证凭证:在unixclient客户端上运行“kinit unixuser1”,然后输入用户密码。
现在我们可以通过运行“klist”,来为unixuser1获取验证凭证。同时也可以运行“kdestroy”来注销验证凭证。
网络文件系统如何使用RPCSEC_GSS协议?
好了,我们现在已经完成了Kerberos的基本设置,下面我们从网络文件系统的角度来介绍一下验证工作的流程。
unixclient客户端需要完成与windowsnfsserver(Windows网络文件系统服务器)的验证,它需要一些用户来用于验证,而在Kerberos协议中称之为参与者。当网络文件系统共享加载完成,客户端会查询网络文件系统服务器的域全名,然后使用"nfs/FQDN@domain_realm"作为参与者来试图验证。在我们此次介绍的情况下,unixclient客户端将去寻找“nfs/windowsnfsserver.nfsdomain.com@NFSDOMAIN.COM”这样的用户去参与验证。依据协议规定,UNIX机器将使用“root”身份执行一些网络文件系统的初始化操作。在本文中,它是本机的系统管理员帐户。按协议规定的话,这个用户全名是“root/unixclient.nfsdomain.com@NFSDOMAIN.COM”。
如何设置用户及参与者?
对于“nfs/windowsnfsserver.nfsdomain.com@NFSDOMAIN.COM”这样的用户,我们只需要去使用活动目录中已经存在的机器的帐户,关键的是要为其创建一个别名。
对于nfsdomain-dc,我们执行:
setspn -A nfs/windowsnfsserver windowsnfsserver
setspn -A nfs/windowsnfsserver.nfsdomain.com windowsnfsserver
然后执行:
setspn -L windownfsserver
这样我们就可以看到机器上所有帐户的服务参与名。
如何设置unixclient的参与帐户?
为了这些验证参与帐户,我们将在活动目录中创建一些用户。由于“/”对于活动目录帐户名称是无效字符,所以我们必须设置不同的名字,然后使用setspn程序添加服务参与名。为了完整性的目的,我们在root系统管理员帐户的基础上再多建一对帐户。在nfsdomain-dc上创建如下用户,并为它们设置好密码:
1、  unixclienthost(代表unixclient这台主机);
2、  unixclientrootunixclientroot系统管理员帐户);
3、  unixclientnfs(网络文件系统服务器在unixclient上使用的帐户)。
创建完这些用户后,右键每个用户,选择“属性”。在“帐户”选项卡下,分别修改“用户登录名称”为"host/unixclient.nfsdomain.com""root/unixclient.nfsdomain.com" "nfs/unixclient.nfsdomain.com"。下面我们对这些帐户设置加密虚拟网:
setspn -A host/unixclient unixclienthost
setspn -A host/unixclient.nfsdomain.com unixclienthost
setspn -A root/unixclient unixclientroot
setspn -A root/unixclient.nfsdomain.com unixclientroot
setspn -A nfs/unixclient unixclientnfs
setspn -A nfs/unixclient.nfsdomain.com unixclientnfs
unixclient需要使用root/unixclient.nfsdomain.com@NFSDOMAIN.COM身份,但是并不需要真实地去输入该身份对应的密码。这是通过一个密钥表来实现的。下面我们来对这些帐户导出密钥表文件。在nfsdomain-dc上运行:
ktpass -princ host/unixclient.nfsdomain.com@NFSDOMAIN.COM -mapuser unixclienthost -pass <insert password> -out unixclienthost.keytab
ktpass -princ root/unixclient.nfsdomain.com@NFSDOMAIN.COM -mapuser unixclientroot -pass <insert password> -out unixclientroot.keytab
ktpass -princ nfs/unixclient.nfsdomain.com@NFSDOMAIN.COM -mapuser unixclientnfs -pass <insert password> -out unixclientnfs.keytab
然后,我们将上述文件从nfsdomain-dc主机上移动到unixclient主机上。
unixclient主机上,我们要将这些文件整合到本机密钥表文件中。在我们放置这些复制过来的文件的目录下,我们可以使用“ktutil”命令来整合。在这个交互式的工具里,我们执行如下命令:
rkt /etc/krb5/krb5.keytab
rkt unixclienthost.keytab
rkt unixclientroot.keytab
rkt unixclientnfs.keytab
wkt /etc/krb5/krb5.keytab
q
好了,现在unixclient应该可以为这些帐户申请验证凭证,而不用再输入密码了。我们可以做如下测试:
kinit -k host/unixclient.nfsdomain.com
kinit -k root/unixclient.nfsdomain.com
kinit -k nfs/unixclient.nfsdomain.com
每条命令都应该显示成功获取到验证凭证。由于对验证凭证进行编码加密的底层的加密机制必须同时被nfsdomain-dcunixclient支持并接受,因而在某些配置上还是比较微妙的。在krb5.conf文件中添加"default_tkt_enctypes" "default_tgs_enctypes"参数就是为了回避OpenSolaris的一个漏洞。在使用ktpass程序时,我们可能需要明确指定加密类型。”-crypto DES-CBC-MD5”基本属于被广泛接受并支持的加密类型。鉴于我们应用环境中活动目录版本 的问题,我们可能还需要检查用户属性页上“用户帐户”选项卡下“对该帐户使用Kerberos DES 加密类型”选项。检查安全事件日志也能帮助我们诊断登录尝试。
unixclient客户端上为Kerberos帐户映射用户ID或用户组ID
在这一节,我们将介绍unixclient上的网络文件系统客户端如何将它本地的用户ID和用户组ID映射到Kerberos帐户上。
unixclient上执行如下命令:
gsscred -m kerberos_v5 –a
gsscred -m kerberos_v5 –n host/unixclient.nfsdomain.com -u 0 –a
gsscred -m kerberos_v5 –n root/unixclient.nfsdomain.com -u 0 –a
gsscred -m kerberos_v5 –n nfs/unixclient.nfsdomain.com -u 0 –a
gsscred -m kerberos_v5 –n unixuser1 -u 500 –a
gsscred -m kerberos_v5 -n unixgroup1 -g 500 -a
这些命令将用于校验接入帐户的公共证书表移入本地用户帐户。我们需要确保的就是在unixclient上要先允许”gssd”
在网络文件系统上启用Kerberos安全校验:
网络文件系统下的OpenSolaris默认禁用Kerberos。显然,我们需要启用它。我们可以编辑”/etc/nfssec.conf”,然后将所有含有krb的行取消批注,确保能够完整执行。我们需要改成这样:
<snip>
krb5            390003  kerberos_v5     default -               # RPCSEC_GSS
krb5i           390004  kerberos_v5     default integrity       # RPCSEC_GSS
krb5p           390005  kerberos_v5     default privacy         # RPCSEC_GSS
</snip>
我们可以注意到网络文件系统服务器当前情况下不支持krb5p
配置网络文件系统服务器的用户ID或用户组ID的映射:
Windows这边,我们还是需要配置UNIX用户ID和用户组IDWindows帐户的映射关系。网络文件系统服务器在每次收到网络文件系统请求时,还是会使用Kerberos验证的。然而网络文件系统协议只会对像GETATTR(获取属性)和READDIR(获取目录信息)的请求回复用户ID和用户组ID。如果不做映射,即使新建的文件在windowsnfsserver上做过准确的安全性可视性描述,在unixclient上执行“ls –l”也将不能准确显示用户ID和用户组ID
如果需要了解网络文件系统服务器如何获取Windows用户和组信息,可以查阅:
而下面这篇博文则对了解活动目录解析特性会很有帮助:
windowsnfsserver上提供一个共享:
如何配置共享可以参与下面的配置文档:
在创建完“share”共享目录后,确认所有打算要访问它的用户(包括unixuser1)都能访问它。
加载共享:
最后,我们可以准备加载共享了。
在加载共享时,我们要记住使用服务器的域全名。这也是为什么unixclient可以在查找windowsnfsserver时精准地指向相应帐户。
unixclient客户端上以系统管理员root身份执行如下命令:
mount -o sec=krb5,vers=3,proto=tcp windowsnfsserver.nfsdomain.com:/share /mnt/share
一旦共享加载完毕,我们以unixuser1身份登录到unixclient客户端上,并运行”kinit”,然后输入密码,接着就可以访问“/mnt/share”共享了。如果所有东西都配置正确,那么我们就能访问共享。此时,我们终于可以说是可喜可贺了,因为我们的网络文件系统连接现在已经十分安全了。
 
参考链接:
1、  Windows Server 2008 R2下网络文件系统服务手把手配置向导:
2、  Windows/UNIX验证配置:
3、  活动目录加密漏洞的快速修补程序解释(如果已经打好补丁,就不需要看了):
4、  OpenSolaris加密漏洞:
 
感谢原文作者: Jeff Biseda.
原文地址: