Skip to content

Commit 46f34a9

Browse files
authored
Improve kerberos tests in testsuite to work with Podman (#257)
Signed-off-by: Marko Strukelj <marko.strukelj@gmail.com>
1 parent 45eb5ec commit 46f34a9

File tree

18 files changed

+134
-68
lines changed

18 files changed

+134
-68
lines changed

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@
109109
<maven.resources.version>3.3.0</maven.resources.version>
110110
<spotbugs.version>4.7.3</spotbugs.version>
111111
<sonatype.nexus.staging>1.7.0</sonatype.nexus.staging>
112-
<kafka.version>3.7.1</kafka.version>
112+
<kafka.version>3.9.0</kafka.version>
113113
<jackson.version>2.15.3</jackson.version>
114114
<jackson.databind.version>2.15.3</jackson.databind.version>
115115
<jsonpath.version>2.9.0</jsonpath.version>

testsuite/common/src/main/java/io/strimzi/testsuite/oauth/common/TestContainersWatcher.java

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ public void starting(Description description) {
8181

8282
protected void outputLogs() {
8383
// Dump the logs to stdout
84+
environment.getContainerByServiceName("kerberos_1").ifPresent(c -> System.out.println("\n\n'kerberos' log:\n\n" + c.getLogs() + "\n"));
8485
environment.getContainerByServiceName("kafka_1").ifPresent(c -> System.out.println("\n\n'kafka' log:\n\n" + c.getLogs() + "\n"));
8586
environment.getContainerByServiceName("mockoauth_1").ifPresent(c -> System.out.println("\n\n'mockoauth' log:\n\n" + c.getLogs() + "\n"));
8687
environment.getContainerByServiceName("keycloak_1").ifPresent(c -> System.out.println("\n\n'keycloak' log:\n\n" + c.getLogs() + "\n"));

testsuite/common/src/main/java/io/strimzi/testsuite/oauth/common/TestUtil.java

+17
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,23 @@ public static List<String> getContainerLogsForString(String containerName, Strin
6464
}
6565
}
6666

67+
/**
68+
* Copy a file from a container to the host using 'docker cp'.
69+
*
70+
* @param containerName The name of the source container
71+
* @param srcPath The path to the source file in the container
72+
* @param destPath The path to the destination file on the host
73+
*/
74+
@SuppressFBWarnings("THROWS_METHOD_THROWS_RUNTIMEEXCEPTION")
75+
public static void copyFileFromContainer(String containerName, String srcPath, String destPath) {
76+
try {
77+
Process p = Runtime.getRuntime().exec(new String[] {"docker", "cp", containerName + ":" + srcPath, destPath});
78+
p.waitFor();
79+
} catch (Throwable e) {
80+
throw new RuntimeException("Failed to copy file from container", e);
81+
}
82+
}
83+
6784
/**
6885
* Helper method to wait for a condition by periodically testing the condition until it is satisfied or until timeout.
6986
*

testsuite/docker/kerberos/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ FROM ubuntu:22.04
22

33
RUN DEBIAN_FRONTEND=noninteractive apt-get update -y && apt-get install -y krb5-kdc krb5-admin-server
44

5-
EXPOSE 88 749
5+
EXPOSE 1088 1749
66

77
ADD ./config.sh /config.sh
88

testsuite/docker/kerberos/config.sh

+61-32
Original file line numberDiff line numberDiff line change
@@ -10,88 +10,117 @@
1010
: ${KAFKA_USER:=kafka}
1111
: ${KAFKA_HOST:=kafka}
1212
: ${KAFKA_CLIENT_USER:=client}
13+
: ${KDC_ADDRESS:=$(hostname -f)}
14+
: ${KEYTABS_SHARED_DIR:=/keytabs}
1315

14-
fix_nameserver() {
15-
cat>/etc/resolv.conf<<EOF
16-
nameserver $NAMESERVER_IP
17-
search $SEARCH_DOMAINS
18-
EOF
19-
}
2016

21-
fix_hostname() {
22-
sed -i "/^hosts:/ s/ *files dns/ dns files/" /etc/nsswitch.conf
23-
}
2417

2518
create_config() {
26-
: ${KDC_ADDRESS:=$(hostname -f)}
27-
2819
cat>/etc/krb5.conf<<EOF
29-
[logging]
30-
default = FILE:/var/log/kerberos/krb5libs.log
31-
kdc = FILE:/var/log/kerberos/krb5kdc.log
32-
admin_server = FILE:/var/log/kerberos/kadmind.log
33-
3420
[libdefaults]
35-
default_realm = $REALM
21+
default_realm = KERBEROS
3622
dns_lookup_realm = false
3723
dns_lookup_kdc = false
3824
ticket_lifetime = 24h
3925
renew_lifetime = 7d
4026
forwardable = true
27+
rdns = false
28+
ignore_acceptor_hostname = true
4129
4230
[realms]
43-
$REALM = {
44-
kdc = $KDC_ADDRESS
45-
admin_server = $KDC_ADDRESS
31+
KERBEROS = {
32+
kdc = kerberos:1088
33+
admin_server = kerberos
4634
}
4735
4836
[domain_realm]
49-
.$DOMAIN_REALM = $REALM
50-
$DOMAIN_REALM = $REALM
37+
.kerberos = KERBEROS
38+
kerberos = KERBEROS
5139
EOF
40+
echo "Created config: /etc/krb5.conf"
41+
cat /etc/krb5.conf
42+
}
43+
44+
45+
create_service_config() {
46+
cat>/etc/krb5kdc/kdc.conf<<EOF
47+
[logging]
48+
default = FILE:/var/log/kerberos/krb5libs.log
49+
kdc = FILE:/var/log/kerberos/krb5kdc.log
50+
admin_server = FILE:/var/log/kerberos/kadmind.log
51+
52+
[kdcdefaults]
53+
kdc_ports = 1750,1088
54+
55+
[realms]
56+
KERBEROS = {
57+
database_name = /var/lib/krb5kdc/principal
58+
admin_keytab = FILE:/etc/krb5kdc/kadm5.keytab
59+
acl_file = /etc/krb5kdc/kadm5.acl
60+
key_stash_file = /etc/krb5kdc/stash
61+
kdc_ports = 1750,1088
62+
max_life = 10h 0m 0s
63+
max_renewable_life = 7d 0h 0m 0s
64+
#master_key_type = aes256-cts
65+
#supported_enctypes = aes256-cts:normal aes128-cts:normal
66+
#default_principal_flags = +preauth
67+
}
68+
EOF
69+
echo "Created service config: /etc/krb5kdc/kdc.conf"
70+
cat /etc/krb5kdc/kdc.conf
5271
}
5372

5473
create_db() {
5574
kdb5_util -P $KERB_MASTER_KEY -r $REALM create -s
75+
echo "Created db"
5676
}
5777

5878
start_kdc() {
5979
service krb5-kdc start
6080
service krb5-admin-server start
6181
}
6282

63-
restart_kdc() {
64-
service krb5-kdc restart
65-
service krb5-admin-server restart
66-
}
67-
6883
create_admin_user() {
6984
kadmin.local -q "addprinc -pw $KERB_ADMIN_PASS $KERB_ADMIN_USER/admin"
7085
echo "*/admin@$REALM *" > /etc/krb5kdc/kadm5.acl
86+
echo "Created admin user in /etc/krb5kdc/kadm5.acl"
7187
}
7288

7389
create_kafka_user() {
7490
kadmin.local -q "addprinc -randkey $KAFKA_HOST/$KAFKA_USER@$REALM"
75-
kadmin.local -q "ktadd -k /keytabs/kafka_broker.keytab $KAFKA_HOST/$KAFKA_USER@$REALM"
91+
kadmin.local -q "ktadd -k /etc/krb5/kafka_broker.keytab $KAFKA_HOST/$KAFKA_USER@$REALM"
7692
kadmin.local -q "addprinc -randkey $KAFKA_HOST/$KAFKA_CLIENT_USER@$REALM"
77-
kadmin.local -q "ktadd -k /keytabs/kafka_client.keytab $KAFKA_HOST/$KAFKA_CLIENT_USER@$REALM"
78-
chmod 666 /keytabs/kafka_broker.keytab
79-
chmod 666 /keytabs/kafka_client.keytab
93+
kadmin.local -q "ktadd -k /etc/krb5/kafka_client.keytab $KAFKA_HOST/$KAFKA_CLIENT_USER@$REALM"
94+
echo "Created keytab files for kafka user and kafka client:"
95+
ls -la /etc/krb5
96+
chmod 666 /etc/krb5/kafka_broker.keytab
97+
chmod 666 /etc/krb5/kafka_client.keytab
8098
}
8199

82-
100+
copy_keytab_files() {
101+
cp -r /etc/krb5/* $KEYTABS_SHARED_DIR
102+
}
83103

84104
if [ ! -f /kerberos_initialized ]; then
85105
mkdir -p /var/log/kerberos
106+
mkdir /etc/krb5
107+
echo "Created directories:"
108+
ls -la /var/log/kerberos
109+
ls -la /etc/krb5
110+
111+
create_service_config
86112
create_config
87113
create_db
88114
create_admin_user
89115
create_kafka_user
116+
copy_keytab_files
90117
start_kdc
91118

92119
touch /kerberos_initialized
93120
else
94121
start_kdc
95122
fi
96123

124+
# Startup condition is based on the output of the log file
125+
# See MockOAuthTests.java
97126
tail -F /var/log/kerberos/krb5kdc.log

testsuite/docker/kerberos/krb5.conf

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
[logging]
2-
default = FILE:/var/log/kerberos/krb5libs.log
3-
kdc = FILE:/var/log/kerberos/krb5kdc.log
4-
admin_server = FILE:/var/log/kerberos/kadmind.log
51
[libdefaults]
62
default_realm = KERBEROS
73
dns_lookup_realm = false
@@ -13,7 +9,7 @@
139
ignore_acceptor_hostname = true
1410
[realms]
1511
KERBEROS = {
16-
kdc = kerberos
12+
kdc = kerberos:1088
1713
admin_server = kerberos
1814
}
1915
[domain_realm]

testsuite/hydra-test/docker-compose.yml

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: '3'
2-
31
services:
42

53
hydra:

testsuite/keycloak-auth-tests/docker-compose.yml

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: '3'
2-
31
services:
42
keycloak:
53
image: quay.io/keycloak/keycloak:23.0.5

testsuite/keycloak-authz-kraft-tests/docker-compose.yml

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: '3'
2-
31
services:
42
keycloak:
53
image: quay.io/keycloak/keycloak:23.0.5
@@ -134,8 +132,9 @@ services:
134132
# The following value will be available as env var STRIMZI_OAUTH_METRIC_REPORTERS
135133
- STRIMZI_OAUTH_METRIC_REPORTERS=org.apache.kafka.common.metrics.JmxReporter
136134

137-
# The following value will turn to 'strimzi.oauth.metric.reporters=...' in 'strimzi.properties' file
135+
# The following value will turn into 'strimzi.oauth.metric.reporters=...' in 'strimzi.properties' file
138136
# However, that won't work as the value may be filtered to the component that happens to initialise OAuthMetrics
137+
# Instead, use the env var approach above
139138
#- KAFKA_STRIMZI_OAUTH_METRIC_REPORTERS=org.apache.kafka.common.metrics.JmxReporter
140139

141140

testsuite/keycloak-authz-tests/docker-compose.yml

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: '3'
2-
31
services:
42
keycloak:
53
image: quay.io/keycloak/keycloak:23.0.5

testsuite/keycloak-authz-zk-tests/docker-compose.yml

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: '3'
2-
31
services:
42
keycloak:
53
image: quay.io/keycloak/keycloak:23.0.5

testsuite/mock-oauth-server/pom.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121

2222
<properties>
2323
<checkstyle.dir>../..</checkstyle.dir>
24-
<vertx.version>4.4.8</vertx.version>
25-
<logback.version>1.3.14</logback.version>
24+
<vertx.version>4.5.11</vertx.version>
25+
<logback.version>1.3.15</logback.version>
2626

2727
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
2828
<maven-shade-plugin.version>3.2.4</maven-shade-plugin.version>

testsuite/mock-oauth-server/src/main/java/io/strimzi/testsuite/oauth/server/MockOAuthServerMainVerticle.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ Future<Void> ensureAuthServer(String keystorePath, String keystorePass, Mode mod
198198

199199
authServer = vertx.createHttpServer(new HttpServerOptions()
200200
.setSsl(true)
201-
.setKeyStoreOptions(keyOptions)
201+
.setKeyCertOptions(keyOptions)
202202
)
203203
.requestHandler(new AuthServerRequestHandler(this))
204204
.listen(8090)

testsuite/mockoauth-tests/docker-compose-kerberos.yml

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: '3'
2-
31
services:
42
mockoauth:
53
image: testsuite/mock-oauth-server
@@ -45,7 +43,7 @@ services:
4543
- ${PWD}/../docker/kafka/scripts:/opt/kafka/strimzi
4644
- ${PWD}/../docker/kerberos/krb5.conf:/etc/krb5.conf
4745
- ${PWD}/../docker/kerberos/kafka_server_jaas.conf:/opt/kafka/kafka_server_jaas.conf
48-
- ${PWD}/../docker/kerberos/keys:/opt/kafka/keytabs
46+
- kerberos-volume:/opt/kafka/keytabs:ro
4947
command:
5048
- /bin/bash
5149
- -c
@@ -123,6 +121,7 @@ services:
123121
# The following value will turn into 'strimzi.oauth.metric.reporters=...' in 'strimzi.properties' file
124122
# However, that won't work as the value may be filtered to the component that happens to initialise OAuthMetrics
125123
#- KAFKA_STRIMZI_OAUTH_METRIC_REPORTERS=org.apache.kafka.common.metrics.JmxReporter
124+
126125
- KAFKA_LISTENER_NAME_KERBEROS_SASL_KERBEROS_SERVICE_NAME=kafka
127126
- KAFKA_LISTENER_NAME_KERBEROS_SASL_ENABLED_MECHANISMS=GSSAPI
128127
- KAFKA_OPTS=-Djava.security.krb5.conf=/etc/krb5.conf -Djava.security.auth.login.config=/opt/kafka/kafka_server_jaas.conf
@@ -133,13 +132,13 @@ services:
133132
- "2181:2181"
134133
volumes:
135134
- ${PWD}/../docker/zookeeper/scripts:/opt/kafka/strimzi
136-
- ${PWD}/../docker/kafka/kerberos/keys:/keytabs
137135
command:
138136
- /bin/bash
139137
- -c
140138
- cd /opt/kafka/strimzi && ./start.sh
141139
environment:
142140
- LOG_DIR=/tmp/logs
141+
143142
kerberos:
144143
build: ${PWD}/../docker/kerberos
145144
hostname: 'kerberos'
@@ -149,8 +148,11 @@ services:
149148
- KERB_MASTER_KEY=masterkey
150149
- KERB_ADMIN_USER=admin
151150
- KERB_ADMIN_PASS=admin
152-
volumes:
153-
- ${PWD}/../docker/kerberos/keys:/keytabs
154151
ports:
155-
- "749:749"
156-
- "88:88/udp"
152+
- "1749:1749"
153+
- "1088:1088/udp"
154+
volumes:
155+
- kerberos-volume:/keytabs
156+
157+
volumes:
158+
kerberos-volume:

testsuite/mockoauth-tests/docker-compose.yml

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: '3'
2-
31
services:
42
mockoauth:
53
image: testsuite/mock-oauth-server

testsuite/mockoauth-tests/src/test/java/io/strimzi/testsuite/oauth/MockOAuthTests.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,9 @@ public void runTests() throws Exception {
112112
new ClientAssertionAuthTest().doTest();
113113

114114
if (includeKerberosTests) {
115+
String kerberosContainer = includeKerberosTests ? environment.getContainerByServiceName("kerberos_1").get().getContainerInfo().getName().substring(1) : null;
115116
logStart("KerberosTests :: Test authentication with Kerberos");
116-
new KerberosListenerTest().doTests();
117+
new KerberosListenerTest(kerberosContainer).doTests();
117118
}
118119

119120
} catch (Throwable e) {

testsuite/mockoauth-tests/src/test/java/io/strimzi/testsuite/oauth/mockoauth/KerberosListenerTest.java

+11-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55
package io.strimzi.testsuite.oauth.mockoauth;
66

7+
import io.strimzi.testsuite.oauth.common.TestUtil;
78
import org.apache.kafka.clients.admin.Admin;
89
import org.apache.kafka.clients.admin.CreateTopicsResult;
910
import org.apache.kafka.clients.admin.NewTopic;
@@ -31,16 +32,24 @@ public class KerberosListenerTest {
3132
private static final long CONSUMER_TIMEOUT = 10000L;
3233
private static final int MESSAGE_COUNT = 100;
3334

35+
private final String kerberosContainer;
36+
37+
public KerberosListenerTest(String kerberosContainer) {
38+
this.kerberosContainer = kerberosContainer;
39+
}
40+
3441
public void doTests() throws Exception {
3542

36-
File keyTab = new File("../docker/kerberos/keys/kafka_client.keytab");
43+
File keyTab = new File("target/kafka_client.keytab");
44+
TestUtil.copyFileFromContainer(kerberosContainer, "/keytabs/kafka_client.keytab", keyTab.getAbsolutePath());
3745
Assert.assertTrue(keyTab.exists());
3846
Assert.assertTrue(keyTab.canRead());
3947

4048
Properties props = new Properties();
4149
props.put("security.protocol", "SASL_PLAINTEXT");
4250
props.put("sasl.kerberos.service.name", "kafka");
43-
props.put("sasl.jaas.config", "com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true storeKey=true keyTab='../docker/kerberos/keys/kafka_client.keytab' principal='kafka/client@KERBEROS';");
51+
props.put("sasl.jaas.config", "com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true storeKey=true keyTab='" +
52+
keyTab.getAbsolutePath() + "' principal='kafka/client@KERBEROS';");
4453
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "kafka:9099");
4554

4655
Admin admin = Admin.create(props);

0 commit comments

Comments
 (0)