大數據SRE的總結(10)-- kerberos in hadoop & 分散式程序認證設計

本系列到今天,hadoop sre相關我能講的,大致快收尾了。

我有一些話想說。

我的專欄得到不少同學關注,這讓我有了成就感,也讓我倍感壓力。每一篇文章我都儘可能的帶上我主觀的思考,尤其思考「技術」,在「不同國情」的商業公司中的價值。我在自己的精力不夠時,真的不敢寫,怕寫不好。

此外,我的初衷是抱著總結自己實際工作中的經驗為目的去寫這些文章。我想通過我的小小share,能讓hadoop這一行在國內哪怕進步一點點。所以我也沒有拒絕任何科技公眾號/科技媒體的轉載。但我拒絕了知識付費媒體。

對於內容,文章中充斥了不少思考,或者說方法論,而不是具體的「技術」。這就是我想要的。 我認為,掌握具體的技術細節是沒有捷徑的,不能想通過幾篇國人翻譯的技術貼就搞定。想要學習細節,就去讀「英文原版文檔」。相比信息二道販子,我更想分享的是「經驗&思考」,而不是純技術細節。


Abstract

上一篇講了hadoop安全總攬。hadoop安全里最重要的一個組件,就是kerberos,如果沒有認證,絕對安全就無從談起。再講一遍kerberos協議,枯燥且無意義,網上能找到的資料已經很多了。所以請沒有kerberos知識的同學,自己補學,下面我會列出一些學習kerberos的鏈接。

我會講:hadoop和kerberos這兩個技術在結合時,有哪些亮點;然後會總結hadoop認證給我們在設計其它分散式系統的認證功能時,積累的經驗;最後,也是最重要的,就是聊聊企業為什麼在實施kerberos時,都這麼痛苦,難點在哪裡。

kerberos基礎知識補學:

1.Wikipedia : Kerberos (protocol)

2.Slideshare. kerberos-explained

3.www.logicprobe.org kerberos.pdf

4.Oracle: 中文kerberos文檔

keywords : kerberos Delegation-Tokens impersonate tgt-forwardable

Agenda

1.kerberos協議,相對普通的認證,為什麼更安全2.hadoop在使用kerberos上,其特點是什麼,對設計分散式程序提供的經驗3.hadoop實施kerberos功能,為什麼這麼難?4.退而求其次的解決方案--堡壘機

1.kerberos協議,相對普通的認證,為什麼更安全

我們在使用it系統,在涉及系統內的私密個人信息時,都需要認證。

認證是一個簡單的信息交換過程: 即,用戶向服務證明,你是你。

典型的認證過程中,有三個參與方面 : 客戶端、傳輸信道、伺服器。而所謂的「不安全」,在這三個參與方都有可能發生。

1.1 認證問題很嚴重

在web時代,網路總是很不安全,發生過很多問題。對互聯網安全感興趣的朋友,可以看看這裡:Security : OWASP Top Ten Project owasp組織每年都會總結出每年互聯網世界中top 10的安全問題,並給予建議. 而身份認證,常常排名在前3名。

owasp top 10

1.2認證不安全的場景

我從三個參與方分別來說。

客戶端C:

C1.憑證填充,使用已知密碼。你的瀏覽器,是否開啟了記住密碼自動填充,他人是否可以在你不在時,使用你的賬號登陸某些網站。

C2.應用會話超時設置不正確。用戶使用公共計算機訪問應用程序。用戶直接關閉瀏覽器選項卡就離開,而不是選擇「註銷」。攻擊者一小時後使用同一個瀏覽器瀏覽網頁,而當前用戶狀態仍然是經過身份驗證的。

伺服器S:

S1. 伺服器存儲用戶密碼的資料庫,使用明文存儲。網站端工作人員,可以盜破用戶密碼。

S2. 伺服器要求的密碼位數太短,太簡單。導致用戶密碼,在分散式算力強大的時代背景下,容易被「暴力破解」。比如,著名的「彩虹表」。

S3. 伺服器端網路不安全,被攻破,被拖庫。

信道Channel:

CH1. 黑客監聽/截獲網路數據包。黑客已經攻入網路,可以監聽到用戶到server端的發送報文。黑客如果截獲的信息是明文,就是最壞的情況。黑客如果截獲的是密文,仍可以採取「破解密碼」 or 「篡改並重發報文」等作惡手段,達到目的。

1.3 Kerberos特徵 及 解決認證的問題

kerberos解決了以上所有問題。

kerberos 認證流程圖

  1. 登陸會話及過期,保證登陸狀態有時效性。時效性短,但客戶端可以refresh。極大的改善了C1,C2.
  2. kerberos存儲密碼的KDC資料庫及其技術,可信,被證明過是「可信的第三方」。
  3. 密碼不用在信道傳輸。根本上去除CH1中的密碼被截獲的可能性。
  4. 信道傳輸的東西是加密的,且信道傳輸的信息也是有時效性的。
  • 信息還是有被暴力破解的可能性。但只要使 time(session-key 過期) < time(破解sessionkey加密的信息),就夠了。信息被黑客破解只在理論上成立,現實中不可能。因為你破解的信息已經過時了,新的信息又是用最新的session-key進行加密。

本文的目的不是去講kerberos細節,而是講kerberos與hadoop的結合,以及hadoop當中涉及kerberos的設計思路,給我們設計「安全的分散式程序「的啟發。但我還是列出一些學習和上手kerberos的鏈接:

1.Wikipedia : Kerberos (protocol)

2.Slideshare. kerberos-explained

3.www.logicprobe.org kerberos.pdf

4.Oracle: 中文kerberos文檔

5.Cloudera Community : Kerberos Concepts - Principals, Keytabs and Delegation Tokens

2.hadoop在使用kerberos上,其特點是什麼,對設計分散式程序提供的經驗

分散式的場景下,絕對的安全,很複雜。分散式意味著「結點」以及「進程」的分散。在企業級這個level,公司集群動輒幾百上千的機器,公司內又有無數的程序員在用開發機器作為客戶端在訪問這些集群,那麼結點進程互相之間的認證就是一個更加複雜的網。hadoop可以算是分散式安全領域的top開源項目,那麼其在分散式背景下的安全框架設計,肯定有值得我們琢磨的地方。

Kerberos Principals

kerberos中最重要的概念是principal,在這裡就再帶一遍。

Principal可以理解為用戶或服務的名字,全集群唯一,由三部分組成:username(or servicename)/instance@realm,例如:nn/host001@TEST.COM,host001為集群中的一台機器;或admin/admin@TEST.COM,管理員賬戶。

  • username or servicename:在本文里為服務,HDFS的2個服務分別取名為nn和dn,即namenode和datanode
  • instance:在本文里為具體的FQDN機器名,用來保證全局唯一(比如多個datanode節點,各節點需要各自獨立認證)
  • realm:域,我這裡為TEST.COM(全大寫喲)

Hadoop 會為每一個host每一個process都生成principal.比如為hdfs 的 NameNode和 yarn 的 ResourceManager都生成各自的principal. 這讓整個hadoop的security達到了一個高水準。細節請看: Hadoop in Secure Mode .

namenode resourcemanager 按 name/host@realm 的格式創建的principal

principal的深入講解:

  1. cloudera community : cdh principal & keytab
  2. ieevee.com/tech/2016/06
  3. Apache Hadoop 2.7.3 - secure mode kerberos configuration

分散式中的認證場景

在一個絕對安全的分散式場景下,每兩台server之間互相聯繫,都需要認證彼此。如果一個cluster有N台機器,理論上是要有 N平方對 的請求需要獲取kerberos ticket。

我們按系統的部署複雜度,漸近式的來羅列認證場景:

1.最簡模型

要求認證者只有一台伺服器。這是最簡模型,沒什麼好說的。標準的kerberos模版。

2.簡單的分散式部署場景

參與者是一個「鏈」,甚至是一顆「樹」。

比如 : 一個大型應用系統 ,web伺服器 與 資料庫/緩存伺服器的分離,以及 大型公司內部 微服務化的 部署。

3. 複雜的分散式部署場景

在hadoop系技術棧下,基本都是複雜的分散式部署場景。

組件的「種類」多,組件的「數量」也多。兩兩之間在通信(發送rpc請求)時,都需要彼此「認證」。

airflow/azkaban 向 hadoop 提交

複雜的分散式場景

Hadoop認證場景的特點 Scenario:

S1.某些門戶伺服器,負責接受用戶請求,然後代用戶,向後方真正的集群進行交互。

  • 比如在用戶使用 諸如 hive/ oozie / azkaban 提交job時,用戶希望真正提交到yarn里的job的user還是用戶自己。

  • 比如在ceph中,client端可以通過 http-api/s3-api / swift-api 等方式訪問 ceph os gateway. 而gateway server這個跳板,又會模擬用戶去真正的調用librados.

ceph gateway - 1

ceph gateway - 2

S2.用戶提交的計算任務,分散式運行。運行的子task,都以提交用戶的許可權去訪問其它「第三方」系統。

  • 比如:hadoop用戶提交的mapreduce job,在每一個task中都有可能訪問hdfs。在訪問hdfs時,以提交job的用戶來訪問hdfs,甚至其它第三方service。

這些場景會產生以下幾個問題 (Question):

在場景S1下,gateway伺服器是連接用戶和系統的屏障,gateway伺服器還要能裝扮成「原提交用戶「去和後端系統交互。

Q1-S1. principal & keytab 泛濫,管理困難。

  • 根據上面kerberos principal的定義 username/instance@realm,同一個用戶,在不同的機器,是需要配置不同的principal的。倘若公司內有m個用戶,n台gateway機器,就要預先定義m*n個principal,且新創建的gateway機器都要重複這個過程。而且這些gateway伺服器在做kinit操作時,又要使用keytab,這都會導致對 principal以及其對應的keytab (what is a keytab)的管理變的困難。

在場景S2下,計算job會生成很多的子計算任務,且分散在集群的很多機器上。這不僅僅會引起Q1-S1同樣的問題,還會更嚴重。一個大型公司的hadoop cluster,上面每天甚至會跑幾萬幾十萬的job。每個job又會生成很多的mapreduce 子task,這些job的生命周期從幾分鐘到天不等.

Q2-S2. 加強版Q1-S1.

  • 由於job的短生命周期,而產生的大量短生命周期principal & keytab

Q3-S2. KDC承受壓力,有dos的風險(deny of service).

  • 在一些大的job launch時,會有很多很多的子task瘋狂的訪問KDC,而kerberos涉及了很多的加解密操作,kdc本就是cpu密集型應用,再加上handle大量的網路請求,很有可能導致 deny of service,讓其它訪問kdc的正常kerberos請求不可用。

Q4-S2. long-running的job,ticket會過期,需要處理好。

  • 很多hadoop上跑的mapreduce job,都會跑很久,甚至好幾天。而kerberos的session key在設計之初,就是要過期,防止暴力破解的。那這些job需要去renew他們的ticket。怎麼實現?

Hadoop這些問題的解決之道,以及對設計「分散式系統安全」的可借鑒經驗 solution

Q1-S1. principal & keytab 泛濫,管理困難。

常規解法:kerberos forward/proxy ticket , 讓gateway機器可以使用客戶端的ticket,訪問後端機器。

  1. Oracle : kerberos forwardable ticket doc
  2. Delegation of Authentication (proxy & forwarded tickets)

forwardable ticket

缺點:不論是proxy還是forwardable ticket.都需要在客戶端kinit時,把gateway機器/後端機器加入kinit的參數當中。其次這種ticket的時效性管理貫穿多台機器,很麻煩。總之,這種實現,複雜度比較高,和kerberos協議耦合太深

Hadoop解法:impersonate | proxy user.

  • Proxy user - Superusers Acting On Behalf Of Other Users

Hadoop提供了一種使用超級用戶,偽裝成普通用戶訪問集群組件的辦法。這種辦法,在hadoop的代碼級別做了支持。在gateway機器和後端機器進行rpc kerberos認證時,仍然使用gateway機器上的principal去獲取tgt。但真正在做訪問控制時,使用impersonate技術,superuser會模擬普通用戶。這就解決了Q1-S1問題。這是以犧牲一部分絕對安全性為代價,換來了複雜度的減少。不過由於在企業內部,gateway機器,以及後端機器,都是被管理員嚴格控制的,所以這是一個行之有效的技術。

tips:還有一個比較生動的例子來解釋這個solution的合理性:1.一個「警察」,他擁有超越普通公民的權利,但他在執行任務時,可以裝扮成便衣,這樣他在訪問商店,辦理事務時,會被作為「普通」公民對待。這是合法的。2.但一個普通公民,你要是裝扮成「警察」,那就應該被抓住,是違法行為。

impersonate技術並非允許所有gateway伺服器/所有進程,都可以做impersonate。這種行為是被嚴格控制的,需要admin把這些配置在hadoop的配置文件中。

-----------------------------------------

Q2-S2. 解決辦法同上Q1-S1。

-----------------------------------------

Q3-S2. KDC承受壓力,有dos的風險(deny of service).

常規解法:給KDC做sharding,做負載均衡。

  • 是的,KDC不外乎也就是一個server,下面掛一個db,那麼理論上肯定是可以做sharding和負載均衡的。但這樣做,真的是又給本來就複雜的實施kerberos環境增加了更多的複雜性。

Hadoop解法:Delegation-Tokens

這個delegation-tokens值得好好的說一說。上面我們提到了大量的mapreduce tasks 會造成KDC的 DOS (deny of service). 我們通過下圖,在來看一下:

map-reduce tasks on workernodes

圖中的紅線表明: 一個mr job里,會切分成很多的workernode的task進程,他們在運行時,會向hdfs的namenode,或者hadoop的其它組件諸如kms,發出rpc請求。 我們知道,在kerberos環境中,每一次rpc請求,都要經過驗證,都要去kdc獲取tgt,那麼這就會導致KDC承受大量的traffic.

所以hadoop就弄出了Delegation Tokens這樣一個輕量級的authentication解決方案來代替分散式mr job場景下的Kerberos authentication. Kerberos是一個三方協議; 相反, Delegation Token認證是一個兩方協議.

Delegation Tokens的工作原理:

  1. client通過kerberos和namenode初始化認證,然後請求namenode拿到一個Delegation Token.
  2. client把delegation token放入提交的job的context,發送給yarn resourcemanager
  3. yarn RM 把job的執行環境初始化好,然後啟動很多container去跑mr job的子tasks,把delegation token 通過container的context再一次下發給workernodes.
  4. 每個workernode上的子task進程都使用這個delegation token去訪問namenode,而並不用再去請求一次kdc來獲取tgt.
  5. 當job結束後,RM負責去namenode把這個delegation token銷毀。

整個流程如下圖:

delegation token 生命周期

delegation token解決了分散式計算任務這種場景下,短生命周期的「子計算進程」導致的principal泛濫,重複性的給kdc造成大量請求traffic的問題。 但這種解決方案的代價,也是以犧牲了一定的安全性換來的。好在hadoop admin對整個集群是可控的。

關於delegation token,感興趣的同學可以深度兩篇文章,一篇是cloudera社區針對delegation token的詳解,另一篇是hadoop jira當中,security的設計文檔:

1.Cloudera : hadoop-delegation-tokens-explained

2.issues.apache.org/jira/

-----------------------------------------

Q4-S2. long-running的job,ticket會過期,需要處理好。

這個問題是真對hadoop上的計算任務的,普通的計算任務,time(job生命周期) < time(session-key 過期),但mapreduce是批處理,是被設計可以跑很久的。加之像sparkstreaming這種任務,是一直要running下去的,這裡就涉及了kerberos ticket的renew問題。

這個問題,對我們設計分散式系統,並沒有什麼借鑒之處。在這裡提出來,主要是因為ticket的renew,設計很複雜。那麼跑在hadoop上的計算框架,必須要自主去實現這些ticekt renew的邏輯。

通常很多on-yarn的非官方application,在coding時並沒有考慮這些,因此,這會對「部署keberos」造成很大的挑戰。這也是後面我們提到的對apply kerberos安全功能到線上,難點之一。

-----------------------------------------

小結,hadoop給我們設計分散式系統提供了哪些經驗:

1.在分散式環境下,我們可以做一些tricky的設計,捨棄「三方認證」帶來的絕對安全,退化成局部「兩方認證」來達到相對的安全。因為用kerberos來保證絕對安全,實現複雜度太高,在實現時甚至可能引入更多的bug。

2.impersonate是在鏈式安全認證模式下,解決gateway伺服器模擬最初用戶,訪問後端伺服器。

3.delegation token是一個在分散式環境下,針對大量的計算型短生命周期進程,產生的短生命周期kerberos principal泛濫,造成kdc server DOS問題的解決方案。

3.hadoop實施kerberos功能,為什麼這麼難?

kerberos上線,為什麼難?

一句話,整個Hadoop系統需要「重新配置」,「重新分發配置」,客戶程序代碼也可能需要改變,才能重新跑起來。

這不但需要停機,還可能因為update,導致啟動後進入不穩定的狀態。從而會導致對公司線上業務造成很大的影響。

我從admin & client兩個維度去羅列,把kerberos上線大致需要做哪些事情,然後自然就能體會為什麼難以實施。

Admin side:

  • 每一個hadoop組件都必須全部停機,重新配置。
  • 所有服務的conf文件都需要重配,加入kerberos的安全參數,然後重新分發,再重啟這些hadoop組件。

具體的配置步驟,可以參考cloudera社區,或者hortonworks社區,我這裡截一個圖,來證明需要重配的組件,有多多。

  1. Cloudera : Configuring Authentication
  2. Setting Up Kerberos Authentication for Non-Ambari Clusters

cdh/hdp kerberos auth conf

  • 需要有一個KDC,且必須高可用,且必須與公司內部現有的員工賬戶體系打通。
  • HA 是必須的, 否則 KDC會成為 hadoop 系統的新 SPOF.
  • KDC 必須和公司員工賬戶體系打通. 公司的個人開發機,以及所有staging/prod機器,其上的linux user/group,在KDC 的資料庫里必須存在,否則從這些機器發出的kinit認證將會不通過.
  • 很多非個人的賬戶的文件,由於歷史遺留問題,已經存在與hdfs中,他們的acl設置可能不正確。那麼這些賬戶的文件在被讀取時,可能會有問題,需要摸清楚哪些非個人賬戶需要「預先」在kdc創建,他們的文件acl設置是否合理。
  • keytab文件的分發/管理,也需要有強大的管理工具來支撐。

User side:

  • 所有的hadoop client機器conf都必須重配置,重啟
  • 這會牽扯到「所有的「data團隊所有hadoop client,所有的application client,一個也逃不了。這將是一個實施的最難點。
  • 調度系統需要重新配置
  • AirflowAzkaban/oozie /以及自研的調度系統,其worker也是hadoop client,也需要重配。
  • On-yarn的應用,需要重構
  • 我們在上一節講到了long running的job,是一個問題。正常的生命周期超過kerberos ticket expiretime的job,也是一個問題。而恰好 mr 和spark這兩個計算層的框架,幫我們解決了這些問題,諸如ticket renew等等。
  • 那麼自研發的on-yarn應用,就要自己來重構kerberos相關的代碼了。
  • 感興趣的朋友可以讀一讀hadoop apache社區的文檔:YARN Application Security
  • 某些公司的mr/spark程序,也可能跑不起來。因為在沒有kerberos時,可能沒有注意acl的問題,使用諸如 「export HADOOP_USER_NAME=hdfs」這種大鎚,那麼再kerberos上線後,這些程序都會出問題,需要重構。

-----------------------------------------小結:不論管理員/用戶,引入kerberos的代價都及其的高,必然會影響線上業務。必然會使公司的大數據業務shutdown一段時間,且還存在核心pipeline啟動不起來的風險,你說這種項目的實施難度得多大? 所以上線難。

4.退而求其次的解決方案--堡壘機

如果kerberos這麼難以實施,那怎麼辦?有沒有不絕對安全,但相對能簡單可實施的解決方案呢?

答案是:堡壘機 + 審計

  • 堡壘機上部署hadoop client,按「組」控制好粒度。
  • 嚴格配置每個組的用戶,不同組的用戶,不可以登陸到不屬於自己team的堡壘機。嚴格控制hdfs/yarn 這種超級用戶在堡壘機創建。不讓用戶"sudo su superuser".
  • 每個組只部署他需要的hadoop組件client conf,不需要的不給予部署。比如用不到直連zookeeper的,就不給他zk conf。只連hive的,就只給他配hive conf。
  • 堡壘機審計
  • 堡壘機是沒有辦法禁止用戶做操作 「export HADOOP_USER_NAME=hdfs"的。但我們可以管理好用戶的每一次登陸,管理好用戶的歷史commands,做到「事後能追查」。

這樣能做到,把hadoop用戶的活動範圍限制在最小的範疇內。在發生壞事時,可以根據hadoop的審計日誌,查詢到是哪個ip幹了壞事,然後通過ip找到對應的堡壘機,就可以落實到team。再根據堡壘機的審計日誌,可以定位到是哪一次session,即:誰,在什麼時間,操作了什麼指令。

tips: 審計就好比。法律是不允許殺人的,但是並不能預先阻止你殺人。而是在你殺人後審判你。因為絕對的防止你殺人,社會成本太高。

知乎用戶:運維人員如何搭建堡壘機(跳板機)?

除了堡壘機,還有別的土辦法嘛?

有,比如hack namenode 的代碼, /a/b/c 這種三層以內的路徑刪除操作,來自其它機器的全部過濾掉,只有來自admin結點的,予以執行。

hive 的drop table . hbase 的刪除表. 也都同理。

這種辦法看上去很low,但實際上也work的不錯。

-----------------------------------------

總結:

  1. 安全,是追求犯罪率的最低化,同時控制預防犯罪的成本。絕對安全在現實世界並不一定最有意義。kerberos的過期sessionkey設計,也是追求密鑰更新的時間間隔 小於 被破解時長。
  2. hadoop使用了kerberos, 但在一些特殊的場景時,kerberos會遇到 性能瓶頸實施複雜度瓶頸。 hadoop使用「把三方認證退化為局部兩方認證」 的 impersonate 和 delegation token技術順利的解決了問題。
  3. kerberos on hadoop 很難實施。如果實在阻力大,還有一些相對容易的方案可選。

附錄:ceph是一種分散式的對象存儲解決方案,他的認證,就沒有使用kerberos,而是使用了一種叫cephx的變種kerberos協議。Cephx ,authentication protocol #high-availability-authentication 。 他把KDC的概念揉進了ceph自己的組件monitor,避免了SPOF。且cephx發出的session-key,在所有不同角色的ceph component server之間是通用的。這個設計,和hadoop的delegation token有異曲同工之妙。


推薦閱讀:

大數據技術六:Hadoop運行環境搭建
2018智能周報 | 02.17-02.25 | 附資源地址 | AI作惡、CVPR會議、IBM量子計算揭秘……
MaxCompute 存儲優化技巧
從頭學習大數據培訓課程 數據倉儲工具 hive(七)hive 自定義 UDTF
知識布局-sql-impala解析

TAG:Hadoop | 大數據 | 網路安全 |