這是一篇翻譯的文章,原文爲 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 軟件工程師。