Enhance Dockerfile and entrypoint script for Kerberos initialization
- Added krb5-admin-server and updated entrypoint to ensure proper initialization of the Kerberos realm. - Improved error handling for required environment variables in entrypoint script. - Updated README with additional prerequisites and client configuration instructions. - Modified env.example to remove default passwords for security. - Enhanced run-container script to set container hostname based on KDC_HOST.
This commit is contained in:
+3
-2
@@ -4,7 +4,8 @@ RUN apt-get update && \
|
|||||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
krb5-kdc \
|
krb5-kdc \
|
||||||
krb5-admin-server \
|
krb5-admin-server \
|
||||||
krb5-config && \
|
krb5-config \
|
||||||
|
tini && \
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
COPY entrypoint.sh /entrypoint
|
COPY entrypoint.sh /entrypoint
|
||||||
@@ -13,4 +14,4 @@ RUN chmod +x /entrypoint
|
|||||||
|
|
||||||
EXPOSE 88/tcp 88/udp 464/tcp 464/udp 749/tcp
|
EXPOSE 88/tcp 88/udp 464/tcp 464/udp 749/tcp
|
||||||
|
|
||||||
ENTRYPOINT ["/entrypoint"]
|
ENTRYPOINT ["tini", "--", "/entrypoint"]
|
||||||
|
|||||||
@@ -2,19 +2,31 @@
|
|||||||
|
|
||||||
MIT Kerberos V KDC + admin server container running on Ubuntu 26.04.
|
MIT Kerberos V KDC + admin server container running on Ubuntu 26.04.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
Kerberos is sensitive to hostname resolution. Before running this container:
|
||||||
|
|
||||||
|
- `KRB5_KDC_HOST` must resolve to the container from every client machine (forward DNS or `/etc/hosts`).
|
||||||
|
- The container's own hostname should match `KRB5_KDC_HOST` so that service tickets are issued for the correct principal. Set it with `--hostname` / the container runtime's hostname option.
|
||||||
|
- Reverse DNS (PTR records) for the KDC host is strongly recommended — some Kerberos operations fail without it.
|
||||||
|
|
||||||
|
DNS lookup of KDC addresses is disabled in the generated `krb5.conf` (`dns_lookup_kdc = false`); the value of `KRB5_KDC_HOST` is used directly instead.
|
||||||
|
|
||||||
## Environment variables
|
## Environment variables
|
||||||
|
|
||||||
| Variable | Default | Description |
|
| Variable | Default | Description |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `KRB5_REALM` | `EXAMPLE.ORG` | Kerberos realm (uppercase) |
|
| `KRB5_REALM` | `EXAMPLE.ORG` | Kerberos realm (uppercase) |
|
||||||
| `KRB5_DOMAIN` | `example.org` | DNS domain mapped to the realm |
|
| `KRB5_DOMAIN` | `example.org` | DNS domain mapped to the realm |
|
||||||
| `KRB5_KDC_HOST` | `localhost` | Hostname clients use to reach this KDC |
|
| `KRB5_KDC_HOST` | *(required)* | FQDN of this KDC, used by clients and in service ticket names |
|
||||||
| `KRB5_MASTER_PASSWORD` | `changeit` | Database master key (set once, never changes) |
|
| `KRB5_MASTER_PASSWORD` | *(required on first start)* | Database master key — set once, cannot be changed without destroying the database |
|
||||||
| `KRB5_ADMIN_PRINCIPAL` | `admin` | Name of the bootstrap admin principal |
|
| `KRB5_ADMIN_PRINCIPAL` | `admin` | Name of the bootstrap admin principal |
|
||||||
| `KRB5_ADMIN_PASSWORD` | `changeit` | Password for `<admin>/admin@<REALM>` |
|
| `KRB5_ADMIN_PASSWORD` | *(required on first start)* | Password for `<admin>/admin@<REALM>` |
|
||||||
|
|
||||||
Copy `env.example` to `~/app-data/kerberos/kerberos.env` and fill in real values before first run.
|
Copy `env.example` to `~/app-data/kerberos/kerberos.env` and fill in real values before first run.
|
||||||
|
|
||||||
|
> **Important:** `KRB5_MASTER_PASSWORD` and `KRB5_ADMIN_PASSWORD` are only required on first start. Once the realm is initialised (the database file exists in the volume), these variables are not read and can be removed from the env file for enhanced security. The master password cannot be changed without wiping the `kerberos_data` volume and reinitialising the realm, which invalidates all issued tickets and keytabs.
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -27,25 +39,118 @@ Copy `env.example` to `~/app-data/kerberos/kerberos.env` and fill in real values
|
|||||||
./scripts/run-container.sh
|
./scripts/run-container.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
The realm database is persisted in the `kerberos_data` volume (`/var/lib/krb5kdc`). Realm initialization runs only on first start.
|
The `kerberos_data` volume (`/var/lib/krb5kdc`) holds the realm database, configuration, and keytab. All files are written once on first start. On subsequent starts the container requires no environment variables — the persisted configuration is used as-is. Sensitive variables (`KRB5_MASTER_PASSWORD`, `KRB5_ADMIN_PASSWORD`) can be removed from the env file after the realm is initialised.
|
||||||
|
|
||||||
## Ports
|
## Ports
|
||||||
|
|
||||||
| Port | Protocol | Service |
|
| Port | Protocol | Service |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| 88 | TCP/UDP | KDC |
|
| 88 | TCP/UDP | KDC (ticket granting) |
|
||||||
| 464 | TCP/UDP | kpasswd |
|
| 464 | TCP/UDP | kpasswd (password changes) |
|
||||||
| 749 | TCP | kadmin |
|
| 749 | TCP | kadmin (remote administration) |
|
||||||
|
|
||||||
|
## Client configuration
|
||||||
|
|
||||||
|
Pre-authentication is required (`+preauth` is set by default), so clients must supply a password or keytab — anonymous TGT requests are rejected.
|
||||||
|
|
||||||
|
The KDC hostname (`KRB5_KDC_HOST`) must be resolvable from every client machine via DNS or a local hosts file entry.
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
|
||||||
|
Install the MIT Kerberos client tools:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt install krb5-user # Debian / Ubuntu
|
||||||
|
sudo dnf install krb5-workstation # Fedora / RHEL
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `/etc/krb5.conf`:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[libdefaults]
|
||||||
|
default_realm = EXAMPLE.ORG
|
||||||
|
|
||||||
|
[realms]
|
||||||
|
EXAMPLE.ORG = {
|
||||||
|
kdc = kerberos.example.org
|
||||||
|
admin_server = kerberos.example.org
|
||||||
|
}
|
||||||
|
|
||||||
|
[domain_realm]
|
||||||
|
.example.org = EXAMPLE.ORG
|
||||||
|
example.org = EXAMPLE.ORG
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kinit user@EXAMPLE.ORG # obtain a ticket
|
||||||
|
klist # verify
|
||||||
|
kdestroy # release
|
||||||
|
```
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
|
||||||
|
Kerberos (Heimdal) is built into macOS — no installation required. It is interoperable with MIT KDCs.
|
||||||
|
|
||||||
|
Create `/etc/krb5.conf` with the same content as the Linux example above.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kinit user@EXAMPLE.ORG
|
||||||
|
klist
|
||||||
|
kdestroy
|
||||||
|
```
|
||||||
|
|
||||||
|
Acquired tickets are also visible in **Ticket Viewer** (`/System/Library/CoreServices/Ticket Viewer.app`).
|
||||||
|
|
||||||
|
For SSH with GSSAPI, add to `~/.ssh/config`:
|
||||||
|
|
||||||
|
```
|
||||||
|
Host *.example.org
|
||||||
|
GSSAPIAuthentication yes
|
||||||
|
GSSAPIDelegateCredentials yes
|
||||||
|
```
|
||||||
|
|
||||||
|
### Windows (standalone, not domain-joined)
|
||||||
|
|
||||||
|
Install **MIT Kerberos for Windows** (KfW) from [web.mit.edu/kerberos/dist](https://web.mit.edu/kerberos/dist/). The built-in Windows Kerberos provider (SSPI) is designed for Active Directory domain membership and is not suitable for standalone use against a custom KDC.
|
||||||
|
|
||||||
|
Create the configuration file at `%ProgramData%\MIT\Kerberos5\krb5.ini` (system-wide) or set the `KRB5_CONFIG` environment variable to point to a file of your choice:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[libdefaults]
|
||||||
|
default_realm = EXAMPLE.ORG
|
||||||
|
|
||||||
|
[realms]
|
||||||
|
EXAMPLE.ORG = {
|
||||||
|
kdc = kerberos.example.org
|
||||||
|
admin_server = kerberos.example.org
|
||||||
|
}
|
||||||
|
|
||||||
|
[domain_realm]
|
||||||
|
.example.org = EXAMPLE.ORG
|
||||||
|
example.org = EXAMPLE.ORG
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the KfW **Network Identity Manager** GUI or the bundled command-line tools from a Command Prompt:
|
||||||
|
|
||||||
|
```cmd
|
||||||
|
kinit user@EXAMPLE.ORG
|
||||||
|
klist
|
||||||
|
kdestroy
|
||||||
|
```
|
||||||
|
|
||||||
## Managing principals
|
## Managing principals
|
||||||
|
|
||||||
Exec into the container and use `kadmin.local` (no password needed):
|
Exec into the running container, then use `kadmin.local` (no password required):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
container exec -it kerberos bash
|
||||||
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# List all principals
|
# List all principals
|
||||||
kadmin.local -q "listprincs"
|
kadmin.local -q "listprincs"
|
||||||
|
|
||||||
# Add a principal
|
# Add a user principal
|
||||||
kadmin.local -q "addprinc username@REALM"
|
kadmin.local -q "addprinc username@REALM"
|
||||||
|
|
||||||
# Add a service principal and extract a keytab
|
# Add a service principal and extract a keytab
|
||||||
|
|||||||
+30
-16
@@ -2,14 +2,15 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
REALM="${KRB5_REALM:-EXAMPLE.ORG}"
|
if [ ! -f /var/lib/krb5kdc/principal ]; then
|
||||||
DOMAIN="${KRB5_DOMAIN:-example.org}"
|
REALM="${KRB5_REALM:?KRB5_REALM must be set for first-time initialisation}"
|
||||||
KDC_HOST="${KRB5_KDC_HOST:-localhost}"
|
DOMAIN="${KRB5_DOMAIN:?KRB5_DOMAIN must be set for first-time initialisation}"
|
||||||
MASTER_PASSWORD="${KRB5_MASTER_PASSWORD:-changeit}"
|
KDC_HOST="${KRB5_KDC_HOST:?KRB5_KDC_HOST must be set to the FQDN of this KDC}"
|
||||||
|
MASTER_PASSWORD="${KRB5_MASTER_PASSWORD:?KRB5_MASTER_PASSWORD must be set for first-time initialisation}"
|
||||||
ADMIN_PRINCIPAL="${KRB5_ADMIN_PRINCIPAL:-admin}"
|
ADMIN_PRINCIPAL="${KRB5_ADMIN_PRINCIPAL:-admin}"
|
||||||
ADMIN_PASSWORD="${KRB5_ADMIN_PASSWORD:-changeit}"
|
ADMIN_PASSWORD="${KRB5_ADMIN_PASSWORD:?KRB5_ADMIN_PASSWORD must be set for first-time initialisation}"
|
||||||
|
|
||||||
cat > /etc/krb5.conf <<EOF
|
cat > /var/lib/krb5kdc/krb5.conf <<EOF
|
||||||
[libdefaults]
|
[libdefaults]
|
||||||
default_realm = ${REALM}
|
default_realm = ${REALM}
|
||||||
dns_lookup_realm = false
|
dns_lookup_realm = false
|
||||||
@@ -26,34 +27,47 @@ cat > /etc/krb5.conf <<EOF
|
|||||||
${DOMAIN} = ${REALM}
|
${DOMAIN} = ${REALM}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cat > /etc/krb5kdc/kdc.conf <<EOF
|
cat > /var/lib/krb5kdc/kdc.conf <<EOF
|
||||||
[kdcdefaults]
|
[kdcdefaults]
|
||||||
kdc_ports = 88
|
kdc_ports = 88
|
||||||
|
|
||||||
[realms]
|
[realms]
|
||||||
${REALM} = {
|
${REALM} = {
|
||||||
database_name = /var/lib/krb5kdc/principal
|
database_name = /var/lib/krb5kdc/principal
|
||||||
admin_keytab = FILE:/etc/krb5kdc/kadm5.keytab
|
admin_keytab = FILE:/var/lib/krb5kdc/kadm5.keytab
|
||||||
acl_file = /etc/krb5kdc/kadm5.acl
|
acl_file = /var/lib/krb5kdc/kadm5.acl
|
||||||
key_stash_file = /etc/krb5kdc/.k5.${REALM}
|
key_stash_file = /var/lib/krb5kdc/stash
|
||||||
kdc_ports = 88
|
kdc_ports = 88
|
||||||
max_life = 10h 0m 0s
|
max_life = 10h 0m 0s
|
||||||
max_renewable_life = 7d 0h 0m 0s
|
max_renewable_life = 7d 0h 0m 0s
|
||||||
master_key_type = aes256-cts
|
master_key_type = aes256-cts-hmac-sha1-96
|
||||||
supported_enctypes = aes256-cts:normal aes128-cts:normal
|
supported_enctypes = aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal
|
||||||
|
default_principal_flags = +preauth
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cat > /etc/krb5kdc/kadm5.acl <<EOF
|
cat > /var/lib/krb5kdc/kadm5.acl <<EOF
|
||||||
${ADMIN_PRINCIPAL}/admin@${REALM} *
|
${ADMIN_PRINCIPAL}/admin@${REALM} *
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
if [ ! -f /var/lib/krb5kdc/principal ]; then
|
cp /var/lib/krb5kdc/krb5.conf /etc/krb5.conf
|
||||||
|
|
||||||
echo "Initializing Kerberos realm ${REALM}..."
|
echo "Initializing Kerberos realm ${REALM}..."
|
||||||
kdb5_util create -s -P "${MASTER_PASSWORD}" -r "${REALM}"
|
KRB5_KDC_PROFILE=/var/lib/krb5kdc/kdc.conf kdb5_util create -s -P "${MASTER_PASSWORD}" -r "${REALM}"
|
||||||
kadmin.local -q "addprinc -pw ${ADMIN_PASSWORD} ${ADMIN_PRINCIPAL}/admin@${REALM}"
|
KRB5_KDC_PROFILE=/var/lib/krb5kdc/kdc.conf kadmin.local -q "addprinc -pw ${ADMIN_PASSWORD} ${ADMIN_PRINCIPAL}/admin@${REALM}"
|
||||||
echo "Realm initialized."
|
echo "Realm initialized."
|
||||||
|
else
|
||||||
|
echo "Realm already initialized, skipping."
|
||||||
|
cp /var/lib/krb5kdc/krb5.conf /etc/krb5.conf
|
||||||
|
|
||||||
|
CONFIGURED_HOST=$(grep -E '^\s+kdc\s*=' /var/lib/krb5kdc/krb5.conf | head -1 | cut -d= -f2- | tr -d ' ')
|
||||||
|
if [ "$(hostname)" != "${CONFIGURED_HOST}" ]; then
|
||||||
|
echo "Error: container hostname '$(hostname)' does not match configured KDC host '${CONFIGURED_HOST}'" >&2
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
export KRB5_KDC_PROFILE=/var/lib/krb5kdc/kdc.conf
|
||||||
|
|
||||||
krb5kdc -n &
|
krb5kdc -n &
|
||||||
KDC_PID=$!
|
KDC_PID=$!
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
KRB5_REALM=EXAMPLE.ORG
|
KRB5_REALM=EXAMPLE.ORG
|
||||||
KRB5_DOMAIN=example.org
|
KRB5_DOMAIN=example.org
|
||||||
KRB5_KDC_HOST=kerberos.example.org
|
KRB5_KDC_HOST=kerberos.example.org
|
||||||
KRB5_MASTER_PASSWORD=changeit
|
KRB5_MASTER_PASSWORD=
|
||||||
KRB5_ADMIN_PRINCIPAL=admin
|
KRB5_ADMIN_PRINCIPAL=admin
|
||||||
KRB5_ADMIN_PASSWORD=changeit
|
KRB5_ADMIN_PASSWORD=
|
||||||
|
|||||||
@@ -3,8 +3,16 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
if command -v container >/dev/null 2>&1; then
|
if command -v container >/dev/null 2>&1; then
|
||||||
|
ENV_FILE=~/app-data/kerberos/kerberos.env
|
||||||
|
KDC_HOST=$(grep -E '^KRB5_KDC_HOST=' "${ENV_FILE}" | cut -d= -f2-)
|
||||||
|
if [ -z "${KDC_HOST}" ]; then
|
||||||
|
echo "Error: KRB5_KDC_HOST is not set in ${ENV_FILE}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
container run -d --name kerberos \
|
container run -d --name kerberos \
|
||||||
--env-file ~/app-data/kerberos/kerberos.env \
|
--hostname "${KDC_HOST}" \
|
||||||
|
--env-file "${ENV_FILE}" \
|
||||||
-v kerberos_data:/var/lib/krb5kdc \
|
-v kerberos_data:/var/lib/krb5kdc \
|
||||||
-p 88:88/tcp -p 88:88/udp \
|
-p 88:88/tcp -p 88:88/udp \
|
||||||
-p 464:464/tcp -p 464:464/udp \
|
-p 464:464/tcp -p 464:464/udp \
|
||||||
|
|||||||
Reference in New Issue
Block a user