第13章 Kerberos(GSSAPI)認証の使用
AMQ Streams では、Kafka クラスターへのシングルサインオンアクセスをセキュアにするために、Kerberos(GSSAPI)認証プロトコルの使用がサポートされます。GSSAPI は Kerberos 機能の API ラッパーで、基礎となる実装の変更からアプリケーションを渡します。
Kerberos は、対称暗号化と信頼できるサードパーティーである Kerberos Key Distribution Centre(KDC)を使用して、クライアントとサーバーが相互に認証できるようにネットワーク認証システムです。
13.1. Kerberos(GSSAPI)認証を使用するように AMQ Streams を設定
この手順では、Kafka クライアントが Kerberos(GSSAPI)認証を使用して Kafka および ZooKeeper にアクセスできるように AMQ Streams を設定する方法を説明します。
この手順では、Kerberos krb5 リソースサーバーが Red Hat Enterprise Linux ホストで設定されていることを前提としています。
この手順では、たとえば以下を設定する方法を説明します。
- サービスプリンシパル
- Kerberos ログインを使用する Kafka ブローカー
- Kerberos ログインを使用する ZooKeeper
- Kerberos 認証を使用して Kafka にアクセスするためのプロデューサーおよびコンシューマークライアント
この手順では、プロデューサーおよびコンシューマークライアントの追加設定とともに、1 台のホストでの ZooKeeper および Kafka インストール 1 つに設定された Kerberos を説明します。
前提条件
Kafka および ZooKeeper が Kerberos クレデンシャルを認証および承認するように設定できるようにするには、以下が必要です。
- Kerberos サーバーへのアクセス
- 各 Kafka ブローカーホストの Kerberos クライアント
Kerberos サーバーの設定方法や、ブローカーホストのクライアントの設定手順の詳細は、「RHEL の設定における Kerberos の例 」を参照してください。
Kerberos のデプロイ方法は、お使いのオペレーティングシステムによって異なります。Red Hat は、Red Hat Enterprise Linux に Kerberos を設定する際に Identity Management(IdM)を使用することを推奨します。Oracle または IBM JDK のユーザーは、JCE(Java Cryptography Extension)をインストールする必要があります。
認証のサービスプリンシパルの追加
Kerberos サーバーから、ZooKeeper、Kafka ブローカー、および Kafka プロデューサーおよびコンシューマークライアントのサービスプリンシパル(ユーザー)を作成します。
サービスプリンシパルは SERVICE-NAME/FULLY-QUALIFIED-HOST-NAME@DOMAIN-REALM の形式にする必要があります。
Kerberos KDC でプリンシパルキーを格納するサービスプリンシパルおよびキータブを作成します。
以下に例を示します。
-
zookeeper/node1.example.redhat.com@EXAMPLE.REDHAT.COM
-
kafka/node1.example.redhat.com@EXAMPLE.REDHAT.COM
-
producer1/node1.example.redhat.com@EXAMPLE.REDHAT.COM
consumer1/node1.example.redhat.com@EXAMPLE.REDHAT.COM
ZooKeeper サービスプリンシパルは、Kafka
config/server.properties
ファイルのzookeeper.connect
設定と同じホスト名である必要があります。zookeeper.connect=node1.example.redhat.com:2181
ホスト名が同じではない場合は、localhost が使用され、認証に失敗します。
-
ホストにディレクトリーを作成し、キータブファイルを追加します。
以下に例を示します。
/opt/kafka/krb5/zookeeper-node1.keytab /opt/kafka/krb5/kafka-node1.keytab /opt/kafka/krb5/kafka-producer1.keytab /opt/kafka/krb5/kafka-consumer1.keytab
kafka
ユーザーがディレクトリーにアクセスできることを確認します。chown kafka:kafka -R /opt/kafka/krb5
Kerberos ログインを使用するように ZooKeeper を設定する
zookeeper
用に事前に作成されたユーザープリンシパルとキータブを使用して、認証に Kerberos Key Distribution Center(KDC)を使用するように ZooKeeper を設定します。
opt/kafka/config/jaas.conf
ファイルを作成または修正して、ZooKeeper のクライアントおよびサーバー操作をサポートします。Client { com.sun.security.auth.module.Krb5LoginModule required debug=true useKeyTab=true 1 storeKey=true 2 useTicketCache=false 3 keyTab="/opt/kafka/krb5/zookeeper-node1.keytab" 4 principal="zookeeper/node1.example.redhat.com@EXAMPLE.REDHAT.COM"; 5 }; Server { com.sun.security.auth.module.Krb5LoginModule required debug=true useKeyTab=true storeKey=true useTicketCache=false keyTab="/opt/kafka/krb5/zookeeper-node1.keytab" principal="zookeeper/node1.example.redhat.com@EXAMPLE.REDHAT.COM"; }; QuorumServer { com.sun.security.auth.module.Krb5LoginModule required debug=true useKeyTab=true storeKey=true keyTab="/opt/kafka/krb5/zookeeper-node1.keytab" principal="zookeeper/node1.example.redhat.com@EXAMPLE.REDHAT.COM"; }; QuorumLearner { com.sun.security.auth.module.Krb5LoginModule required debug=true useKeyTab=true storeKey=true keyTab="/opt/kafka/krb5/zookeeper-node1.keytab" principal="zookeeper/node1.example.redhat.com@EXAMPLE.REDHAT.COM"; };
- 1
true
に設定して、キータブからプリンシパルキーを取得します。- 2
- プリンシパルキーを保存するには、
true
に設定します。 - 3
- チケットキャッシュから TGT(Ticket Granting Ticket)を取得するには、
true
に設定します。 - 4
keyTab
プロパティーは、Kerberos KDC からコピーしたキータブファイルの場所を参照します。場所およびファイルはkafka
ユーザーが読み取りできる必要があります。- 5
principal
プロパティーは、SERVICE-NAME/FULLY-QUALIFIED-HOST-NAME@DOMAIN-NAME
という形式に続く KDC ホストで作成された完全修飾プリンシパル名と一致するように設定されます。
opt/kafka/config/zookeeper.properties
を編集して、更新された JAAS 設定を使用します。# ... requireClientAuthScheme=sasl jaasLoginRenew=3600000 1 kerberos.removeHostFromPrincipal=false 2 kerberos.removeRealmFromPrincipal=false 3 quorum.auth.enableSasl=true 4 quorum.auth.learnerRequireSasl=true 5 quorum.auth.serverRequireSasl=true quorum.auth.learner.loginContext=QuorumLearner 6 quorum.auth.server.loginContext=QuorumServer quorum.auth.kerberos.servicePrincipal=zookeeper/_HOST 7 quorum.cnxn.threads.size=20
- 1
- ログイン更新の頻度をミリ秒単位で制御します。これは、チケットの更新間隔に合わせて調整できます。デフォルトは 1 時間です。
- 2
- ログインプリンシパル名の一部としてホスト名を使用するかどうかを指定します。クラスター内のすべてのノードに単一のキータブを使用している場合、これは
true
に設定されます。ただし、トラブルシューティング用に各ブローカーホストに個別のキータブおよび完全修飾プリンシパルを生成することが推奨されます。 - 3
- Kerberos ネゴシエーションのプリンシパル名からレルム名を取り除くかどうかを制御します。この設定は
false
に設定することを推奨します。 - 4
- ZooKeeper サーバーおよびクライアントの SASL 認証メカニズムを有効にします。
- 5
RequireSasl
プロパティーは、マスター選択などのクォーラムイベントに SASL 認証が必要であるかどうかを制御します。- 6
loginContext
プロパティーは、指定されたコンポーネントの認証設定に使用される JAAS 設定でログインコンテキストの名前を識別します。loginContext 名は、opt/kafka/config/jaas.conf
ファイルの関連するセクションの名前に対応します。- 7
- 識別に使用されるプリンシパル名を形成するために使用される命名規則を制御します。プレースホルダー
_HOST
は、実行時にserver.1
プロパティーによって定義されるホスト名に自動的に解決されます。
JVM パラメーターで ZooKeeper を開始し、Kerberos ログイン設定を指定します。
su - kafka export EXTRA_ARGS="-Djava.security.krb5.conf=/etc/krb5.conf -Djava.security.auth.login.config=/opt/kafka/config/jaas.conf"; /opt/kafka/bin/zookeeper-server-start.sh -daemon /opt/kafka/config/zookeeper.properties
デフォルトのサービス名(
zookeeper
)を使用していない場合は、-Dzookeeper.sasl.client.username=NAME
パラメーターを使用して名前を追加します。注記/etc/krb5.conf
の場所を使用している場合は、ZooKeeper、Kafka、または Kafka プロデューサーおよびコンシューマーの起動時に-Djava.security.krb5.conf=/etc/krb5.conf
を指定する必要はありません。
Kerberos ログインを使用するように Kafka ブローカーサーバーを設定します。
kafka
用に事前に作成されたユーザープリンシパルとキータブを使用して、認証に Kerberos Key Distribution Center(KDC)を使用するように Kafka を設定します。
以下の要素で
opt/kafka/config/jaas.conf
ファイルを変更します。KafkaServer { com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true storeKey=true keyTab="/opt/kafka/krb5/kafka-node1.keytab" principal="kafka/node1.example.redhat.com@EXAMPLE.REDHAT.COM"; }; KafkaClient { com.sun.security.auth.module.Krb5LoginModule required debug=true useKeyTab=true storeKey=true useTicketCache=false keyTab="/opt/kafka/krb5/kafka-node1.keytab" principal="kafka/node1.example.redhat.com@EXAMPLE.REDHAT.COM"; };
リスナーが SASL/GSSAPI ログインを使用できるように、
config/server.properties
ファイルのリスナー設定を変更して、Kafka クラスターの各ブローカーを設定します。SASL プロトコルをリスナーのセキュリティープロトコルのマッピングに追加し、不要なプロトコルを削除します。
以下に例を示します。
# ... broker.id=0 # ... listeners=SECURE://:9092,REPLICATION://:9094 1 inter.broker.listener.name=REPLICATION # ... listener.security.protocol.map=SECURE:SASL_PLAINTEXT,REPLICATION:SASL_PLAINTEXT 2 # .. sasl.enabled.mechanisms=GSSAPI 3 sasl.mechanism.inter.broker.protocol=GSSAPI 4 sasl.kerberos.service.name=kafka 5 ...
- 1
- リスナーが設定された 2 つのリスナーは、クライアントとの汎用通信(通信用の TLS サポート)とブローカー間の通信を行うレプリケーションリスナーの 2 つです。
- 2
- TLS 対応のリスナーの場合、プロトコル名は SASL_PLAINTEXT です。TLS が有効ではないコネクターの場合、プロトコル名は SASL_PLAINTEXT になります。SSL が必要ない場合は、
ssl.*
プロパティーを削除できます。 - 3
- Kerberos 認証の SASL メカニズムは
GSSAPI
です。 - 4
- ブローカー間通信の Kerberos 認証。
- 5
- 認証要求に使用されるサービスの名前が指定され、同じ Kerberos 設定を使用している可能性がある他のサービスと区別されます。
JVM パラメーターを使用して Kafka ブローカーを起動し、Kerberos ログイン設定を指定します。
su - kafka export KAFKA_OPTS="-Djava.security.krb5.conf=/etc/krb5.conf -Djava.security.auth.login.config=/opt/kafka/config/jaas.conf"; /opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties
ブローカーおよび ZooKeeper クラスターが以前設定され、Kerberos 以外の認証システムで動作している場合、ZooKeeper およびブローカークラスターを起動し、ログで設定エラーの有無を確認できます。
ブローカーおよび Zookeeper インスタンスを起動すると、クラスターは Kerberos 認証用に設定されます。
Kafka プロデューサーおよびコンシューマークライアントが Kerberos 認証を使用するように設定する
以前 producer1
および consumer1
用に作成されたユーザープリンシパルおよびキータブを使用して、認証に Kerberos Key Distribution Center(KDC)を使用するように Kafka プロデューサーおよびコンシューマークライアントを設定します。
Kerberos 設定をプロデューサーまたはコンシューマー設定ファイルに追加します。
以下に例を示します。
/opt/kafka/config/producer.properties
# ... sasl.mechanism=GSSAPI 1 security.protocol=SASL_PLAINTEXT 2 sasl.kerberos.service.name=kafka 3 sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \ 4 useKeyTab=true \ useTicketCache=false \ storeKey=true \ keyTab="/opt/kafka/krb5/producer1.keytab" \ principal="producer1/node1.example.redhat.com@EXAMPLE.REDHAT.COM"; # ...
/opt/kafka/config/consumer.properties
# ... sasl.mechanism=GSSAPI security.protocol=SASL_PLAINTEXT sasl.kerberos.service.name=kafka sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \ useKeyTab=true \ useTicketCache=false \ storeKey=true \ keyTab="/opt/kafka/krb5/consumer1.keytab" \ principal="consumer1/node1.example.redhat.com@EXAMPLE.REDHAT.COM"; # ...
クライアントを実行して、Kafka ブローカーからメッセージを送受信できることを確認します。
プロデューサークライアント:
export KAFKA_HEAP_OPTS="-Djava.security.krb5.conf=/etc/krb5.conf -Dsun.security.krb5.debug=true"; /opt/kafka/bin/kafka-console-producer.sh --producer.config /opt/kafka/config/producer.properties --topic topic1 --bootstrap-server node1.example.redhat.com:9094
コンシューマークライアント:
export KAFKA_HEAP_OPTS="-Djava.security.krb5.conf=/etc/krb5.conf -Dsun.security.krb5.debug=true"; /opt/kafka/bin/kafka-console-consumer.sh --consumer.config /opt/kafka/config/consumer.properties --topic topic1 --bootstrap-server node1.example.redhat.com:9094
その他のリソース
- Kerberos の man ページ: krb5.conf(5)、kinit(1)、klist(1)、および kdestroy(1)
- RHEL セットアップ上の Kerberos サーバーの例
- Kerberos チケットを使用して Kafka クラスターと認証するクライアントアプリケーションの例