Skip to content

Commit f5acb04

Browse files
committed
feat: reintroduce Docker support with enhanced Kerby KDC features
- Added `docker-compose.yml` file for a local Kerby KDC setup with multiple principals and keytabs. - Reintroduced and updated `kdc-entrypoint.sh` with dynamic client configuration and enhanced flexibility. - Included `log4j.properties`
1 parent 434bc65 commit f5acb04

4 files changed

Lines changed: 379 additions & 13 deletions

File tree

kerby-dist/docker/README.md

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
# Kerby Docker Image
2+
3+
This module builds the Kerby KDC Docker image from the current repository
4+
checkout. Build from the repository root with `-am` so Maven builds the local
5+
`kdc-dist` distribution first instead of resolving snapshot artifacts remotely.
6+
7+
```bash
8+
mvn -Dmaven.repo.local=/home/coder/.m2/repository -Pdist,docker -DskipTests \
9+
-Ddocker.image.name=apache/kerby-kdc \
10+
-Ddocker.image.tag.sha=test \
11+
-pl kerby-dist/docker -am package
12+
```
13+
14+
## Docker Compose
15+
16+
Use `docker-compose.yml` in this directory as a local Kerby KDC example:
17+
18+
```bash
19+
cd kerby-dist/docker
20+
docker compose up -d
21+
docker compose exec kerby-kdc ls -l /var/lib/kerby/keytabs
22+
docker compose exec kerberos-client cat /kerby/client/krb5.conf
23+
```
24+
25+
The example creates:
26+
27+
`app_user@EXAMPLE.COM` with password `app-user-secret`
28+
29+
`alice@EXAMPLE.COM` with password `alice-secret`
30+
31+
`bob@EXAMPLE.COM` with password `bob-secret`
32+
33+
`HTTP/api.example.com@EXAMPLE.COM` with keytab
34+
`/var/lib/kerby/keytabs/http-api.keytab`
35+
36+
`hive/hiveserver2.example.com@EXAMPLE.COM` with keytab
37+
`/var/lib/kerby/keytabs/hive.keytab`
38+
39+
`kafka/broker1.example.com@EXAMPLE.COM` with keytab
40+
`/var/lib/kerby/keytabs/kafka.keytab`
41+
42+
Copy a generated keytab to the host:
43+
44+
```bash
45+
docker compose cp kerby-kdc:/var/lib/kerby/keytabs/hive.keytab ./hive.keytab
46+
```
47+
48+
The `kerby-data` volume stores the JSON identity backend and generated keytabs.
49+
Remove it when you want a clean realm:
50+
51+
```bash
52+
docker compose down -v
53+
```
54+
55+
The KDC also generates a client Kerberos config in the same volume:
56+
57+
```text
58+
/var/lib/kerby/client/krb5.conf
59+
```
60+
61+
Other containers can mount the `kerby-data` volume read-only and use that file
62+
as `KRB5_CONFIG`. The Compose example includes a MIT krb5 client container:
63+
64+
```yaml
65+
kerberos-client:
66+
image: ghcr.io/openprojectx/kerberos:latest
67+
entrypoint: ["/bin/sh", "-c"]
68+
command: ["sleep infinity"]
69+
environment:
70+
KRB5_CONFIG: /kerby/client/krb5.conf
71+
KRB5_TRACE: /dev/stderr
72+
volumes:
73+
- kerby-data:/kerby:ro
74+
```
75+
76+
The client image has its own KDC entrypoint, so the Compose example overrides
77+
`entrypoint` and `command` to keep the container running as a client toolbox
78+
only.
79+
80+
## Principal Configuration
81+
82+
The image supports one default password principal and one default service
83+
principal:
84+
85+
```text
86+
KERBY_CLIENT_PRINCIPAL=app_user@EXAMPLE.COM
87+
KERBY_CLIENT_PASSWORD=app-user-secret
88+
KERBY_SERVICE_PRINCIPAL=HTTP/api.example.com@EXAMPLE.COM
89+
KERBY_SERVICE_KEYTAB=/var/lib/kerby/keytabs/http-api.keytab
90+
```
91+
92+
The shared client config is generated from:
93+
94+
```text
95+
KERBY_CLIENT_KDC_HOST=kerby-kdc
96+
KERBY_CLIENT_KDC_PORT=88
97+
KERBY_CLIENT_DOMAIN=example.com
98+
KERBY_CLIENT_CONF_DIR=/var/lib/kerby/client
99+
```
100+
101+
The Compose example also disables KDC preauthentication for MIT krb5 client
102+
interoperability in local development:
103+
104+
```text
105+
KERBY_PREAUTH_REQUIRED=false
106+
KERBY_PA_ENC_TIMESTAMP_REQUIRED=false
107+
```
108+
109+
Without this, MIT `kinit` can fail with `Generic preauthentication failure`
110+
after the KDC returns `Additional pre-authentication required`.
111+
112+
Add more password principals with `KERBY_EXTRA_PRINCIPALS` as a comma-separated
113+
list of `principal:password` entries:
114+
115+
```text
116+
KERBY_EXTRA_PRINCIPALS=alice@EXAMPLE.COM:alice-secret,bob@EXAMPLE.COM:bob-secret
117+
```
118+
119+
Add more service principals with `KERBY_EXTRA_SERVICE_PRINCIPALS` as a
120+
comma-separated list of `principal:/container/keytab/path` entries:
121+
122+
```text
123+
KERBY_EXTRA_SERVICE_PRINCIPALS=hive/hiveserver2.example.com@EXAMPLE.COM:/var/lib/kerby/keytabs/hive.keytab,kafka/broker1.example.com@EXAMPLE.COM:/var/lib/kerby/keytabs/kafka.keytab
124+
```
125+
126+
## MIT krb5 Client Usage
127+
128+
Install the MIT krb5 client tools on the host. Package names vary by
129+
distribution:
130+
131+
```bash
132+
sudo apt-get install krb5-user
133+
```
134+
135+
Create a host-side client config that points at the Compose service published
136+
on localhost:
137+
138+
```bash
139+
cat > ./krb5.conf <<'EOF'
140+
[libdefaults]
141+
default_realm = EXAMPLE.COM
142+
dns_lookup_kdc = false
143+
dns_lookup_realm = false
144+
rdns = false
145+
udp_preference_limit = 1
146+
147+
[realms]
148+
EXAMPLE.COM = {
149+
kdc = 127.0.0.1:88
150+
}
151+
152+
[domain_realm]
153+
.example.com = EXAMPLE.COM
154+
example.com = EXAMPLE.COM
155+
EOF
156+
```
157+
158+
Start the KDC and get a user ticket:
159+
160+
```bash
161+
docker compose up -d
162+
KRB5_CONFIG="$PWD/krb5.conf" KRB5_TRACE=/dev/stderr kinit -V app_user@EXAMPLE.COM
163+
```
164+
165+
Use `app-user-secret` when prompted. Inspect the credential cache:
166+
167+
```bash
168+
KRB5_CONFIG="$PWD/krb5.conf" klist
169+
```
170+
171+
Request service tickets for the service principals created by the Compose
172+
file:
173+
174+
```bash
175+
KRB5_CONFIG="$PWD/krb5.conf" kvno HTTP/api.example.com@EXAMPLE.COM
176+
KRB5_CONFIG="$PWD/krb5.conf" kvno hive/hiveserver2.example.com@EXAMPLE.COM
177+
KRB5_CONFIG="$PWD/krb5.conf" kvno kafka/broker1.example.com@EXAMPLE.COM
178+
KRB5_CONFIG="$PWD/krb5.conf" klist
179+
```
180+
181+
Copy a generated service keytab from the KDC container and inspect it with MIT
182+
krb5:
183+
184+
```bash
185+
docker compose cp kerby-kdc:/var/lib/kerby/keytabs/hive.keytab ./hive.keytab
186+
KRB5_CONFIG="$PWD/krb5.conf" klist -kte ./hive.keytab
187+
```
188+
189+
Validate that a service principal can authenticate from its keytab:
190+
191+
```bash
192+
KRB5_CONFIG="$PWD/krb5.conf" \
193+
kinit -kt ./hive.keytab hive/hiveserver2.example.com@EXAMPLE.COM
194+
KRB5_CONFIG="$PWD/krb5.conf" klist
195+
```
196+
197+
If the MIT client runs from another Compose service on the same Docker network,
198+
use the service name instead of the published localhost port:
199+
200+
```text
201+
[realms]
202+
EXAMPLE.COM = {
203+
kdc = kerby-kdc:88
204+
}
205+
```
206+
207+
Clean up local credentials when finished:
208+
209+
```bash
210+
KRB5_CONFIG="$PWD/krb5.conf" kdestroy
211+
```
212+
213+
## MIT krb5 Client Container Usage
214+
215+
The Compose file includes `kerberos-client` using
216+
`ghcr.io/openprojectx/kerberos:latest`. It mounts the shared Kerby data volume
217+
read-only at `/kerby`, so it can read:
218+
219+
`/kerby/client/krb5.conf`
220+
221+
`/kerby/keytabs/http-api.keytab`
222+
223+
`/kerby/keytabs/hive.keytab`
224+
225+
`/kerby/keytabs/kafka.keytab`
226+
227+
Start both services:
228+
229+
```bash
230+
docker compose up -d
231+
```
232+
233+
Get a user TGT from the client container:
234+
235+
```bash
236+
printf 'app-user-secret\n' \
237+
| docker compose exec -T kerberos-client \
238+
kinit app_user@EXAMPLE.COM
239+
```
240+
241+
List the ticket cache:
242+
243+
```bash
244+
docker compose exec kerberos-client klist
245+
```
246+
247+
Request service tickets:
248+
249+
```bash
250+
docker compose exec kerberos-client kvno HTTP/api.example.com@EXAMPLE.COM
251+
docker compose exec kerberos-client kvno hive/hiveserver2.example.com@EXAMPLE.COM
252+
docker compose exec kerberos-client kvno kafka/broker1.example.com@EXAMPLE.COM
253+
```
254+
255+
Inspect generated keytabs from the client container:
256+
257+
```bash
258+
docker compose exec kerberos-client klist -kte /kerby/keytabs/http-api.keytab
259+
docker compose exec kerberos-client klist -kte /kerby/keytabs/hive.keytab
260+
docker compose exec kerberos-client klist -kte /kerby/keytabs/kafka.keytab
261+
```
262+
263+
Authenticate using a service keytab:
264+
265+
```bash
266+
docker compose exec kerberos-client \
267+
kinit -kt /kerby/keytabs/hive.keytab hive/hiveserver2.example.com@EXAMPLE.COM
268+
docker compose exec kerberos-client klist
269+
```
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing,
11+
# software distributed under the License is distributed on an
12+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13+
# KIND, either express or implied. See the License for the
14+
# specific language governing permissions and limitations
15+
# under the License.
16+
17+
services:
18+
kerby-kdc:
19+
image: apache/kerby-kdc:latest
20+
container_name: kerby-kdc
21+
ports:
22+
- "88:88/tcp"
23+
- "88:88/udp"
24+
environment:
25+
KERBY_REALM: EXAMPLE.COM
26+
KERBY_KDC_HOST: kerby-kdc
27+
KERBY_KDC_BIND_HOST: 0.0.0.0
28+
KERBY_KDC_TCP_PORT: "88"
29+
KERBY_KDC_UDP_PORT: "88"
30+
KERBY_CLIENT_KDC_HOST: kerby-kdc
31+
KERBY_CLIENT_KDC_PORT: "88"
32+
KERBY_CLIENT_DOMAIN: example.com
33+
# KERBY_PREAUTH_REQUIRED: "true"
34+
# KERBY_PA_ENC_TIMESTAMP_REQUIRED: "true"
35+
36+
KERBY_CLIENT_PRINCIPAL: app_user@EXAMPLE.COM
37+
KERBY_CLIENT_PASSWORD: app-user-secret
38+
39+
KERBY_SERVICE_PRINCIPAL: HTTP/api.example.com@EXAMPLE.COM
40+
KERBY_SERVICE_KEYTAB: /var/lib/kerby/keytabs/http-api.keytab
41+
42+
KERBY_EXTRA_PRINCIPALS: >-
43+
alice@EXAMPLE.COM:alice-secret,
44+
bob@EXAMPLE.COM:bob-secret
45+
46+
KERBY_EXTRA_SERVICE_PRINCIPALS: >-
47+
hive/hiveserver2.example.com@EXAMPLE.COM:/var/lib/kerby/keytabs/hive.keytab,
48+
kafka/broker1.example.com@EXAMPLE.COM:/var/lib/kerby/keytabs/kafka.keytab
49+
volumes:
50+
- kerby-data:/var/lib/kerby
51+
- ./log4j.properties:/opt/kerby/log4j.properties:ro
52+
53+
kerberos-client:
54+
image: ghcr.io/openprojectx/kerberos:latest
55+
container_name: kerberos-client
56+
depends_on:
57+
- kerby-kdc
58+
entrypoint: ["/bin/sh", "-c"]
59+
command: ["sleep infinity"]
60+
environment:
61+
KRB5_CONFIG: /kerby/client/krb5.conf
62+
KRB5_TRACE: /dev/stderr
63+
volumes:
64+
- kerby-data:/kerby:ro
65+
66+
volumes:
67+
kerby-data:

kerby-dist/docker/log4j.properties

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
log4j.rootLogger=DEBUG,STDOUT
2+
3+
log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
4+
log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
5+
log4j.appender.STDOUT.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %5p %c - %m%n

0 commit comments

Comments
 (0)