这是一篇翻译的文章,原文为 New in CDH 5.2: Impala Authentication with LDAP and Kerberos。因为翻译水平有限,不免会一些翻译不许确的地方,欢迎指正!html
Impala 认证如今能够经过 LDAP 和 Kerberos 联合使用来解决。下文来解释为何和怎样解决。java
Impala,是基于 Apache Hadoop 的一个开源的分析数据库,使用 Kerberos 和 LDAP 来支持认证-做为一种角色来证实你是不是你所说的你是谁。Kerberos 在1.0版本中就已经被支持了,而 LDAP 是最近才被支持,在 CDH 5.2 中,你可以同时使用二者。ios
同时使用 LDAP 和 Kerberos 提供了显著的价值;Kerberos 保留了核心的认证协议而且老是用在 Impala 进程彼此之间以及和 Hadoop 集群链接的时候。而后,Kerberos 须要更多的维护支持。LDAP 是在整个企业中无处不在,而且一般由经过 ODBC 和 JDBC 驱动程序链接到 Impala 的客户端应用程序来使用。二者的组合使用是有必定道理的。shell
下表代表了各类组合和它们的使用场景:数据库
Impala 认证 | 使用场景 |
---|---|
No Authentication | 非安全的集群。咱们肯定既然你在阅读这篇文章,那你不会对这种场景感兴趣 |
Kerberos Only | Hadoop 集群开启 Kerberos 认证,而且链接到 Impala 的每一个用户或者客户端都有一个 Kerberos principal。(详细说明见下文。) |
LDAP Only | Hadoop 集群 没有开启 Kerberos 认证,可是你想认证链接 Impala 的外包的客户端,如你使用 Active Directory 或者其余的 LDAP 服务。 |
Kerberos and LDAP | Hadoop 集群开启 Kerberos 认证。在 Impala 外部的用户没有 Kerberos principal,可是有一个 LDAP 的凭证。 |
在这篇文章中,我将解释为什么以及如何使用 LDAP 和 Kerberos 的组合来创建 Impala 认证。后端
Kerberos 仍然是 Apache Hadoop 的主要认证机制。下面是 Kerberos 的一些术语将会帮助你理解这篇文章讨论的内容。安全
principal
是 Kerberos 主体,就要一个用户或者一个守护进程。对于咱们来讲,一个 principal 对于守护进程来讲是 name/hostname@realm
,或者对于用户来讲仅仅是 name@realm
。name
字段多是一个进程,例如 impala
,或者是一个用户名,例如 m
yoder`。hostname
多是一个机器的全名称,或者是一个 Hadoop 定义的 _HOST 字符串,一般会机器全名称自动替换。realm
相似于(但没必要要和其同样)一个 DNS 域名。Kerberos 主体可以证实他们是谁,要么经过提供一个密码(若是主体是人),或者经过提供“密钥表”的文件。 Impala 守护进程须要一个密钥表文件,该文件必须获得很好的保护:任何能够读取密钥表文件的人能够冒充 Impala 守护进程。bash
Basic support for Kerberos in impala for this process is straightforward: Supply the following arguments, and the daemons will use the given principal and the keys in the keytab file to take on the identity of the principal for all communication.服务器
在 Impala 中对 Kerberos 基本的支持很简单:提供如下参数,守护程序将使用给定的主体和 key,在密钥表文件中验证全部通讯的主体的身份。网络
bash--principal=impala/hostname@realm --keytab_file=/full/path/to/keytab
还有另外一外一种状况是 Impala 守护进程(impalad)运行在一个负载均衡器下。
当客户端经过负载平衡器(一个代理)运行查询时,客户端指望 impalad 有一个和负载平衡器的名称的主体。因此当 Impalad 对外部查询提供服务时,须要使用一个和代理相同名称的主体,可是当作后台程序之间的通信时须要一个主体匹配实际的主机名称。
bash--principal=impala/proxy-hostname@realm --be_principal=impala/actual-hostname@realm --keytab_file=/full/path/to/keytab
第一个参数 --principal
定义 Impalad 服务外部查询时使用哪个主体,--be_principal
参数定义 Impalad 进程之间通讯时使用哪个主体。两个主体的 key 必须存在于相同的 keytab 文件中。
Kerberos是一个优雅的协议,可是当出现错误的时候实际的实现不是很是有帮助的。下面主要有两件事情须要检查,在出现认证失败的时候:
Time
。Kerberos 是依赖于同步时钟,所以在全部使用 Kerberos 的机器上安装和使用 NTP(网络时间协议)是一个最佳实践。DNS
。请确保您的主机名是全名称的而且正向(名称 - > IP)和反向(IP->名称)DNS查找是否正确。除此以外,也能够设置两个环境变量以输出 Kerberos 调试信息。输出多是一小部分的内容,但一般是帮助你解决问题。
KRB5_TRACE=/full/path/to/trace/output.log
:该环境变量指定调试日志输出路径。JAVA_TOOL_OPTIONS=-Dsun.security.krb5.debug=true
:该环境变量会传给 Impala 守护进程,并传递给内部的 java 组件。Cloudera documentation for Kerberos and Impala 给出了详细的说明,这里只作简要介绍:
Kerberos 是伟大的,但它确实须要最终用户有一个有效的 Kerberos 证书,这在许多环境中是不实际的,由于每一个与 Impala 和Hadoop集群交互的用户都必须配置 Kerberos 主体。对于使用 Active Directory 来管理用户账户的组织,可能须要在 MIT Kerberos 领域频繁的建立每一个用户对应的用户账户。取而代之的时许多企业环境使用 LDAP 协议,在客户使用本身的用户名和密码进行身份验证本身。
当配置为使用LDAP,把 impalad 看做为一个 LDAP 代理:客户端( Impala shell,ODBC,JDBC,hue 等等)发送其用户名和密码到 impalad ,而后 impalad 将用户名和密码发送给 LDAP 服务器并尝试登陆。在 LDAP 术语中,impalad 发出 LDAP “绑定” 操做。若是 LDAP 服务器为该次登录尝试返回成功,则 impalad 接受链接。
LDAP只用于验证外部客户,如Impala shell,ODBC,JDBC,和 hue。全部其余后端认证由 Kerberos 的处理。
LDAP 是复杂的(并且强大的),由于它很是灵活;有许多方式来配置 LDAP 实体和验证这些实体。在通常状况下,每一个人都在 LDAP 具备专有名称或DN,可被认为是 LDAP 中的用户名或主体。
让咱们来看看对于两个不一样的LDAP服务器用户是如何设置的。第一个用户名为“Test1 Person”,并存在 Windows2008 Active Directory 中。
# Test1 Person, Users, ad.sec.cloudera.com dn: CN=Test1 Person,CN=Users,DC=ad,DC=sec,DC=cloudera,DC=com cn: Test1 Person sAMAccountName: test1 userPrincipalName: test1@ad.sec.cloudera.com
第二个用户是我:用户 myoder 的项,存在于 OpenLDAP 服务器中:
# myoder, People, cloudera.com dn: uid=myoder,ou=People,dc=cloudera,dc=com cn: Michael Yoder uid: myoder homeDirectory: /home/myoder
为了简单,上面中的其余的许多项都被删除了。下面来看看这两个帐户的相同点和不一样点:
DN
:在注释后面的第一行就是 DN。这是一个 LDAP 帐户最主要的标识串。CN
:通用名称。对 AD 来讲,他和 DN 是同样的;对于 OpenLDAP 来讲他是一我的的名称,他不是 DN 中的 uid。sAMAccountName
:只存在 AD 中的条目,是一个用户名称的过期的形式。尽管其过期了,可是被普遍使用中。userPrincipalName
:只存在 AD 中的条目,经过转换,应该映射到用户的邮箱名称。其一般像这样的格式:sAMAccountName@fully.qualified.domain.com
。这是 Active Directory 更现代的名称而且被普遍使用。这里还有一些额外有趣的关于 AD 的实现细节。一般,LDAP 认证是基于 DN。对于 AD,下面几项会被轮流尝试:
考虑全部这些的不一样点,幸运的是 Impala 进程提供了几个机制去标识 LDAP 的配置。首先,使用简单的配置:
--enable_ldap_auth
必须设置为 true--ldap_uri=ldap://ldapserver.your.company.com
必须定义仅仅设置这些,传递给 impalad 的用户名(经过 impala shell、jdbc、odbc 等等)直接传递到 LDAP 服务器。这个过程对于 AD 来讲没什么问题,若是用户名称是全名称,就像 test1@ad.sec.cloudera.com
- 其使用 userPrincipal
或者 sAMAccountName
加上 DNS 域名都会匹配上。
也能够设置 impalad 启动参数以便 这域名(在当前状况下是 ad.sec.cloudera.com
)能够自动添加到 用户名上,这须要经过设置参数 --ldap_domain=ad.sec.cloudera.com
添加到 impalad 的启动参数中。如今,当一个客户端用户访问时,例如 test1 用户,其会将域名名称追加到用户名称以后以便追加后的结果 test1@ad.sec.cloudera.com
传递给 AD 。这种方式对于你的用户来讲是很方便的。
目前,对于 AD 来讲都运行正常。可是对于其余的 LDAP 服务器,例如 OpenLDAP 呢?OpenLDAP 没有 sAMAccountName 或者 userPrincipalName 中的任何一个,取而代之的是咱们不得不直接使用 DN 进行认证。用户将不会去关心他们的 LDAP DN!
幸运地是,impalade 对于这种场景也提供了一些参数。--ldap_baseDN=X
参数用户将用户名称转换为 LDAP DN,以便这个 DN 结果看上去像 uid=username,X
。例如,若是设置 --ldap_baseDN=ou=People,dc=cloudera,dc=com
,传递的用户名是 myoder,传到到 LDAP 的查询将是 uid=myoder,ou=People,dc=cloudera,dc=com
,这将会和 myoder 的 DN 想匹配。
为了得到最大的灵活性,也能够经过 --ldap_bind_pattern
参数将指定用户名任意映射到一个DN。这个想法是,该参数中必须有一个名称为 #UID 的占位符,而且 #UID
会被用户名替代。例如你能够经过指定 --ldap_bind_pattern=uid=#UID,ou=People,dc=cloudera,dc=com
来定义 --ldap_baseDN
。当 myoder 这个用户进来时,其将会替换 #UID
,而且咱们将获得和上面一直的字符串。这个参数应该在须要对 DN 有更多控制的时候才使用。
当使用 LDAP 时,传递个 LDAP 服务器的用户名和密码都是明文的。这意味着没有任何的保护,任何人均可以看到传输中的密码。为了阻止这一点,你必须使用 TLS(Transport Layer Security,更为人熟知的是 SSL) 来保护链接。 这里有两种不一样的链接须要保护:客户端和 impalad 进程之间以及 impalad 进程和 LDAP 服务器之间。
TLS 链接的认证须要使用证书来完成,因此 impalad 进程(做为 TLS server)须要他本身的证书。Impalad 呈现该证书给客户端以证实他的确是 impalad 进程。为了提供该证书,impalad 进程须要设置下面两个参数:
bash--ssl_server_certificate=/full/path/to/impalad-cert.pem --ssl_private_key=/full/path/to/impalad-key.pem
如今客户端必须使用 TLS 和 impalad 通讯。在 impala-shell 中,你必须设置 --ssl
和 --ca_cert=/full/path/to/ca-certificate.pem
这两个参数。ca_cert 参数必须指定为上面 ssl_server_certificate
参数定义的值。对于 ODBC 链接来讲,请参考 the Cloudera ODBC driver for Impala。其提供了一个全面的描述。关于设置证书、认证和 TLS 的必要性。
坦白地说,在 impala 客户端和 impalad 进程之间使用 TLS 是一个很好的想法,不论是否使用 LDAP。然而,你的查询,以及这些查询的结果都是经过明文传输的。
这里有两种方法开启和 LDAP 服务器之间的 TLS :
--ldap_tls
。该链接会使用 LDAP 的端口,可是在第一次链接以后,会发送一个 STRATETLS
的请求,该请求会使用 TLS 升级该链接为一个安全的链接而且使用相同的端口。ldaps://
开头。这将会使用一个不一样于 ldap://
的端口。最后,到 LDAP 服务器的链接须要他本身的认证;在这种状况下,你知道 impalad 是在和正确的 ldap 服务器通话而且你不会将你的密码发送给一个无赖的人为工具的请求。你须要添加 --ldap_ca_certificate
参数到 impalad 定义 LDAP 服务器的证书存放的位置。
Cloudera documentation for LDAP and Impala 一文包括这部分的信息,而且建议你阅读 TLS between the Impala client and the Impala daemon 这篇文章。
若是咱们想同事使用 Kerberos 和 LDAP 认证,则须要以下配置:
bashimpalad --enable_ldap_auth \ --ldap_uri=ldap://ldapserver.your.company.com \ --ldap_tls \ --ldap_ca_certificate=/full/path/to/certs/ldap-ca-cert.pem \ --ssl_server_certificate=/full/path/to/certs/impala-cert.pem \ --ssl_private_key=/full/path/to/certs/impala-key.pem \ --principal=impala/_HOST@EXAMPLE.COM \ --keytab_file=/full/path/to/keytab
当使用 Kerberos 认证时,使用 impala shell 链接:
bashimpala-shell.sh --ssl \ --ca_cert=/full/path/to/cert/impala-ca-cert.pem \ -k
当使用 LDAP 认证时:
bashimpala-shell.sh --ssl \ --ca_cert=/full/path/to/cert/impala-ca-cert.pem \ -l -u myoder@cloudera.com
原文做者为 Michael Yoder,Cloudera 软件工程师。