ドルイドはKerberosを統合します



Druid Integrates Kerberos



バックグラウンド:
最近、ビジネス側のニーズにより、許可管理のためにKerberosをDruidに統合する必要がありますが、統合プロセス中に、参照資料が非常に少なく、基本的に検索できるすべての情報が含まれていることがわかりました。 Hdfsとkerberosの統合に取り組んだため、統合プロセス中に多くの落とし穴に遭遇しました。
この記事は、主に統合プロセスを整理して記録すると同時に、それ自体の知識の要約を目的としています。オープンソースの精神とプログラマーの相互支援の精神で、私も同様のニーズを持つ友人を助けたいと思っています

この記事は、主にKerberos内部統合と外部アクセスの2つの部分に分かれています。



外部アクセスとは、主にCommand line, browser, program他の方法でドルイドの関連リソースにアクセスすることを指します。

3、Linuxアクセス

この例ではUbuntu 16.04.2 LTS例として、Liunxの下でドルイドリソースにアクセスする方法



1.1。 登録ユーザー
kdcでは、つまりdev224.sugo.net外部クライアントが続行できるように登録しますprincipal

$ kadmin.local -q 'addprinc root@xxxxx' Authenticating as principal HTTP/root@xxxxx with password. WARNING: no policy specified for root@xxxxx defaulting to no policy Enter password for principal 'root@xxxxx': Re-enter password for principal 'root@xxxxx': Principal 'root@xxxxx' created.

二。 キータブファイルを生成する
kdcでコマンドを実行する

$ cd /var/kerberos/krb5kdc/ $ kadmin.local -q 'xst -k cyz.keytab root@xxxxx'

3.3。 Kerberosクライアントをインストールします
アクセスする外部クライアントのコマンドラインに次のコマンドを入力します。



$ sudo apt-get install krb5-user

一部のポップアップは、外部クライアントの構成に使用されるインストールプロセス中にポップアップする場合がありますkrb5.conf、ここで理解できない場合は、自由に何かを入力してインストールを続行できます。対応するものがあります。これを後でカバーする操作krb5.conf

四。 キータブと構成ファイルを取得する
-ステップ2はkdcで生成されますcyz.keytabファイルを外部クライアントにコピー/opt/apps/kerberos/keytabs目次

$ cd /var/kerberos/krb5kdc/ $ scp cyz.keytab root@xxxxx{Client IP}:/opt/apps/kerberos/keytabs
  • kdcにあります/etc/krb5.confファイルを外部クライアントにコピーします/etc内容の下:
$ scp /etc/krb5.conf root@xxxxx{Client IP}:/etc

5 外部クライアントのhostsファイルを変更します
druidクラスターのドメイン名解決をアクセスする外部クライアントに追加します。

$ cat /etc/hosts 127.0.0.1 localhost 192.168.0.225 dev225.sugo.net 192.168.0.223 dev223.sugo.net 192.168.0.224 dev224.sugo.net

6.6。 チケットを入手する
アクセスする外部クライアントで使用kinitチケットを取得するコマンド、次のように入力klistチケットを表示するコマンド:

$ kinit -k -t ../kerberos/keytabs/cyz.keytab root@xxxxx $ klist Ticket cache: FILE:/tmp/krb5cc_1000 Default principal: root@xxxxx Valid starting Expires Service principal 2017-11-28T11:23:18 2017-11-29T11:23:18 krbtgt/root@xxxxx renew until 2017-11-28T11:23:18

7。 コマンドラインからドルイドインターフェースにアクセスする
パスcurlコマンド--negotiateパラメータ、外部クライアントのコマンドラインでdruidにアクセス

$ curl --negotiate -u:cyz -X 'POST' -H 'Content-Type:application/json' -d @task-spec.json http://dev225.sugo.net:8090/druid/indexer/v1/task

8.8。 ブラウザからドルイドインターフェースにアクセスする
多くのテストの後、現在Firefoxブラウザアクセスをサポートしていますが、Chromeブラウザはサポートしていません

  • 外部クライアントでFirefoxブラウザーを開き、アドレスバーに入力しますabout:config構成ページに入り、検索network.negotiate-auth.trusted-uris item

  • ダブルクリックして入力'http://druid-coordinator-hostname:ui-port' with 'http://druid-overlord-hostname:port'、To ,個別:

http://dev225.sugo.net:8090,http://dev225.sugo.net:8081

新しく開いたページのアドレスバーに入力しますhttp://dev225.sugo.net:8090 with http://dev225.sugo.net:8081ドルイドリソースにアクセスします

4、Windowsアクセス

この例ではWin7 WindowsでDruidリソースにアクセスする方法を説明する例としてのオペレーティングシステム

  1. ユーザーを登録し、keytabファイルを取得します
    参照Linux accessステップ1および2は、kdcでユーザー登録を実行し、keytabファイル操作を生成し、keytabファイルをクライアントに配置しますC:ProgramDataKerberoskeytabs便宜上、この例では引き続き| _ + _を使用します。 |ユーザーとroot@xxxxxファイル

  2. 外部クライアントのhostsファイルを変更します
    クライアントで変更cyz.keytabディレクトリの下C:WindowsSystem32driversetcファイルで、ドルイドクラスターのドメイン名解決をファイルに追加します

hosts

オペレーティングシステムがプロンプトを表示する場合があることに注意してください192.168.0.225 dev225.sugo.net 192.168.0.223 dev223.sugo.net 192.168.0.224 dev224.sugo.netファイルは編集できません。ファイルの内容をコピーして別のディレクトリに作成できますhostsファイルを貼り付けてから、上記の内容を追加し、新しいものを入れてくださいhostsファイルのコピー先hosts元のファイルを上書きC:WindowsSystem32driversetcファイル

3.3。 Kerberosクライアントをインストールします
MITKerberosダウンロードページ 独自のオペレーティングシステムの数字に従って、対応するインストールパッケージをダウンロードします。この例では、クライアントはダウンロードします kfw-4.1-amd64.msi 。ダウンロード直後にダブルクリックすると、特別な設定なしでインストールを自動的に完了できます

四。 外部クライアントのKerberos構成を変更します
-外部クライアントを変更するhostsファイル
WindowsシステムでのKerberos構成ファイルはkrb5.ini、Not krb5.iniです。3番目のステップでクライアントをインストールした後、ファイルは次の場所にありますkrb5.confディレクトリ内、見つからない場合は、 Windowsファイルブラウザで検索できますC:ProgramDataMITKerberos5。 kdcを変更しますkrb5.iniファイルの内容をコピーして上書きしますkrb5.conf file

  • クライアントのパス変数を変更します
    3番目のステップでクライアントをインストールすると、クライアントは独自の実行ディレクトリをPATHに自動的に追加します。デフォルトはkrb5.iniです。ただし、一部のマシンにインストールされている一部のjdkは、ソフトウェアを待機するC:Program FilesMITKerberosin待機するため、次のように入力しますkinit, ktab, klist実行はjdkのツールまたはkinit 、klistパスの下のコマンド、したがって、 kfwパスを最初に配置してから、クライアントを再起動する必要があります。

5.5。 チケットを入手する
クライアントのdosウィンドウで使用C:WindowsSystem32チケットを取得するコマンド、次のように入力しますkinitチケットを表示するコマンド:

klist

デスクトップを開くC:Users>kinit -k -t C:ProgramDataKerberoskeytabs root@xxxxx.COM C:Users>klist Ticket cache: API:Initial default ccache Default principal: root@xxxxx.COM Valid starting Expires Service principal 11/28/17 14:38:40 11/29/17 14:38:40 krbtgt/SUGO.COM@SUGO.COM renew until 11/28/17 14:38:40ショートカット、クリックMIT Kerberos Ticket Managerボタン、ポップアップウィンドウに手動で入力Get Ticketおよび対応するパスワードの取得root@xxxxx

6.6。 ブラウザからドルイドインターフェースにアクセスする
現在、WindowsシステムでのFirefoxブラウザアクセスのみをサポートしており、コマンドラインticketコマンドとChromeブラウザへのアクセスはサポートしていません。

  • 外部クライアントでFirefoxブラウザーを開き、アドレスバーに入力しますcurl構成ページに入る

  • 構成ページで、次のプロパティを1つずつ検索して構成します。

about:config

新しく開いたページのアドレスバーに入力しますnetwork.negotiate-auth.trusted-uris = http://dev225.sugo.net:8090,http://dev225.sugo.net:8081 network.negotiate-auth.using-native-gsslib = false network.negotiate-auth.gsslib = C:Program FilesMITKerberosingssapi32.dll network.auth.use-sspi = false network.negotiate-auth.allow-non-fqdn = true with http://dev225.sugo.net:8090ドルイドリソースにアクセスします。アクセスできない場合は、Firefoxブラウザを再起動して再度アクセスしてください。

5、プログラムへのアクセス

この例はLinuxシステムで使用されていますhttp://dev225.sugo.net:8081例として、ドルイドリソースにアクセスするためのプログラムを作成する方法

  1. ユーザーを登録し、keytabファイルを取得します
    参照HttpClientステップ1および2は、kdcでユーザー登録を実行し、キータブファイル操作を生成し、キータブファイルをクライアントに配置しますLinux accessディレクトリでは、この例は引き続き便宜上使用されます/opt/apps/kerberos/keytabsユーザーとroot@xxxxxファイル

  2. krb5.confを入手する
    変更cyz.keytabファイルを外部クライアントにコピー/etc/krb5.conf内容の下:

/etc

3.3。 クライアントのhostsファイルを変更します
参照$ scp /etc/krb5.conf root@xxxxx{Client IP}:/etcステップ5で、druidクラスターのドメイン名解決をクライアントに追加します

四。 アクセスプログラムを書く

  • 新しいMavenプロジェクトを作成します。pomファイルは以下に依存します
Linux access
  • アクセスプログラムを書く
<properties> <httpclient.version>4.3.3httpclient.version> <httpcore.version>4.3.3httpcore.version> properties> <dependencies> <dependency> <groupId>org.apache.httpcomponentsgroupId> <artifactId>httpclientartifactId> <version>${httpclient.version}version> dependency> <dependency> <groupId>org.apache.httpcomponentsgroupId> <artifactId>httpcoreartifactId> <version>${httpcore.version}version> dependency> <dependency> <groupId>org.apache.commonsgroupId> <artifactId>commons-ioartifactId> <version>1.3.2version> dependency> dependencies>

プログラムの実行結果:

import org.apache.commons.io.IOUtils import org.apache.http.HttpResponse import org.apache.http.auth.AuthSchemeProvider import org.apache.http.auth.AuthScope import org.apache.http.auth.Credentials import org.apache.http.client.HttpClient import org.apache.http.client.config.AuthSchemes import org.apache.http.client.methods.HttpGet import org.apache.http.client.methods.HttpPost import org.apache.http.client.methods.HttpUriRequest import org.apache.http.config.Lookup import org.apache.http.config.RegistryBuilder import org.apache.http.entity.StringEntity import org.apache.http.impl.auth.SPNegoSchemeFactory import org.apache.http.impl.client.BasicCredentialsProvider import org.apache.http.impl.client.CloseableHttpClient import org.apache.http.impl.client.HttpClientBuilder import javax.security.auth.Subject import javax.security.auth.kerberos.KerberosPrincipal import javax.security.auth.login.AppConfigurationEntry import javax.security.auth.login.Configuration import javax.security.auth.login.LoginContext import java.io.IOException import java.security.Principal import java.security.PrivilegedAction import java.util.HashMap import java.util.HashSet import java.util.Set /** * Created by cyz on 2017/11/23 * Update date: * Time: 18:33 * Describle : * Result of Test: Test passed * Command: * Email: root@xxxxx */ public class HttpClientWithAuth { public static String user ='root@xxxxx' public static String keytab='/opt/apps/kerberos/keytabs/cyz.keytab' public static String krb5Location='/etc/krb5.conf' public static String isDebugStr = 'false' private String principal private String keyTabLocation public HttpClientWithAuth(String principal, String keyTabLocation, String krb5Location) { this.principal = principal this.keyTabLocation = keyTabLocation System.setProperty('java.security.krb5.conf', krb5Location) System.setProperty('sun.security.spnego.debug', isDebugStr) // System.setProperty('sun.security.krb5.debug', isDebugStr) } //Simulate curl command to use kerberos authentication private static HttpClient buildSpengoHttpClient() { HttpClientBuilder builder = HttpClientBuilder.create() Lookup authSchemeRegistry = RegistryBuilder.create(). register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory(true)).build() //Using SPNEGO certification scheme builder.setDefaultAuthSchemeRegistry(authSchemeRegistry) BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider() //kerberos ticket provider credentialsProvider.setCredentials(new AuthScope(null, -1, null), new Credentials() { @Override public Principal getUserPrincipal() { return null } @Override public String getPassword() { return null } }) builder.setDefaultCredentialsProvider(credentialsProvider) CloseableHttpClient httpClient = builder.build() return httpClient } //Configure kerberos properties private Configuration getKerberosConfig(){ return new Configuration() { @SuppressWarnings('serial') @Override public AppConfigurationEntry[] getAppConfigurationEntry(String name) { return new AppConfigurationEntry[] { new AppConfigurationEntry('com.sun.security.auth.module.Krb5LoginModule', AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, new HashMap() { { put('useTicketCache', 'false') put('useKeyTab', 'true') put('keyTab', keyTabLocation) //Krb5 in GSS API needs to be refreshed so it does not throw the error //Specified version of key is not available put('refreshKrb5Config', 'true') put('principal', principal) put('storeKey', 'true') put('doNotPrompt', 'true') put('isInitiator', 'true') put('debug', isDebugStr) } }) } } } } //Http Get Method public HttpResponse callRestUrl(final String url,final String userId) { System.out.println(String.format('Calling KerberosHttpClient %s %s %s',this.principal, this.keyTabLocation, url)) Set princ = new HashSet(1) princ.add(new KerberosPrincipal(userId)) Subject sub = new Subject(false, princ, new HashSet(), new HashSet()) try { //Authentication module: Krb5Login LoginContext lc = new LoginContext('Krb5Login', sub, null, getKerberosConfig()) lc.login() Subject serviceSubject = lc.getSubject() return Subject.doAs(serviceSubject, new PrivilegedAction() { HttpResponse httpResponse = null @Override public HttpResponse run() { try { HttpUriRequest request = new HttpGet(url) HttpClient spnegoHttpClient = buildSpengoHttpClient() httpResponse = spnegoHttpClient.execute(request) return httpResponse } catch (IOException ioe) { ioe.printStackTrace() } return httpResponse } }) } catch (Exception le) { le.printStackTrace() } return null } //Http Post Method public HttpResponse postRestUrl(final String url,final String userId,final String params) { System.out.println(String.format('Calling KerberosHttpClient %s %s %s',this.principal, this.keyTabLocation, url)) Set princ = new HashSet(1) princ.add(new KerberosPrincipal(userId)) Subject sub = new Subject(false, princ, new HashSet(), new HashSet()) try { //Authentication module: Krb5Login LoginContext lc = new LoginContext('Krb5Login', sub, null, getKerberosConfig()) lc.login() Subject serviceSubject = lc.getSubject() return Subject.doAs(serviceSubject, new PrivilegedAction() { HttpResponse httpResponse = null @Override public HttpResponse run() { try { StringEntity entity = new StringEntity(params,'UTF-8') entity.setContentEncoding('UTF-8') entity.setContentType('application/json') HttpPost httpPost = new HttpPost(url) httpPost.setEntity(entity) HttpClient spnegoHttpClient = buildSpengoHttpClient() httpResponse = spnegoHttpClient.execute(httpPost) return httpResponse } catch (IOException ioe) { ioe.printStackTrace() } return httpResponse } }) } catch (Exception le) { le.printStackTrace() } return null } public static void main(String[] args) throws UnsupportedOperationException, IOException { HttpClientWithAuth restTest = new HttpClientWithAuth(user,keytab,krb5Location) String supervisorUrl = 'http://dev225.sugo.net:8090/druid/indexer/v1/supervisor' String params = '{ ' + ' 'queryType':'lucene_timeBoundary', ' + ' 'dataSource':'druid-test002', ' + ' 'context':null, ' + ' 'intervals':'1000/3000', ' + ' 'bound':null ' + '}' String brokerUrl = 'http://dev225.sugo.net:8082/druid/v2?pretty' HttpResponse response = restTest.postRestUrl(brokerUrl,user,params) //Query maxTime, minTime of data source printResponse(response) response = restTest.callRestUrl(supervisorUrl,user) //Get the running supervisor printResponse(response) } public static void printResponse(HttpResponse response) throws IOException { System.out.println('Status code ' + response.getStatusLine().getStatusCode()) System.out.println('Return value: '+new String(IOUtils.toByteArray(response.getEntity().getContent()), 'UTF-8')) } }

6、まとめ

この記事では、ドルイド統合Kerberos認証のプロセスを紹介します。次の点に注意する必要があります。
1.ホストを構成します。ホスト名には小文字を使用してください。
2.Kerberosクライアントとサーバーが接続されていることを確認します
3.JREに付属のJCEjarパッケージを交換します
4.キータブの権限を設定します
5.サービスを開始する前に、チケットを取得してから、関連するコマンドを実行します

また、外部からの訪問では、頻繁に使用されるChromeブラウザがサポートされていないのは残念です。友達がこの問題を解決できるなら、共有することを歓迎します。