This is an automated email from the ASF dual-hosted git repository.
viktorsomogyi pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/kafka.git
The following commit(s) were added to refs/heads/trunk by this push:
new 1695e958af9 KAFKA-20419 : Add SASL_PLAINTEXT docker compose examples
and sanity test (#22023)
1695e958af9 is described below
commit 1695e958af9e343cc5f8f0a3682b3ef304e9ffd9
Author: Murali Basani <[email protected]>
AuthorDate: Fri May 15 17:18:00 2026 +0200
KAFKA-20419 : Add SASL_PLAINTEXT docker compose examples and sanity test
(#22023)
Note : these examples work only with jvm image and not with native
image. (Open issue https://issues.apache.org/jira/browse/KAFKA-19584)
Changes :
- Adding sasl_plain docker compose examples
- Updated readme
- Added sasl_flow tests (only combined and isolated modes)
Reviewers: Viktor Somogyi-Vass <[email protected]>
---
docker/examples/README.md | 64 +++++++
.../combined/sasl_plaintext/docker-compose.yml | 103 ++++++++++++
.../isolated/sasl_plaintext}/docker-compose.yml | 184 ++++++++++-----------
.../single-node/sasl_plaintext/docker-compose.yml | 45 +++++
.../fixtures/client-secrets/client-sasl.properties | 20 +++
docker/examples/fixtures/sasl/broker_jaas.conf | 22 +++
docker/test/constants.py | 5 +
docker/test/docker_sanity_test.py | 29 ++--
.../test/fixtures/mode/combined/docker-compose.yml | 10 +-
.../test/fixtures/mode/isolated/docker-compose.yml | 10 +-
docker/test/fixtures/sasl/broker_jaas.conf | 22 +++
docker/test/fixtures/sasl/client-sasl.properties | 20 +++
12 files changed, 421 insertions(+), 113 deletions(-)
diff --git a/docker/examples/README.md b/docker/examples/README.md
index 162e27c711a..1c847ce0ba1 100644
--- a/docker/examples/README.md
+++ b/docker/examples/README.md
@@ -73,6 +73,18 @@ It is also possible to use the input file to have a common
set of configurations
- Assuming that
`KAFKA_LOG4J_LOGGERS='property1=value1,property2=value2'` environment variable
is provided to Docker container.
- `log4j.logger.property1=value1` and
`log4j.logger.property2=value2` will be added to the `log4j2.yaml` file inside
Docker container.
+Running in SASL mode
+--------------------
+
+- SASL mode requires a JAAS configuration file to be mounted into the Docker
container and referenced via the `KAFKA_OPTS` environment variable.
+- Mount the directory containing the JAAS config file to `/etc/kafka/secrets`
in the Docker container.
+- Set `KAFKA_OPTS` to
`-Djava.security.auth.login.config=/etc/kafka/secrets/<jaas_config_filename>`.
+- Set `KAFKA_SASL_ENABLED_MECHANISMS` to the desired SASL mechanism (e.g.
`GSSAPI` , `PLAIN`, `SCRAM-SHA-256`, `SCRAM-SHA-512`).
+- Ensure `KAFKA_ADVERTISED_LISTENERS` contains a `SASL_PLAINTEXT://` or
`SASL_SSL://` listener.
+- For inter-broker SASL communication, set
`KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL` to the desired SASL *mechanism*
(e.g. `PLAIN`, `SCRAM-SHA-256`). To choose between `SASL_PLAINTEXT` and
`SASL_SSL` for inter-broker traffic, set `KAFKA_INTER_BROKER_LISTENER_NAME` to
a listener whose security protocol is mapped accordingly in
`KAFKA_LISTENER_SECURITY_PROTOCOL_MAP`.
+- The Docker image `configure` script will log a warning if `KAFKA_OPTS` does
not contain the `java.security.auth.login.config` property when SASL listeners
are detected.
+- For more details on SASL mechanisms and configuration, refer to the [Kafka
SASL authentication
documentation](https://kafka.apache.org/documentation/#security_sasl).
+
Running in SSL mode
-------------------
@@ -169,6 +181,25 @@ Single Node
# Run from root of the repo
$ bin/kafka-console-producer.sh --topic test --bootstrap-server
localhost:9093 --command-config
./docker/examples/fixtures/client-secrets/client-ssl.properties
```
+- SASL_PLAINTEXT:
+ - Here we use SASL/PLAIN mechanism for authentication.
+ - A JAAS configuration file is mounted into the container via a volume
mount.
+ - `KAFKA_OPTS` is set to point to the JAAS config file.
+ - Similar to the plaintext example, two listeners are configured: one for
inter-broker communication and one for client-to-broker communication. Both use
the `SASL_PLAINTEXT` security protocol.
+ - Two users are configured in the JAAS file: `admin` (for inter-broker)
and `alice` (for clients).
+ - Note: SASL is currently not supported with the GraalVM based native
image (`apache/kafka-native`) due to missing reflection configuration for
`java.security.AccessController`. See
[KAFKA-19584](https://issues.apache.org/jira/browse/KAFKA-19584) for details.
+ - To run the example:
+ ```
+ # Run from root of the repo
+
+ # JVM based Apache Kafka Docker Image
+ $ IMAGE=apache/kafka:latest docker compose -f
docker/examples/docker-compose-files/single-node/sasl_plaintext/docker-compose.yml
up
+ ```
+ - To produce messages using client scripts (Ensure that java version >=
17):
+ ```
+ # Run from root of the repo
+ $ bin/kafka-console-producer.sh --topic test --bootstrap-server
localhost:9094 --command-config
./docker/examples/fixtures/client-secrets/client-sasl.properties
+ ```
Multi Node Cluster
------------------
@@ -221,6 +252,23 @@ Multi Node Cluster
# Run from root of the repo
$ bin/kafka-console-producer.sh --topic test --bootstrap-server
localhost:29093 --command-config
./docker/examples/fixtures/client-secrets/client-ssl.properties
```
+ - SASL_PLAINTEXT:
+ - Similar to Plaintext example, with SASL/PLAIN authentication added.
+ - Similar to Plaintext example, two listeners are configured for
inter-broker and client-to-broker communication, both using the
`SASL_PLAINTEXT` security protocol. Controllers use `PLAINTEXT`.
+ - Each broker mounts the same JAAS config file. In production, each
broker should have its own credentials.
+ - Note: SASL is currently not supported with the GraalVM based native
image (`apache/kafka-native`) due to missing reflection configuration for
`java.security.AccessController`. See
[KAFKA-19584](https://issues.apache.org/jira/browse/KAFKA-19584) for details.
+ - To run the example:
+ ```
+ # Run from root of the repo
+
+ # JVM based Apache Kafka Docker Image
+ $ IMAGE=apache/kafka:latest docker compose -f
docker/examples/docker-compose-files/cluster/combined/sasl_plaintext/docker-compose.yml
up
+ ```
+ - To produce messages using client scripts (Ensure that java version
>= 17):
+ ```
+ # Run from root of the repo
+ $ bin/kafka-console-producer.sh --topic test --bootstrap-server
localhost:29094 --command-config
./docker/examples/fixtures/client-secrets/client-sasl.properties
+ ```
- Isolated:
- Examples are present in `docker-compose-files/cluster/isolated`
directory.
- Plaintext:
@@ -260,5 +308,21 @@ Multi Node Cluster
# Run from root of the repo
$ bin/kafka-console-producer.sh --topic test --bootstrap-server
localhost:29093 --command-config
./docker/examples/fixtures/client-secrets/client-ssl.properties
```
+ - SASL_PLAINTEXT:
+ - Same as combined SASL_PLAINTEXT example, with controllers and
brokers separated.
+ - `SASL_PLAINTEXT` is only for inter-broker and client communication.
Controllers use `PLAINTEXT`.
+ - Note: SASL is currently not supported with the GraalVM based native
image (`apache/kafka-native`) due to missing reflection configuration for
`java.security.AccessController`. See
[KAFKA-19584](https://issues.apache.org/jira/browse/KAFKA-19584) for details.
+ - To run the example:
+ ```
+ # Run from root of the repo
+
+ # JVM based Apache Kafka Docker Image
+ $ IMAGE=apache/kafka:latest docker compose -f
docker/examples/docker-compose-files/cluster/isolated/sasl_plaintext/docker-compose.yml
up
+ ```
+ - To produce messages using client scripts (Ensure that java version
>= 17):
+ ```
+ # Run from root of the repo
+ $ bin/kafka-console-producer.sh --topic test --bootstrap-server
localhost:29094 --command-config
./docker/examples/fixtures/client-secrets/client-sasl.properties
+ ```
- Note that the examples are meant to be tried one at a time, make sure you
close an example server before trying out the other to avoid conflicts.
diff --git
a/docker/examples/docker-compose-files/cluster/combined/sasl_plaintext/docker-compose.yml
b/docker/examples/docker-compose-files/cluster/combined/sasl_plaintext/docker-compose.yml
new file mode 100644
index 00000000000..17fadb49891
--- /dev/null
+++
b/docker/examples/docker-compose-files/cluster/combined/sasl_plaintext/docker-compose.yml
@@ -0,0 +1,103 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+---
+services:
+ kafka-1:
+ image: ${IMAGE}
+ hostname: kafka-1
+ container_name: kafka-1
+ ports:
+ - 29094:9094
+ volumes:
+ - ../../../../fixtures/sasl:/etc/kafka/secrets
+ environment:
+ KAFKA_NODE_ID: 1
+ KAFKA_PROCESS_ROLES: 'broker,controller'
+ KAFKA_LISTENER_SECURITY_PROTOCOL_MAP:
'CONTROLLER:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_PLAINTEXT_HOST:SASL_PLAINTEXT'
+ KAFKA_CONTROLLER_QUORUM_VOTERS:
'1@kafka-1:9093,2@kafka-2:9093,3@kafka-3:9093'
+ KAFKA_LISTENERS:
'SASL_PLAINTEXT://:19094,CONTROLLER://:9093,SASL_PLAINTEXT_HOST://:9094'
+ KAFKA_INTER_BROKER_LISTENER_NAME: 'SASL_PLAINTEXT'
+ KAFKA_ADVERTISED_LISTENERS:
SASL_PLAINTEXT://kafka-1:19094,SASL_PLAINTEXT_HOST://localhost:29094
+ KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
+ CLUSTER_ID: '4L6g3nShT-eMCtK--X86sw'
+ KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
+ KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
+ KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
+ KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
+ KAFKA_SHARE_COORDINATOR_STATE_TOPIC_REPLICATION_FACTOR: 1
+ KAFKA_SHARE_COORDINATOR_STATE_TOPIC_MIN_ISR: 1
+ KAFKA_LOG_DIRS: '/tmp/kraft-combined-logs'
+ KAFKA_SASL_ENABLED_MECHANISMS: 'PLAIN'
+ KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL: 'PLAIN'
+ KAFKA_OPTS:
'-Djava.security.auth.login.config=/etc/kafka/secrets/broker_jaas.conf'
+
+ kafka-2:
+ image: ${IMAGE}
+ hostname: kafka-2
+ container_name: kafka-2
+ ports:
+ - 39094:9094
+ volumes:
+ - ../../../../fixtures/sasl:/etc/kafka/secrets
+ environment:
+ KAFKA_NODE_ID: 2
+ KAFKA_PROCESS_ROLES: 'broker,controller'
+ KAFKA_LISTENER_SECURITY_PROTOCOL_MAP:
'CONTROLLER:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_PLAINTEXT_HOST:SASL_PLAINTEXT'
+ KAFKA_CONTROLLER_QUORUM_VOTERS:
'1@kafka-1:9093,2@kafka-2:9093,3@kafka-3:9093'
+ KAFKA_LISTENERS:
'SASL_PLAINTEXT://:19094,CONTROLLER://:9093,SASL_PLAINTEXT_HOST://:9094'
+ KAFKA_INTER_BROKER_LISTENER_NAME: 'SASL_PLAINTEXT'
+ KAFKA_ADVERTISED_LISTENERS:
SASL_PLAINTEXT://kafka-2:19094,SASL_PLAINTEXT_HOST://localhost:39094
+ KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
+ CLUSTER_ID: '4L6g3nShT-eMCtK--X86sw'
+ KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
+ KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
+ KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
+ KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
+ KAFKA_SHARE_COORDINATOR_STATE_TOPIC_REPLICATION_FACTOR: 1
+ KAFKA_SHARE_COORDINATOR_STATE_TOPIC_MIN_ISR: 1
+ KAFKA_LOG_DIRS: '/tmp/kraft-combined-logs'
+ KAFKA_SASL_ENABLED_MECHANISMS: 'PLAIN'
+ KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL: 'PLAIN'
+ KAFKA_OPTS:
'-Djava.security.auth.login.config=/etc/kafka/secrets/broker_jaas.conf'
+
+ kafka-3:
+ image: ${IMAGE}
+ hostname: kafka-3
+ container_name: kafka-3
+ ports:
+ - 49094:9094
+ volumes:
+ - ../../../../fixtures/sasl:/etc/kafka/secrets
+ environment:
+ KAFKA_NODE_ID: 3
+ KAFKA_PROCESS_ROLES: 'broker,controller'
+ KAFKA_LISTENER_SECURITY_PROTOCOL_MAP:
'CONTROLLER:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_PLAINTEXT_HOST:SASL_PLAINTEXT'
+ KAFKA_CONTROLLER_QUORUM_VOTERS:
'1@kafka-1:9093,2@kafka-2:9093,3@kafka-3:9093'
+ KAFKA_LISTENERS:
'SASL_PLAINTEXT://:19094,CONTROLLER://:9093,SASL_PLAINTEXT_HOST://:9094'
+ KAFKA_INTER_BROKER_LISTENER_NAME: 'SASL_PLAINTEXT'
+ KAFKA_ADVERTISED_LISTENERS:
SASL_PLAINTEXT://kafka-3:19094,SASL_PLAINTEXT_HOST://localhost:49094
+ KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
+ CLUSTER_ID: '4L6g3nShT-eMCtK--X86sw'
+ KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
+ KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
+ KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
+ KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
+ KAFKA_SHARE_COORDINATOR_STATE_TOPIC_REPLICATION_FACTOR: 1
+ KAFKA_SHARE_COORDINATOR_STATE_TOPIC_MIN_ISR: 1
+ KAFKA_LOG_DIRS: '/tmp/kraft-combined-logs'
+ KAFKA_SASL_ENABLED_MECHANISMS: 'PLAIN'
+ KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL: 'PLAIN'
+ KAFKA_OPTS:
'-Djava.security.auth.login.config=/etc/kafka/secrets/broker_jaas.conf'
diff --git a/docker/test/fixtures/mode/isolated/docker-compose.yml
b/docker/examples/docker-compose-files/cluster/isolated/sasl_plaintext/docker-compose.yml
similarity index 53%
copy from docker/test/fixtures/mode/isolated/docker-compose.yml
copy to
docker/examples/docker-compose-files/cluster/isolated/sasl_plaintext/docker-compose.yml
index 2c77fc123f1..a86379a6e31 100644
--- a/docker/test/fixtures/mode/isolated/docker-compose.yml
+++
b/docker/examples/docker-compose-files/cluster/isolated/sasl_plaintext/docker-compose.yml
@@ -15,162 +15,152 @@
---
services:
- controller1:
- image: {$IMAGE}
- hostname: controller1
- container_name: controller1
+ controller-1:
+ image: ${IMAGE}
environment:
KAFKA_NODE_ID: 1
- KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: 'CONTROLLER:PLAINTEXT'
+ KAFKA_PROCESS_ROLES: 'controller'
+ KAFKA_CONTROLLER_QUORUM_VOTERS:
'1@controller-1:9093,2@controller-2:9093,3@controller-3:9093'
+ KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
+ KAFKA_LISTENERS: 'CONTROLLER://:9093'
+ CLUSTER_ID: '4L6g3nShT-eMCtK--X86sw'
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
KAFKA_SHARE_COORDINATOR_STATE_TOPIC_REPLICATION_FACTOR: 1
KAFKA_SHARE_COORDINATOR_STATE_TOPIC_MIN_ISR: 1
- KAFKA_PROCESS_ROLES: 'controller'
- KAFKA_CONTROLLER_QUORUM_VOTERS:
'1@controller1:19092,2@controller2:19092,3@controller3:19092'
- KAFKA_LISTENERS: 'CONTROLLER://:19092'
- KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
KAFKA_LOG_DIRS: '/tmp/kraft-combined-logs'
- CLUSTER_ID: '4L6g3nShT-eMCtK--X86sw'
- controller2:
- image: {$IMAGE}
- hostname: controller2
- container_name: controller2
+ controller-2:
+ image: ${IMAGE}
environment:
KAFKA_NODE_ID: 2
- KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: 'CONTROLLER:PLAINTEXT'
+ KAFKA_PROCESS_ROLES: 'controller'
+ KAFKA_CONTROLLER_QUORUM_VOTERS:
'1@controller-1:9093,2@controller-2:9093,3@controller-3:9093'
+ KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
+ KAFKA_LISTENERS: 'CONTROLLER://:9093'
+ CLUSTER_ID: '4L6g3nShT-eMCtK--X86sw'
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
KAFKA_SHARE_COORDINATOR_STATE_TOPIC_REPLICATION_FACTOR: 1
KAFKA_SHARE_COORDINATOR_STATE_TOPIC_MIN_ISR: 1
- KAFKA_PROCESS_ROLES: 'controller'
- KAFKA_CONTROLLER_QUORUM_VOTERS:
'1@controller1:19092,2@controller2:19092,3@controller3:19092'
- KAFKA_LISTENERS: 'CONTROLLER://:19092'
- KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
KAFKA_LOG_DIRS: '/tmp/kraft-combined-logs'
- CLUSTER_ID: '4L6g3nShT-eMCtK--X86sw'
- controller3:
- image: {$IMAGE}
- hostname: controller3
- container_name: controller3
+ controller-3:
+ image: ${IMAGE}
environment:
KAFKA_NODE_ID: 3
- KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: 'CONTROLLER:PLAINTEXT'
+ KAFKA_PROCESS_ROLES: 'controller'
+ KAFKA_CONTROLLER_QUORUM_VOTERS:
'1@controller-1:9093,2@controller-2:9093,3@controller-3:9093'
+ KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
+ KAFKA_LISTENERS: 'CONTROLLER://:9093'
+ CLUSTER_ID: '4L6g3nShT-eMCtK--X86sw'
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
KAFKA_SHARE_COORDINATOR_STATE_TOPIC_REPLICATION_FACTOR: 1
KAFKA_SHARE_COORDINATOR_STATE_TOPIC_MIN_ISR: 1
- KAFKA_PROCESS_ROLES: 'controller'
- KAFKA_CONTROLLER_QUORUM_VOTERS:
'1@controller1:19092,2@controller2:19092,3@controller3:19092'
- KAFKA_LISTENERS: 'CONTROLLER://:19092'
- KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
KAFKA_LOG_DIRS: '/tmp/kraft-combined-logs'
- CLUSTER_ID: '4L6g3nShT-eMCtK--X86sw'
- broker1:
- image: {$IMAGE}
- hostname: broker1
- container_name: broker1
+ kafka-1:
+ image: ${IMAGE}
+ hostname: kafka-1
+ container_name: kafka-1
ports:
- - "9092:9092"
- - "19093:9093"
- - "9101:9101"
+ - 29094:9094
volumes:
- - ../../secrets:/etc/kafka/secrets
+ - ../../../../fixtures/sasl:/etc/kafka/secrets
environment:
KAFKA_NODE_ID: 4
- KAFKA_LISTENER_SECURITY_PROTOCOL_MAP:
'CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,SSL:SSL,PLAINTEXT_HOST:PLAINTEXT'
- KAFKA_ADVERTISED_LISTENERS:
'PLAINTEXT_HOST://localhost:9092,SSL://localhost:19093,PLAINTEXT://broker1:29092'
+ KAFKA_PROCESS_ROLES: 'broker'
+ KAFKA_LISTENER_SECURITY_PROTOCOL_MAP:
'CONTROLLER:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_PLAINTEXT_HOST:SASL_PLAINTEXT'
+ KAFKA_LISTENERS: 'SASL_PLAINTEXT://:19094,SASL_PLAINTEXT_HOST://:9094'
+ KAFKA_CONTROLLER_QUORUM_VOTERS:
'1@controller-1:9093,2@controller-2:9093,3@controller-3:9093'
+ KAFKA_INTER_BROKER_LISTENER_NAME: 'SASL_PLAINTEXT'
+ KAFKA_ADVERTISED_LISTENERS:
SASL_PLAINTEXT://kafka-1:19094,SASL_PLAINTEXT_HOST://localhost:29094
+ KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
+ CLUSTER_ID: '4L6g3nShT-eMCtK--X86sw'
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
KAFKA_SHARE_COORDINATOR_STATE_TOPIC_REPLICATION_FACTOR: 1
KAFKA_SHARE_COORDINATOR_STATE_TOPIC_MIN_ISR: 1
- KAFKA_PROCESS_ROLES: 'broker'
- KAFKA_CONTROLLER_QUORUM_VOTERS:
'1@controller1:19092,2@controller2:19092,3@controller3:19092'
- KAFKA_LISTENERS: 'PLAINTEXT_HOST://:9092,SSL://:9093,PLAINTEXT://:29092'
- KAFKA_INTER_BROKER_LISTENER_NAME: 'PLAINTEXT'
- KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
KAFKA_LOG_DIRS: '/tmp/kraft-combined-logs'
- CLUSTER_ID: '4L6g3nShT-eMCtK--X86sw'
- KAFKA_JMX_PORT: 9101
- KAFKA_JMX_HOSTNAME: localhost
- KAFKA_SSL_KEYSTORE_FILENAME: "kafka01.keystore.jks"
- KAFKA_SSL_KEYSTORE_CREDENTIALS: "kafka_keystore_creds"
- KAFKA_SSL_KEY_CREDENTIALS: "kafka_ssl_key_creds"
- KAFKA_SSL_TRUSTSTORE_FILENAME: "kafka.truststore.jks"
- KAFKA_SSL_TRUSTSTORE_CREDENTIALS: "kafka_truststore_creds"
- KAFKA_SSL_CLIENT_AUTH: "required"
+ KAFKA_SASL_ENABLED_MECHANISMS: 'PLAIN'
+ KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL: 'PLAIN'
+ KAFKA_OPTS:
'-Djava.security.auth.login.config=/etc/kafka/secrets/broker_jaas.conf'
depends_on:
- - controller1
- - controller2
- - controller3
+ - controller-1
+ - controller-2
+ - controller-3
- broker2:
- image: {$IMAGE}
- hostname: broker2
- container_name: broker2
+ kafka-2:
+ image: ${IMAGE}
+ hostname: kafka-2
+ container_name: kafka-2
ports:
- - "9093:9093"
- - "19092:9092"
+ - 39094:9094
volumes:
- - ../../secrets:/etc/kafka/secrets
+ - ../../../../fixtures/sasl:/etc/kafka/secrets
environment:
KAFKA_NODE_ID: 5
- KAFKA_LISTENER_SECURITY_PROTOCOL_MAP:
'CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,SSL:SSL,PLAINTEXT_HOST:PLAINTEXT'
- KAFKA_ADVERTISED_LISTENERS:
"PLAINTEXT_HOST://localhost:19092,SSL://localhost:9093,PLAINTEXT://broker2:29092"
+ KAFKA_PROCESS_ROLES: 'broker'
+ KAFKA_LISTENER_SECURITY_PROTOCOL_MAP:
'CONTROLLER:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_PLAINTEXT_HOST:SASL_PLAINTEXT'
+ KAFKA_LISTENERS: 'SASL_PLAINTEXT://:19094,SASL_PLAINTEXT_HOST://:9094'
+ KAFKA_CONTROLLER_QUORUM_VOTERS:
'1@controller-1:9093,2@controller-2:9093,3@controller-3:9093'
+ KAFKA_INTER_BROKER_LISTENER_NAME: 'SASL_PLAINTEXT'
+ KAFKA_ADVERTISED_LISTENERS:
SASL_PLAINTEXT://kafka-2:19094,SASL_PLAINTEXT_HOST://localhost:39094
+ KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
+ CLUSTER_ID: '4L6g3nShT-eMCtK--X86sw'
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
KAFKA_SHARE_COORDINATOR_STATE_TOPIC_REPLICATION_FACTOR: 1
KAFKA_SHARE_COORDINATOR_STATE_TOPIC_MIN_ISR: 1
- KAFKA_PROCESS_ROLES: 'broker'
- KAFKA_CONTROLLER_QUORUM_VOTERS:
'1@controller1:19092,2@controller2:19092,3@controller3:19092'
- KAFKA_LISTENERS: 'PLAINTEXT_HOST://:9092,SSL://:9093,PLAINTEXT://:29092'
- KAFKA_INTER_BROKER_LISTENER_NAME: 'PLAINTEXT'
- KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
KAFKA_LOG_DIRS: '/tmp/kraft-combined-logs'
- CLUSTER_ID: '4L6g3nShT-eMCtK--X86sw'
- KAFKA_SSL_KEYSTORE_FILENAME: "kafka01.keystore.jks"
- KAFKA_SSL_KEYSTORE_CREDENTIALS: "kafka_keystore_creds"
- KAFKA_SSL_KEY_CREDENTIALS: "kafka_ssl_key_creds"
- KAFKA_SSL_TRUSTSTORE_FILENAME: "kafka.truststore.jks"
- KAFKA_SSL_TRUSTSTORE_CREDENTIALS: "kafka_truststore_creds"
- KAFKA_SSL_CLIENT_AUTH: "required"
+ KAFKA_SASL_ENABLED_MECHANISMS: 'PLAIN'
+ KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL: 'PLAIN'
+ KAFKA_OPTS:
'-Djava.security.auth.login.config=/etc/kafka/secrets/broker_jaas.conf'
depends_on:
- - controller1
- - controller2
- - controller3
+ - controller-1
+ - controller-2
+ - controller-3
- broker3:
- image: {$IMAGE}
- hostname: broker3
- container_name: broker3
+ kafka-3:
+ image: ${IMAGE}
+ hostname: kafka-3
+ container_name: kafka-3
ports:
- - "39092:9092"
- - "9094:9093"
+ - 49094:9094
volumes:
- - ../../secrets:/etc/kafka/secrets
- - ../../file-input:/mnt/shared/config
+ - ../../../../fixtures/sasl:/etc/kafka/secrets
environment:
- CLUSTER_ID: '4L6g3nShT-eMCtK--X86sw'
- # Set a property absent from the file
KAFKA_NODE_ID: 6
- # Override existing properties
KAFKA_PROCESS_ROLES: 'broker'
- KAFKA_LISTENERS: 'PLAINTEXT_HOST://:9092,SSL://:9093,PLAINTEXT://:29092'
- KAFKA_CONTROLLER_QUORUM_VOTERS:
'1@controller1:19092,2@controller2:19092,3@controller3:19092'
+ KAFKA_LISTENER_SECURITY_PROTOCOL_MAP:
'CONTROLLER:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_PLAINTEXT_HOST:SASL_PLAINTEXT'
+ KAFKA_LISTENERS: 'SASL_PLAINTEXT://:19094,SASL_PLAINTEXT_HOST://:9094'
+ KAFKA_CONTROLLER_QUORUM_VOTERS:
'1@controller-1:9093,2@controller-2:9093,3@controller-3:9093'
+ KAFKA_INTER_BROKER_LISTENER_NAME: 'SASL_PLAINTEXT'
+ KAFKA_ADVERTISED_LISTENERS:
SASL_PLAINTEXT://kafka-3:19094,SASL_PLAINTEXT_HOST://localhost:49094
+ KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
+ CLUSTER_ID: '4L6g3nShT-eMCtK--X86sw'
+ KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
+ KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
+ KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
+ KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
+ KAFKA_SHARE_COORDINATOR_STATE_TOPIC_REPLICATION_FACTOR: 1
+ KAFKA_SHARE_COORDINATOR_STATE_TOPIC_MIN_ISR: 1
+ KAFKA_LOG_DIRS: '/tmp/kraft-combined-logs'
+ KAFKA_SASL_ENABLED_MECHANISMS: 'PLAIN'
+ KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL: 'PLAIN'
+ KAFKA_OPTS:
'-Djava.security.auth.login.config=/etc/kafka/secrets/broker_jaas.conf'
depends_on:
- - controller1
- - controller2
- - controller3
+ - controller-1
+ - controller-2
+ - controller-3
diff --git
a/docker/examples/docker-compose-files/single-node/sasl_plaintext/docker-compose.yml
b/docker/examples/docker-compose-files/single-node/sasl_plaintext/docker-compose.yml
new file mode 100644
index 00000000000..082e9fe98f3
--- /dev/null
+++
b/docker/examples/docker-compose-files/single-node/sasl_plaintext/docker-compose.yml
@@ -0,0 +1,45 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+---
+services:
+ broker:
+ image: ${IMAGE}
+ hostname: broker
+ container_name: broker
+ ports:
+ - '9094:9094'
+ volumes:
+ - ../../../fixtures/sasl:/etc/kafka/secrets
+ environment:
+ KAFKA_NODE_ID: 1
+ KAFKA_LISTENER_SECURITY_PROTOCOL_MAP:
'CONTROLLER:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_PLAINTEXT_HOST:SASL_PLAINTEXT'
+ KAFKA_ADVERTISED_LISTENERS:
'SASL_PLAINTEXT_HOST://localhost:9094,SASL_PLAINTEXT://broker:19094'
+ KAFKA_PROCESS_ROLES: 'broker,controller'
+ KAFKA_CONTROLLER_QUORUM_VOTERS: '1@broker:29093'
+ KAFKA_LISTENERS:
'CONTROLLER://:29093,SASL_PLAINTEXT_HOST://:9094,SASL_PLAINTEXT://:19094'
+ KAFKA_INTER_BROKER_LISTENER_NAME: 'SASL_PLAINTEXT'
+ KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
+ CLUSTER_ID: '4L6g3nShT-eMCtK--X86sw'
+ KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
+ KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
+ KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
+ KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
+ KAFKA_SHARE_COORDINATOR_STATE_TOPIC_REPLICATION_FACTOR: 1
+ KAFKA_SHARE_COORDINATOR_STATE_TOPIC_MIN_ISR: 1
+ KAFKA_LOG_DIRS: '/tmp/kraft-combined-logs'
+ KAFKA_SASL_ENABLED_MECHANISMS: 'PLAIN'
+ KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL: 'PLAIN'
+ KAFKA_OPTS:
'-Djava.security.auth.login.config=/etc/kafka/secrets/broker_jaas.conf'
diff --git a/docker/examples/fixtures/client-secrets/client-sasl.properties
b/docker/examples/fixtures/client-secrets/client-sasl.properties
new file mode 100644
index 00000000000..710d6930784
--- /dev/null
+++ b/docker/examples/fixtures/client-secrets/client-sasl.properties
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+security.protocol=SASL_PLAINTEXT
+sasl.mechanism=PLAIN
+sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule
required \
+ username="alice" \
+ password="alice-secret";
diff --git a/docker/examples/fixtures/sasl/broker_jaas.conf
b/docker/examples/fixtures/sasl/broker_jaas.conf
new file mode 100644
index 00000000000..d2faf584730
--- /dev/null
+++ b/docker/examples/fixtures/sasl/broker_jaas.conf
@@ -0,0 +1,22 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+KafkaServer {
+ org.apache.kafka.common.security.plain.PlainLoginModule required
+ username="admin"
+ password="admin-secret"
+ user_admin="admin-secret"
+ user_alice="alice-secret";
+};
diff --git a/docker/test/constants.py b/docker/test/constants.py
index 710e29b6961..5bc480b36c2 100644
--- a/docker/test/constants.py
+++ b/docker/test/constants.py
@@ -30,6 +30,10 @@ SSL_TOPIC="test-topic-ssl"
FILE_INPUT_FLOW_TESTS="File Input Flow Tests"
FILE_INPUT_TOPIC="test-topic-file-input"
+SASL_FLOW_TESTS="SASL Flow Tests"
+SASL_CLIENT_CONFIG="fixtures/sasl/client-sasl.properties"
+SASL_TOPIC="test-topic-sasl"
+
BROKER_RESTART_TESTS="Broker Restart Tests"
BROKER_CONTAINER="broker1"
BROKER_RESTART_TEST_TOPIC="test-topic-broker-restart"
@@ -40,6 +44,7 @@ JMX_TOOL="org.apache.kafka.tools.JmxTool"
BROKER_METRICS_HEADING='"time","kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:Count","kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:EventType","kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:FifteenMinuteRate","kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:FiveMinuteRate","kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:MeanRate","kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:OneMinuteRate","kafka.server:type=Brok
[...]
SSL_ERROR_PREFIX="SSL_ERR"
+SASL_ERROR_PREFIX="SASL_ERR"
BROKER_RESTART_ERROR_PREFIX="BROKER_RESTART_ERR"
FILE_INPUT_ERROR_PREFIX="FILE_INPUT_ERR"
BROKER_METRICS_ERROR_PREFIX="BROKER_METRICS_ERR"
diff --git a/docker/test/docker_sanity_test.py
b/docker/test/docker_sanity_test.py
index d6e648cbe0b..5efcb43b68f 100644
--- a/docker/test/docker_sanity_test.py
+++ b/docker/test/docker_sanity_test.py
@@ -24,6 +24,7 @@ import os
class DockerSanityTest(unittest.TestCase):
IMAGE="apache/kafka"
FIXTURES_DIR="."
+ MODE="jvm"
def resume_container(self):
subprocess.run(["docker", "start", constants.BROKER_CONTAINER])
@@ -119,32 +120,32 @@ class DockerSanityTest(unittest.TestCase):
return errors
- def ssl_flow(self, ssl_broker_port, test_name, test_error_prefix, topic):
+ def secure_flow(self, broker_port, client_config, test_name,
test_error_prefix, topic):
print(f"Running {test_name}")
errors = []
try:
- self.assertTrue(self.create_topic(topic, ["--bootstrap-server",
ssl_broker_port, "--command-config",
f"{self.FIXTURES_DIR}/{constants.SSL_CLIENT_CONFIG}"]))
+ self.assertTrue(self.create_topic(topic, ["--bootstrap-server",
broker_port, "--command-config", f"{self.FIXTURES_DIR}/{client_config}"]))
except AssertionError as e:
errors.append(test_error_prefix + str(e))
return errors
- producer_config = ["--bootstrap-server", ssl_broker_port,
- "--command-config",
f"{self.FIXTURES_DIR}/{constants.SSL_CLIENT_CONFIG}"]
+ producer_config = ["--bootstrap-server", broker_port,
+ "--command-config",
f"{self.FIXTURES_DIR}/{client_config}"]
self.produce_message(topic, producer_config, "key", "message")
consumer_config = [
- "--bootstrap-server", ssl_broker_port,
+ "--bootstrap-server", broker_port,
"--command-property", "auto.offset.reset=earliest",
- "--command-config",
f"{self.FIXTURES_DIR}/{constants.SSL_CLIENT_CONFIG}",
+ "--command-config", f"{self.FIXTURES_DIR}/{client_config}",
]
message = self.consume_message(topic, consumer_config)
try:
self.assertEqual(message, "key:message")
except AssertionError as e:
errors.append(test_error_prefix + str(e))
-
+
return errors
-
+
def broker_restart_flow(self):
print(f"Running {constants.BROKER_RESTART_TESTS}")
errors = []
@@ -180,15 +181,22 @@ class DockerSanityTest(unittest.TestCase):
print(constants.BROKER_METRICS_ERROR_PREFIX, str(e))
total_errors.append(str(e))
try:
- total_errors.extend(self.ssl_flow('localhost:9093',
constants.SSL_FLOW_TESTS, constants.SSL_ERROR_PREFIX, constants.SSL_TOPIC))
+ total_errors.extend(self.secure_flow('localhost:9093',
constants.SSL_CLIENT_CONFIG, constants.SSL_FLOW_TESTS,
constants.SSL_ERROR_PREFIX, constants.SSL_TOPIC))
except Exception as e:
print(constants.SSL_ERROR_PREFIX, str(e))
total_errors.append(str(e))
try:
- total_errors.extend(self.ssl_flow('localhost:9094',
constants.FILE_INPUT_FLOW_TESTS, constants.FILE_INPUT_ERROR_PREFIX,
constants.FILE_INPUT_TOPIC))
+ total_errors.extend(self.secure_flow('localhost:9094',
constants.SSL_CLIENT_CONFIG, constants.FILE_INPUT_FLOW_TESTS,
constants.FILE_INPUT_ERROR_PREFIX, constants.FILE_INPUT_TOPIC))
except Exception as e:
print(constants.FILE_INPUT_ERROR_PREFIX, str(e))
total_errors.append(str(e))
+ # SASL is not supported on native image due to missing reflection
config (KAFKA-19584)
+ if self.MODE == "jvm":
+ try:
+ total_errors.extend(self.secure_flow('localhost:9095',
constants.SASL_CLIENT_CONFIG, constants.SASL_FLOW_TESTS,
constants.SASL_ERROR_PREFIX, constants.SASL_TOPIC))
+ except Exception as e:
+ print(constants.SASL_ERROR_PREFIX, str(e))
+ total_errors.append(str(e))
try:
total_errors.extend(self.broker_restart_flow())
except Exception as e:
@@ -216,6 +224,7 @@ class DockerSanityTestIsolatedMode(DockerSanityTest):
def run_tests(image, mode, fixtures_dir):
DockerSanityTest.IMAGE = image
DockerSanityTest.FIXTURES_DIR = fixtures_dir
+ DockerSanityTest.MODE = mode
test_classes_to_run = []
if mode == "jvm" or mode == "native":
diff --git a/docker/test/fixtures/mode/combined/docker-compose.yml
b/docker/test/fixtures/mode/combined/docker-compose.yml
index 8691019d024..28513f58a96 100644
--- a/docker/test/fixtures/mode/combined/docker-compose.yml
+++ b/docker/test/fixtures/mode/combined/docker-compose.yml
@@ -23,12 +23,14 @@ services:
- "9092:9092"
- "9101:9101"
- "19093:9093"
+ - "9095:9095"
volumes:
- ../../secrets:/etc/kafka/secrets
+ - ../../sasl:/etc/kafka/sasl
environment:
KAFKA_NODE_ID: 1
- KAFKA_LISTENER_SECURITY_PROTOCOL_MAP:
'CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,SSL:SSL,PLAINTEXT_HOST:PLAINTEXT'
- KAFKA_ADVERTISED_LISTENERS:
'PLAINTEXT_HOST://localhost:9092,SSL://localhost:19093,PLAINTEXT://broker1:29092'
+ KAFKA_LISTENER_SECURITY_PROTOCOL_MAP:
'CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,SSL:SSL,PLAINTEXT_HOST:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT'
+ KAFKA_ADVERTISED_LISTENERS:
'PLAINTEXT_HOST://localhost:9092,SSL://localhost:19093,PLAINTEXT://broker1:29092,SASL_PLAINTEXT://localhost:9095'
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
@@ -37,7 +39,7 @@ services:
KAFKA_SHARE_COORDINATOR_STATE_TOPIC_MIN_ISR: 1
KAFKA_PROCESS_ROLES: 'broker,controller'
KAFKA_CONTROLLER_QUORUM_VOTERS:
'1@broker1:19092,2@broker2:19092,3@broker3:19092'
- KAFKA_LISTENERS:
'CONTROLLER://:19092,PLAINTEXT_HOST://:9092,SSL://:9093,PLAINTEXT://:29092'
+ KAFKA_LISTENERS:
'CONTROLLER://:19092,PLAINTEXT_HOST://:9092,SSL://:9093,PLAINTEXT://:29092,SASL_PLAINTEXT://:9095'
KAFKA_INTER_BROKER_LISTENER_NAME: 'PLAINTEXT'
KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
KAFKA_LOG_DIRS: '/tmp/kraft-combined-logs'
@@ -50,6 +52,8 @@ services:
KAFKA_SSL_TRUSTSTORE_FILENAME: "kafka.truststore.jks"
KAFKA_SSL_TRUSTSTORE_CREDENTIALS: "kafka_truststore_creds"
KAFKA_SSL_CLIENT_AUTH: "required"
+ KAFKA_SASL_ENABLED_MECHANISMS: 'PLAIN'
+ KAFKA_OPTS:
'-Djava.security.auth.login.config=/etc/kafka/sasl/broker_jaas.conf'
broker2:
image: {$IMAGE}
diff --git a/docker/test/fixtures/mode/isolated/docker-compose.yml
b/docker/test/fixtures/mode/isolated/docker-compose.yml
index 2c77fc123f1..24a05924f4a 100644
--- a/docker/test/fixtures/mode/isolated/docker-compose.yml
+++ b/docker/test/fixtures/mode/isolated/docker-compose.yml
@@ -83,12 +83,14 @@ services:
- "9092:9092"
- "19093:9093"
- "9101:9101"
+ - "9095:9095"
volumes:
- ../../secrets:/etc/kafka/secrets
+ - ../../sasl:/etc/kafka/sasl
environment:
KAFKA_NODE_ID: 4
- KAFKA_LISTENER_SECURITY_PROTOCOL_MAP:
'CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,SSL:SSL,PLAINTEXT_HOST:PLAINTEXT'
- KAFKA_ADVERTISED_LISTENERS:
'PLAINTEXT_HOST://localhost:9092,SSL://localhost:19093,PLAINTEXT://broker1:29092'
+ KAFKA_LISTENER_SECURITY_PROTOCOL_MAP:
'CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,SSL:SSL,PLAINTEXT_HOST:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT'
+ KAFKA_ADVERTISED_LISTENERS:
'PLAINTEXT_HOST://localhost:9092,SSL://localhost:19093,PLAINTEXT://broker1:29092,SASL_PLAINTEXT://localhost:9095'
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
@@ -97,7 +99,7 @@ services:
KAFKA_SHARE_COORDINATOR_STATE_TOPIC_MIN_ISR: 1
KAFKA_PROCESS_ROLES: 'broker'
KAFKA_CONTROLLER_QUORUM_VOTERS:
'1@controller1:19092,2@controller2:19092,3@controller3:19092'
- KAFKA_LISTENERS: 'PLAINTEXT_HOST://:9092,SSL://:9093,PLAINTEXT://:29092'
+ KAFKA_LISTENERS:
'PLAINTEXT_HOST://:9092,SSL://:9093,PLAINTEXT://:29092,SASL_PLAINTEXT://:9095'
KAFKA_INTER_BROKER_LISTENER_NAME: 'PLAINTEXT'
KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
KAFKA_LOG_DIRS: '/tmp/kraft-combined-logs'
@@ -110,6 +112,8 @@ services:
KAFKA_SSL_TRUSTSTORE_FILENAME: "kafka.truststore.jks"
KAFKA_SSL_TRUSTSTORE_CREDENTIALS: "kafka_truststore_creds"
KAFKA_SSL_CLIENT_AUTH: "required"
+ KAFKA_SASL_ENABLED_MECHANISMS: 'PLAIN'
+ KAFKA_OPTS:
'-Djava.security.auth.login.config=/etc/kafka/sasl/broker_jaas.conf'
depends_on:
- controller1
- controller2
diff --git a/docker/test/fixtures/sasl/broker_jaas.conf
b/docker/test/fixtures/sasl/broker_jaas.conf
new file mode 100644
index 00000000000..d2faf584730
--- /dev/null
+++ b/docker/test/fixtures/sasl/broker_jaas.conf
@@ -0,0 +1,22 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+KafkaServer {
+ org.apache.kafka.common.security.plain.PlainLoginModule required
+ username="admin"
+ password="admin-secret"
+ user_admin="admin-secret"
+ user_alice="alice-secret";
+};
diff --git a/docker/test/fixtures/sasl/client-sasl.properties
b/docker/test/fixtures/sasl/client-sasl.properties
new file mode 100644
index 00000000000..710d6930784
--- /dev/null
+++ b/docker/test/fixtures/sasl/client-sasl.properties
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+security.protocol=SASL_PLAINTEXT
+sasl.mechanism=PLAIN
+sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule
required \
+ username="alice" \
+ password="alice-secret";