1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Flink on Yarn Kerberos安全認(rèn)證

        共 8548字,需瀏覽 18分鐘

         ·

        2020-12-22 23:10

        點(diǎn)擊上方藍(lán)色字體,選擇“設(shè)為星標(biāo)

        回復(fù)”資源“獲取更多資源

        大數(shù)據(jù)技術(shù)與架構(gòu)
        點(diǎn)擊右側(cè)關(guān)注,大數(shù)據(jù)開發(fā)領(lǐng)域最強(qiáng)公眾號(hào)!

        大數(shù)據(jù)真好玩
        點(diǎn)擊右側(cè)關(guān)注,大數(shù)據(jù)真好玩!



        Flink作為新一代的大數(shù)據(jù)處理引擎,其批流一體化的設(shè)計(jì)與出色的流處理性能,在業(yè)界得到了很多頭部公司的青睞。目前運(yùn)行Flink的集群多采用Yarn進(jìn)行資源管理,這是最成熟的方案。Yarn做為Hadoop生態(tài)系統(tǒng)中的工具之一,客戶端通常需要經(jīng)過Kerberos認(rèn)證才能使用Yarn提交或管理任務(wù)。那么Flink任務(wù)是如何提交到帶有Kerberos認(rèn)證的Yarn集群的呢?我們先從Kerberos的原理開始說起,再說如何讓Flink在帶有Kerberos認(rèn)證的Yarn集群上跑起來,知其然知其所以然。

        為什么需要Kerberos

        在Hadoop1.0.0或者CDH3以前,Hadoop集群中的所有節(jié)點(diǎn)幾乎就是裸奔的,主要存在以下安全問題:

        • NameNode與JobTracker上沒有用戶認(rèn)證,用戶可以偽裝成管理員入侵到一個(gè)HDFS 或者M(jìn)apReduce集群上。

        • DataNode上沒有認(rèn)證:Datanode對(duì)讀入輸出并沒有認(rèn)證,如果知道block的ID,就可以任意的訪問DataNode上block的數(shù)據(jù)

        • JobTracker上沒有認(rèn)證:可以任意的殺死或更改用戶的jobs,也可以更改JobTracker的工作狀態(tài)

        • 沒有對(duì)DataNode與TaskTracker的認(rèn)證:用戶可以偽裝成DataNode與TaskTracker,去接受JobTracker與Namenode的任務(wù)指派。

        為了解決這些問題,kerberos認(rèn)證出現(xiàn)了,它實(shí)現(xiàn)的是機(jī)器級(jí)別的安全認(rèn)證。

        kerberos是希臘神話中的三頭狗,地獄之門的守護(hù)者

        其原理是事先將集群中的機(jī)器添加到kerberos數(shù)據(jù)庫中,在數(shù)據(jù)庫中分別產(chǎn)生主機(jī)與各個(gè)節(jié)點(diǎn)的keytab,并將這些keytab分發(fā)到對(duì)應(yīng)的節(jié)點(diǎn)上。通過這些keytab文件,節(jié)點(diǎn)可以從數(shù)據(jù)庫中獲得與目標(biāo)節(jié)點(diǎn)通信的密鑰防止身份被冒充。針對(duì)Hadoop集群可以解決兩方面的認(rèn)證

        • 解決服務(wù)器到服務(wù)器的認(rèn)證,確保不會(huì)冒充服務(wù)器的情況。集群中的機(jī)器都是是可靠的,有效防止了用戶偽裝成Datanode,Tasktracker,去接受JobTracker,Namenode的任務(wù)指派。

        • 解決client到服務(wù)器的認(rèn)證,防止用戶惡意冒充client提交作業(yè),也無法發(fā)送對(duì)于作業(yè)的操作到JobTracker上,即使知道datanode的相關(guān)信息,也無法讀取HDFS上的數(shù)據(jù)。

        對(duì)于具體到用戶粒度上的權(quán)限控制,如哪些用戶可以提交某種類型的作業(yè),哪些用戶不能,目前Kerberos還沒有實(shí)現(xiàn),需要有專門的ACL模塊進(jìn)行把控。

        Kerberos認(rèn)證過程

        Kerberos認(rèn)證過程會(huì)涉及以下幾個(gè)基本概念:

        • Principal(安全個(gè)體):被認(rèn)證的個(gè)體,有一個(gè)名字和口令,每個(gè)server都對(duì)應(yīng)一個(gè)principal,其格式如下,@前面部分為具體身份,后面的部分稱為REALM。

        component1 / component2 @ REALM
        • KDC(key distribution center ) : 是一個(gè)網(wǎng)絡(luò)服務(wù),提供ticket 和臨時(shí)會(huì)話密鑰。

        • Ticket:一個(gè)記錄,客戶用它來向服務(wù)器證明自己的身份,包括客戶標(biāo)識(shí)、會(huì)話密鑰、時(shí)間戳。

        • AS (Authentication Server):認(rèn)證服務(wù)器,率屬于KDC,用于認(rèn)證Client身份。

        • TGS(Ticket Granting Server):許可證服務(wù)器,率屬于KDC。

        事先對(duì)集群中確定的機(jī)器由管理員手動(dòng)添加到kerberos數(shù)據(jù)庫中,在KDC上分別產(chǎn)生主機(jī)與各個(gè)節(jié)點(diǎn)的keytab(包含了host和對(duì)應(yīng)節(jié)點(diǎn)的名字,還有他們之間的密鑰——Master Key),并將這些keytab分發(fā)到對(duì)應(yīng)的節(jié)點(diǎn)上。

        1. AS Exchange

        通過這個(gè)過程,KDC(確切地說是KDC中的Authentication Service)可以實(shí)現(xiàn)對(duì)Client身份的確認(rèn),并頒發(fā)給該Client一個(gè)TGT。具體過程如下:

        Client向KDC的Authentication Service發(fā)送Authentication Service Request(KRB_AS_REQ), 為了確保KRB_AS_REQ僅限于自己和KDC知道,Client使用自己的Master Key對(duì)KRB_AS_REQ的內(nèi)容進(jìn)行加密。KRB_AS_REQ內(nèi)容主要包括:

        • Pre-authentication data:用于證明自己知道自己聲稱的那個(gè)account的Password,一般是一個(gè)被Client的Master key加密過的Timestamp。

        • Client信息: 可以理解為client的principal。

        • TGS的Server Name。

        AS在接收到的KRB_AS_REQ后從Account Database中提取Client對(duì)應(yīng)的Master Key對(duì)Pre-authentication data進(jìn)行解密,如果是一個(gè)合法的Timestamp,則可以證明發(fā)送方的確是Client信息中聲稱的那個(gè)人。

        驗(yàn)證通過之后,AS將一份Authentication Service Response(KRB_AS_REP)發(fā)送給請求方。KRB_AS_REQ主要包含兩個(gè)部分:該Client的Master Key加密過的Session Key(SKDC-Client:Logon Session Key)和被自己(KDC)的Master Key加密的TGT。而TGT大體又包含以下的內(nèi)容:

        • Session Key;

        • Client信息:即Client的principal;

        • End time: TGT到期的時(shí)間。

        Client通過自己的Master Key對(duì)第一部分解密獲得Session Key之后,利用TGT便可以進(jìn)行Kerberos認(rèn)證的下一步:TGS Exchange。

        2. TGS Exchange

        Client先向TGS發(fā)送Ticket Granting Service Request(KRB_TGS_REQ),其主要內(nèi)容為:

        • 被KDC的Master Key加密的TGT;

        • Authenticator:用于驗(yàn)證確認(rèn)Client提供的那個(gè)TGT是否是AS頒發(fā)給它的,其內(nèi)容為Client信息與Timestamp,并且用Session Key進(jìn)行加密。

        • Client信息;

        • Server信息:Client試圖訪問的Server的Principal。

        TGS收到KRB_TGS_REQ后,先使用他自己的Master Key對(duì)TGT進(jìn)行解密,從而獲得Session Key。隨后使用該Session Key解密Authenticator,通過比較Authenticator中的Client InfoSession Ticket中的Client Info從而實(shí)現(xiàn)對(duì)Client的驗(yàn)證。

        驗(yàn)證通過向?qū)Ψ桨l(fā)送Ticket Granting Service Response(KRB_TGS_REP)。這個(gè)KRB_TGS_REP有兩部分組成:使用Logon Session Key(SKDC-Client)加密過用于Client和Server認(rèn)證的Session Key(SServer-Client)和使用Server的Master Key進(jìn)行加密的Ticket。該Ticket大體包含以下一些內(nèi)容:

        • Session Key:SServer-Client;

        • Client信息;

        • End time: Ticket的到期時(shí)間。

        Client收到KRB_TGS_REP,使用Logon Session Key(SKDC-Client)解密第一部分后獲得Session Key(SServer-Client)。有了Session Key和Ticket,Client就可以和Server進(jìn)行交互,這時(shí)無須KDC介入了。我們看看 Client是如何使用Ticket與Server怎樣進(jìn)行交互的。

        3. CS(Client/Server )Exchange

        先是Client向Server認(rèn)證自己的身份。這個(gè)過程與TGS Exchange中認(rèn)證的過程類似,Client創(chuàng)建用于證明自己就是Ticket的真正所有者的Authenticator,并使用上一步獲得的Session Key(SServer-Client)進(jìn)行加密,然后將它和Ticket一起作為Application Service Request(KRB_AP_REQ)發(fā)送給Server。

        除了上述兩項(xiàng)內(nèi)容之外,KRB_AP_REQ還包含一個(gè)Flag用于表示Client是否需要進(jìn)行雙向驗(yàn)證(Mutual Authentication)。

        Server接收到KRB_AP_REQ之后,通過自己的Master Key解密Ticket,從而獲得Session Key(SServer-Client)。通過Session Key(SServer-Client)解密Authenticator,進(jìn)而驗(yàn)證對(duì)方的身份。驗(yàn)證成功,讓Client訪問需要訪問的資源,否則直接拒絕對(duì)方的請求。

        對(duì)于需要進(jìn)行雙向驗(yàn)證,Server從Authenticator提取Timestamp,使用Session Key(SServer-Client)進(jìn)行加密,并將其發(fā)送給Client用于Client驗(yàn)證Server的身份。

        Flink on Kerberos Yarn實(shí)現(xiàn)方式

        在客戶端使用Kerberos認(rèn)證來獲取服務(wù)時(shí),需要經(jīng)過三個(gè)步驟:

        • 認(rèn)證:客戶端向認(rèn)證服務(wù)器發(fā)送一條報(bào)文,并獲取一個(gè)含時(shí)間戳的TGT。

        • 授權(quán):客戶端使用TGT向TGS請求一個(gè)服務(wù)Ticket。

        • 服務(wù)請求:客戶端向服務(wù)器出示服務(wù)Ticket,以證實(shí)自己的合法性。

        其關(guān)鍵在于獲取TGT,客戶端有了它就可以申請?jiān)L問服務(wù)。所以第一種方式就是使用

        1. 使用Delegation token

        如果本地安裝了Kerberos客戶端,可以使用kinit命令來獲取TGT,

        • 可以使用密碼來向KDC申請

        kinit wanghuan70
        Password for [email protected]:


        • 也可以直接使用keytab來獲取,keytab文件中包含了密碼的散列值;

        kinit -kt wanghuan70.keytab wanghuan70

        使用klist命令可以查看獲取到的tgt的詳細(xì)信息,包括Client principal、Service principal、位置、有效期等;

        $ klist
        Ticket cache: FILE:/tmp/krb5cc_2124
        Default principal: [email protected]

        Valid starting Expires Service principal
        08/03/2017 09:31:52 08/11/2017 09:31:52 krbtgt/IDC.XXX- [email protected]
        renew until 08/10/2017 09:31:52

        在Flink client上執(zhí)行這一系列操作后,再在Flink配置文件flink-conf.yaml里面添加如下配置

        security.kerberos.login.use-ticket-cache: true

        這時(shí)Flink客戶端就可以像一般情況一樣直接用command向Yarn集群提交任務(wù)了。但是tgt有一個(gè)有效期,通常是一周,過期了就無法使用了,所以這種方式不適合長期任務(wù)。這就有了第二種方式——使用keytab,先獲取token,后臺(tái)再啟動(dòng)一個(gè)進(jìn)程定期刷新token。

        2. 使用keytab

        這種方式時(shí)通過客戶端將keytab提交到Hadoop集群,再通過YARN分發(fā)keytab給AM和其他 worker container,具體步驟如下

        • Flink客戶端在提交任務(wù)時(shí),將keytab上傳至HDFS,將其作為AM需要本地化的資源。

        • AM container初始化時(shí)NodeManager將keytab拷貝至container的資源目錄,然后再AM啟動(dòng)時(shí)通過UserGroupInformation.loginUserFromKeytab()來重新認(rèn)證。

        • 當(dāng)AM需要申請其他worker container時(shí),也將 HDFS 上的keytab列為需要本地化的資源,因此worker container也可以仿照AM的認(rèn)證方式進(jìn)行認(rèn)證。

        • 此外AM和container都必須額外實(shí)現(xiàn)一個(gè)線程來定時(shí)刷新TGT。


        任務(wù)運(yùn)行結(jié)束后,集群中的keytab也會(huì)隨container被清理掉。

        使用這種方式的話,F(xiàn)link客戶端需要持有keytab文件,并且在Flink配置文件flink-conf.yaml里面添加如下配置

        security.kerberos.login.keytab: /home/hadoop_runner/hadoop-3.2.1/etc/hadoop/krb5.keytab
        security.kerberos.login.principal: superuser
        security.kerberos.login.contexts: Client

        注意:Flink客戶端進(jìn)行Kerberos認(rèn)證是在加載集群動(dòng)態(tài)配置之前進(jìn)行的,所以需要在flink-conf.yaml文件中位置principal與keytab。在命令行中添加這個(gè)配置參數(shù),實(shí)際還是用客戶端的用戶名作為principal進(jìn)行認(rèn)證,會(huì)報(bào)找不到tgt的錯(cuò)誤。

        設(shè)置Hadoop代理用戶

        出于于安全考慮,很多時(shí)候我們希望客戶端能以某一個(gè)hadoop用戶的身份去運(yùn)提交任務(wù)、訪問hdfs文件,目前實(shí)現(xiàn)方式主要有以下幾種

        • client端root用戶su為joe用戶,再使用joe用戶的名義提交作業(yè),但這種方法前提是客戶端已經(jīng)有joe的token,并且會(huì)造成潛在的權(quán)限濫用風(fēng)險(xiǎn)。

        • 設(shè)置環(huán)境變量或者系統(tǒng)變量HADOOP_USER_NAME,例如希望訪問hdfs文件,并在hdfs中進(jìn)行讀寫操作,可將用戶名設(shè)置為hdfs,因?yàn)樵趆dfs文件系統(tǒng)中hdfs具有最高權(quán)限。這種方法對(duì)于帶有Kerberos認(rèn)證的Hadoop集群并不起作用。

         export HADOOP_USER_NAME=hdfs
        • 設(shè)置環(huán)境變量或者系統(tǒng)變量HADOOP_PROXY_USER,即設(shè)置Hadoop代理用戶,因?yàn)閷?duì)于帶有Kerberos認(rèn)證的集群,都是通過UserGroupInformation進(jìn)行認(rèn)證的,用戶名是由getLoginUser方法獲取的。

            @Public
        @Evolving
        public static synchronized UserGroupInformation getLoginUser() throws IOException {
        if (loginUser == null) {
        loginUserFromSubject((Subject)null);
        }

        return loginUser;
        }


        @Public
        @Evolving
        public static synchronized void loginUserFromSubject(Subject subject) throws IOException {
        ensureInitialized();

        try {
        if (subject == null) {
        subject = new Subject();
        }

        LoginContext login = newLoginContext(authenticationMethod.getLoginAppName(), subject, new UserGroupInformation.HadoopConfiguration());
        login.login();
        UserGroupInformation realUser = new UserGroupInformation(subject);
        realUser.setLogin(login);
        realUser.setAuthenticationMethod(authenticationMethod);
        realUser = new UserGroupInformation(login.getSubject());
        String proxyUser = System.getenv("HADOOP_PROXY_USER");
        if (proxyUser == null) {
        proxyUser = System.getProperty("HADOOP_PROXY_USER");
        }

        loginUser = proxyUser == null ? realUser : createProxyUser(proxyUser, realUser);
        String fileLocation = System.getenv("HADOOP_TOKEN_FILE_LOCATION");
        if (fileLocation != null) {
        Credentials cred = Credentials.readTokenStorageFile(new File(fileLocation), conf);
        loginUser.addCredentials(cred);
        }

        loginUser.spawnAutoRenewalThreadForUserCreds();
        } catch (LoginException var6) {
        LOG.debug("failure to login", var6);
        throw new IOException("failure to login", var6);
        }

        if (LOG.isDebugEnabled()) {
        LOG.debug("UGI loginUser:" + loginUser);
        }

        }

        然而直接在客戶端設(shè)置這個(gè)環(huán)境變量或者Java系統(tǒng)變量是不work的,因?yàn)閷?shí)際訪問Hadoop的Operator是在TaskManager中運(yùn)行的,所以需要將這個(gè)變量傳到運(yùn)行tm的NodeManager中,可以通過在Flink客戶端配置參數(shù)env.ssh.opts或者env.java.opts來實(shí)現(xiàn)。

        env.java.opts: -DHADOOP_PROXY_USER=hdfs # 配置所有Flink進(jìn)程的JVM啟動(dòng)參數(shù)
        env.ssh.opts: export HADOOP_PROXY_USER=hdfs # 啟動(dòng)jm、tm、zookeeper等服務(wù)的額外命令

        也可以通過配置containerized.master.env.與containerized.taskmanager.env.來傳遞環(huán)境變量。

        然而,在目前版本(Flink 1.10)中,如果配置了keytab文件與Principal,F(xiàn)link在后續(xù)中始終會(huì)以該P(yáng)rincipal的名義提交任務(wù),即便配置了HADOOP_PROXY_USER也起不到效果。針對(duì)這個(gè)issue,Uber提出了Flink on Yarn Security的改進(jìn)方案,其進(jìn)展詳見Flink-11271。


        版權(quán)聲明:

        本文為大數(shù)據(jù)技術(shù)與架構(gòu)整理,原作者獨(dú)家授權(quán)。未經(jīng)原作者允許轉(zhuǎn)載追究侵權(quán)責(zé)任。
        編輯|冷眼丶
        微信公眾號(hào)|import_bigdata


        歡迎點(diǎn)贊+收藏+轉(zhuǎn)發(fā)朋友圈素質(zhì)三連




        文章不錯(cuò)?點(diǎn)個(gè)【在看】吧!??


        瀏覽 88
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            日韩一级黄色视频 | 欧美性爱乱伦视频 | 欧美抠逼视频 | 女人黄色一级片 | 国产精品久久精品 | 夜夜爽99久久国产综合精品女不卡 | 亚洲丰满熟妇大荫蒂毛茸茸 | 久久久7777 | A片 爱豆aⅴ | 国产日产欧产美韩**毛片 |