ZooKeeper のセキュリティ

以下の例に従うことで、ZooKeeper のセキュリティを有効にできます。Confluent Platform のセキュリティの完全な例については、「セキュリティのチュートリアル」を参照してください。

注釈

ZooKeeper を使用してブローカーを認証する場合は、すべてのブローカーについて zookeeper.set.acl=true を設定します。デフォルトの設定(zookeeper.set.acl=false)を受け入れた場合、ACL は作成されず、誰でも ZooKeeper の情報を書き込めるようになります。

ZooKeeper の認証の概要

バージョン 3.5.x 以降の ZooKeeper では、相互 TLS(mTLS)認証がサポートされています。バージョン 2.5 以降の Kafka では、SASL または mTLS、あるいはその両方を使用した ZooKeeper への認証がサポートされています。詳細については、KIP-515 参照してください。

mTLS だけを使用する場合、ブローカーや CLI ツール(ZooKeeper セキュリティ移行ツール ZkSecurityMigrator など)はすべて、同じ識別名(DN)で識別する必要があります。DN は ZooKeeper の ACL に含まれているため、ZooKeeper ではその DN のみが認可されます。したがって、ZooKeeper へのすべての接続でその DN を提供する必要があります。DN から ACL に入力される内容は変更できますが、それにはカスタムの ZooKeeper 認証プロバイダーを作成しデプロイする作業が必要になります。詳細については、「mTLS 認証」を参照してください。ブローカーおよび CLI ツールで ZooKeeper ホスト名の検証を成功させるには、各 CA 証明書で同じ DN を使用し、異なる SAN(Subject Alternative Name)を指定する必要があります。

ZooKeeper で SASL 認証と mTLS 認証を同時に使用する場合は、SASL ID と、znode を作成した DN(作成したブローカーの CA 証明書)またはセキュリティ移行ツールの DN(znode の作成後に移行が実行された場合)が ACL に含まれています。このとき、すべてのブローカーと CLI ツールに同じ SASL ID が使用されるため、すべての DN が異なっていても認可されます。mTLS 認証のみを使用する場合は、すべての DN が一致する必要があり、カスタムの ZooKeeper 認証プロバイダーを作成およびデプロイしていなければ、SAN が不可欠になります。

SASL 認証

このセクションでは、ZooKeeper で SASL 認証を有効にして使用する方法について説明します。SASL 資格情報が平文で送信されないように TLS 暗号化を追加する方法の詳細については、「TLS を使用した ZooKeeper への通信の暗号化」を参照してください。

SASL による ZooKeeper 認証の有効化

SASL による ZooKeeper 認証を有効にするには、以下を zookeeper.properties に追加します。

authProvider.sasl=org.apache.zookeeper.server.auth.SASLAuthenticationProvider

Digest-MD5 を利用した SASL

ZooKeeper ノードの JAAS ファイルの例を以下に示します。

Server {
       org.apache.zookeeper.server.auth.DigestLoginModule required
       user_super="adminsecret"
       user_bob="bobsecret";
};

ブローカーや管理スクリプト(kafka-topics など)を含む、ZooKeeper クライアントの JAAS ファイルの例を以下に示します。

Client {
       org.apache.zookeeper.server.auth.DigestLoginModule required
       username="bob"
       password="bobsecret";
};

Kafka ブローカーの JAAS ファイルが既にある場合は、このセクションを追加する必要があります。

Kerberos を利用した SASL

ZooKeeper ノードの JAAS ファイルの例を以下に示します。

Server {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    keyTab="<path-to-server-keytab>"
    storeKey=true
    useTicketCache=false
    principal="zookeeper/yourzkhostname@EXAMPLE.COM";
};

ブローカーや管理スクリプト(kafka-topics など)を含む、ZooKeeper クライアントの JAAS ファイルの例を以下に示します。

Client {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    storeKey=true
    keyTab="<path-to-client-keytab>"
    principal="kafka/kafka1.hostname.com@EXAMPLE.COM";
};

注釈

ZooKeeper を起動する前に、JAAS 構文とキータブのアクセス許可を確認してください。サーバーの起動を妨げる最も一般的なエラーは、JAAS 構文エラーと、キータブファイルに誤って設定されたアクセス許可です。詳細については、「TLS を使用した ZooKeeper への通信の暗号化」を参照してください。

mTLS 認証

SASL 認証を使用するかどうかにかかわらず、ZooKeeper mTLS 認証を有効にできます。

ZooKeeper に接続するすべてのクライアントは ID を共有する必要があり、すべての接続には 0 個以上の ID が関連付けられます。2 つの ID が存在する可能性もあります(たとえば、mTLS と SASL の両方が有効になっていて、クライアントが両方で正常に認証された場合)。mTLS を SASL で使用する場合、mTLS が共通 ID のソースである必要はありません。すべてのユーザーが同じ SASL ID を使用できます。

SASL 認証を使用せずに mTLS を有効にする場合、ブローカーや CLI ツール(ZooKeeper セキュリティ移行ツール ZkSecurityMigrator など)はすべて、同じ識別名(DN)で識別する必要があります。デフォルトでは、完全な DN が ZooKeeper の ACL に含まれており、ZooKeeper では ACL に含まれているエントリのみが認可されるため、ZooKeeper へのすべての接続で、その DN を提供する必要があります。ただし ZooKeeper は、この単一の DN を使用して、リクエストの発信元である複数のホストにマップすることはできません。このため、各 CA 証明書には SAN(Subject Alternative Name)を含める必要があります。SAN がない場合、ブローカーや CLI ツールのホスト名検証は失敗し、ZooKeeper への接続は拒否されます。

DN と SAN の要件を理解するために、Web サイト https://meeting.bigdata.us を閲覧するシナリオについて考えてみましょう。サイトの CA 証明書には、DN として CN=meeting.bigdata.us が含まれている必要があります(または、ワイルドカード証明書の場合は CN=*.bigdata.us)。含まれていない場合は、ホスト名の検証に失敗し、ブラウザーへの接続が拒否されます。同様に、クライアントが ZooKeeper への mTLS 接続を確立した場合に、クライアントのホスト名が foo.example.org であれば、DN として CN=foo.example.org が含まれた証明書(または、CN=*.example.org を使用したワイルドカード証明書)を提示する必要があります。この DN が含まれた証明書を提示しない場合、foo.example.org を含む SAN(Subject Alternative Name )を定義していなければ、ZooKeeper への接続は拒否されます。SASL 認証を使用していない場合、さまざまなブローカーや CLI ツールがすべて同じ DN を使用している場合にのみ、異なるホストから mTLS を使用して ZooKeeper に接続できます。その場合、それぞれのホスト名に一致する SAN も指定する必要があります。

重要

(SASL を使用せずに)mTLS のみを使用し、zookeeper.set.acl=true を指定する場合は、ホスト名の検証に代わる手段としてリクエストの送信元の場所によってホスト名が異なる CN=hostname を指定した証明書を使用しないでください。この証明書を使用すると、ブローカーが ZooKeeper ノードにアクセスできない場合があります。ZooKeeper の ACL には完全な DN が含まれており、ZooKeeper では ACL に含まれているエントリのみが認可されます。

DN を使用する代わりに、org.apache.zookeeper.server.auth.X509AuthenticationProvider を拡張し protected String getClientId(X509Certificate clientCert) メソッドをオーバーライドするクラスを作成することによって、mTLS クライアントの ID を指定することもできます。スキーム名を選択し、ZooKeeper の authProvider.[scheme] をカスタム実装の完全修飾クラス名に設定します。次に、それを使用できるように ssl.authProvider=[scheme] を構成します。

ZooKeeper で mTLS 認証を有効にするには、ZooKeeper と Kafka の両方を構成する必要があります。次の例は、mTLS 認証を有効にする ZooKeeper 構成を示しています。

secureClientPort=2182
serverCnxnFactory=org.apache.zookeeper.server.NettyServerCnxnFactory
authProvider.x509=org.apache.zookeeper.server.auth.X509AuthenticationProvider
ssl.keyStore.location=<path-to-zookeeper-keystore>
ssl.keyStore.password=<zookeeper-keystore-password>
ssl.trustStore.location=<path-to-zookeeper-trustore>
ssl.trustStore.password=<zookeeper-truststore-password>

重要

ZooKeeper では、ZooKeeper サーバーのキーストアにあるキーパスワードをキーストアのパスワード自体と異なる値に設定することはできません。キーパスワードは、必ずキーストアのパスワードと同じになるように設定してください。

次の例は、mTLS 認証を使用して ZooKeeper に接続する Kafka 構成を示しています。

# Connect to the ZooKeeper port configured for TLS
zookeeper.connect=zk1:2182,zk2:2182,zk3:2182
# Required to use TLS-to-ZooKeeper (default is false)
zookeeper.ssl.client.enable=true
# Required to use TLS-to-ZooKeeper
zookeeper.clientCnxnSocket=org.apache.zookeeper.ClientCnxnSocketNetty
# Define key/trust stores to use TLS-to-ZooKeeper; ignored unless zookeeper.ssl.client.enable=true
zookeeper.ssl.keystore.location=<path-to-kafka-keystore>
zookeeper.ssl.keystore.password=<kafka-keystore-password>
zookeeper.ssl.truststore.location=<path-to-kafka-trustore>
zookeeper.ssl.truststore.password=<kafka-truststore-password>
# Tells broker to create ACLs on znodes
zookeeper.set.acl=true

重要

ZooKeeper では、ZooKeeper クライアントのキーストア(ブローカー)内でキーパスワードをキーストアのパスワード自体と異なる値に設定することはできません。キーパスワードは、必ずキーストアのパスワードと同じになるように設定してください。また、ZooKeeper とは異なり、Kafka では TLS 関連の構成にキャメルケース名を使用しないことに注意してください(たとえば、Kafka では zookeeper.ssl.keystore.location を使用し、ZooKeeper では ssl.keyStore.location を使用します)。

TLS を使用した ZooKeeper への通信の暗号化

mTLS を使用した ZooKeeper 接続は暗号化されます。ZooKeeper 3.5.7( Kafka 2.5 に付属のバージョン)以降、ZooKeeper ではサーバー側の構成 ssl.clientAuth=none がサポートされます。この構成では大文字と小文字の区別がなく、指定可能なオプションは、wantneed (デフォルト)、および none です。none に設定した場合、クライアントは独自の CA 証明書を提示せずに TLS 暗号化接続を使用して ZooKeeper に接続できます。

次に示す Kafka ブローカー構成(一部)は、TLS 暗号化のみを使用して ZooKeeper に接続する方法を示しています。

注釈

zookeeper.properties 内で明示的な列挙値を伴う ZooKeeper 構成(ssl.clientAuth など)では、末尾に空白を使用できません。末尾のスペースを含めると、" need " (余分な空白があります)のような値になりますが、これは指定可能な値 {want, need, none} に含まれていません。

# Connect to the ZooKeeper port configured for TLS
zookeeper.connect=zk1:2182,zk2:2182,zk3:2182
# Required to use TLS-to-ZooKeeper (default is false)
zookeeper.ssl.client.enable=true
# Required to use TLS-to-ZooKeeper
zookeeper.clientCnxnSocket=org.apache.zookeeper.ClientCnxnSocketNetty
# Define trust store to use encryption-only TLS-to-ZooKeeper; ignored unless zookeeper.ssl.client.enable=true
# There is no need to set keystore information assuming ssl.clientAuth=none on ZooKeeper
zookeeper.ssl.truststore.location=<path-to-kafka-trustore>
zookeeper.ssl.truststore.password=<kafka-truststore-password>
# Tells broker to create ACLs on znodes (if using SASL authentication, otherwise do not set)
zookeeper.set.acl=true

TLS 対応の ZooKeeper への接続(CLI ツールを使用)

CLI ツール zookeeper-security-migration.shkafka-acls.shkafka-configs.sh を使用すると、TLS 対応の ZooKeeper クォーラムに接続できます。これらのツールのいずれかを使用する場合は、ツールの TLS 構成をファイルに保存し、--zk-tls-config-file <filename> を使用してそのファイルを参照します。このファイルには、ブローカーが使用するすべての ZooKeeper 関連の構成オプションが含まれています(ただし、TLS 暗号化のみではなく、mTLS を使用する場合には異なるキーストアが使用されます)。mTLS 構成の例については「mTLS 認証」、暗号化のみの例については「TLS を使用した ZooKeeper への通信の暗号化」を参照してください。次のツール呼び出しは、--zk-tls-config-file <filename> の使用方法を示しています。

bin/kafka-acls.sh --zk-tls-config-file <filename>  --authorizer-properties zookeeper.connect=zk1:2182 --authorizer-properties zookeeper.set.acl=true --add --allow-principal User:Alice --operation Read --operation Write --topic test-topic

次のように ZooKeeper シェルを使用して、TLS 対応の ZooKeeper クォーラムに接続できます。

bin/zookeeper-shell.sh zk1:2182 -zk-tls-config-file <filename>

zookeeper-shell.sh の TLS 構成を含むファイルを識別する際には、ダブルダッシュ(--)ではなくシングルダッシュ(-)を使用してください。

ZooKeeper クォーラムの mTLS 認証

ZooKeeper サーバー間で mTLS 認証を有効にすることもできます。詳細については、「Quorum TLS」を参照してください。

デモ

mTLS や Digest-MD5 を利用した SASL など、ZooKeeper に含まれるこれらのセキュリティ機能の実用例については、「Confluent Platform のデモ」を参照してください。