Added GSSAPI Authentication.
This commit is contained in:
@@ -5,6 +5,7 @@ RUN apt-get update && \
|
|||||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
slapd \
|
slapd \
|
||||||
ldap-utils \
|
ldap-utils \
|
||||||
|
libsasl2-modules-gssapi-mit \
|
||||||
python3-jinja2 \
|
python3-jinja2 \
|
||||||
python3-ldap3 && \
|
python3-ldap3 && \
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|||||||
@@ -210,3 +210,61 @@ ldapsearch -x -H ldap://localhost \
|
|||||||
ldapwhoami -x -H ldap://localhost \
|
ldapwhoami -x -H ldap://localhost \
|
||||||
-D "cn=readonly,ou=service-accounts,dc=koszewscy,dc=waw,dc=pl" -W
|
-D "cn=readonly,ou=service-accounts,dc=koszewscy,dc=waw,dc=pl" -W
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Kerberos SASL/GSSAPI
|
||||||
|
|
||||||
|
Gate with `KERBEROS_ENABLE=1`. When enabled, slapd is configured at first-run bootstrap with SASL GSSAPI and two authz-regexp rules that map Kerberos principals to LDAP DNs.
|
||||||
|
|
||||||
|
### Environment variables
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| `KERBEROS_ENABLE` | `0` | Set to `1` to enable |
|
||||||
|
| `KRB5_REALM` | — | Kerberos realm (uppercase, e.g. `EXAMPLE.ORG`) |
|
||||||
|
| `KRB5_SASL_HOST` | — | Hostname matching the `ldap/<host>@REALM` service principal |
|
||||||
|
| `KRB5_KTNAME` | `/etc/ldap/ldap.keytab` | Path to the keytab inside the container |
|
||||||
|
|
||||||
|
### Principal-to-DN mapping
|
||||||
|
|
||||||
|
| Kerberos principal | LDAP DN |
|
||||||
|
|---|---|
|
||||||
|
| `*/admin@REALM` | `cn=admin,<base_dn>` |
|
||||||
|
| `username@REALM` | `uid=username,ou=users,<base_dn>` |
|
||||||
|
|
||||||
|
### Setup steps
|
||||||
|
|
||||||
|
1. In the Kerberos container, create the service principal and extract a keytab:
|
||||||
|
```bash
|
||||||
|
kadmin.local -q "addprinc -randkey ldap/ldap.example.org@REALM"
|
||||||
|
kadmin.local -q "ktadd -k /tmp/ldap.keytab ldap/ldap.example.org@REALM"
|
||||||
|
```
|
||||||
|
2. Copy the keytab to the OpenLDAP host:
|
||||||
|
```bash
|
||||||
|
container cp kerberos:/tmp/ldap.keytab ~/app-data/openldap/ldap.keytab
|
||||||
|
```
|
||||||
|
3. Mount it into the OpenLDAP container at `KRB5_KTNAME` (default `/etc/ldap/ldap.keytab`) and set the Kerberos env vars in `openldap.env`.
|
||||||
|
4. On first start, bootstrap applies the SASL configuration automatically. For an already-initialised instance apply it manually:
|
||||||
|
```bash
|
||||||
|
ldapmodify -Q -Y EXTERNAL -H ldapi:/// <<'EOF'
|
||||||
|
dn: cn=config
|
||||||
|
changetype: modify
|
||||||
|
replace: olcSaslHost
|
||||||
|
olcSaslHost: ldap.example.org
|
||||||
|
-
|
||||||
|
replace: olcSaslRealm
|
||||||
|
olcSaslRealm: EXAMPLE.ORG
|
||||||
|
-
|
||||||
|
replace: olcAuthzRegexp
|
||||||
|
olcAuthzRegexp: {0}uid=([^/]+)/admin,cn=example.org,cn=gssapi,cn=auth cn=admin,dc=example,dc=org
|
||||||
|
olcAuthzRegexp: {1}uid=([^,]+),cn=example.org,cn=gssapi,cn=auth uid=$1,ou=users,dc=example,dc=org
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test authentication
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kinit username@REALM
|
||||||
|
ldapwhoami -Y GSSAPI -H ldap://ldap.example.org
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: `dn:uid=username,ou=users,dc=example,dc=org`
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ SLAPD_D = Path("/etc/ldap/slapd.d")
|
|||||||
base_dn = os.environ.get("LDAP_BASE_DN") or "dc=example,dc=org"
|
base_dn = os.environ.get("LDAP_BASE_DN") or "dc=example,dc=org"
|
||||||
password = os.environ.get("LDAP_PASSWORD") or "changeit"
|
password = os.environ.get("LDAP_PASSWORD") or "changeit"
|
||||||
tls_enabled = os.environ.get("TLS_ENABLED") == "1"
|
tls_enabled = os.environ.get("TLS_ENABLED") == "1"
|
||||||
|
kerberos_enabled = os.environ.get("KERBEROS_ENABLE") == "1"
|
||||||
|
krb5_realm = os.environ.get("KRB5_REALM", "")
|
||||||
|
krb5_sasl_host = os.environ.get("KRB5_SASL_HOST", "")
|
||||||
admin_dn = f"cn=admin,{base_dn}"
|
admin_dn = f"cn=admin,{base_dn}"
|
||||||
|
|
||||||
|
|
||||||
@@ -116,6 +119,9 @@ def main():
|
|||||||
apply_ldif(LDIF_DIR / "config-acl.ldif", env, base_dn=base_dn, admin_dn=admin_dn)
|
apply_ldif(LDIF_DIR / "config-acl.ldif", env, base_dn=base_dn, admin_dn=admin_dn)
|
||||||
if tls_enabled:
|
if tls_enabled:
|
||||||
apply_ldif(LDIF_DIR / "config-tls.ldif", env)
|
apply_ldif(LDIF_DIR / "config-tls.ldif", env)
|
||||||
|
if kerberos_enabled:
|
||||||
|
apply_ldif(LDIF_DIR / "config-sasl.ldif", env,
|
||||||
|
base_dn=base_dn, krb5_realm=krb5_realm, sasl_host=krb5_sasl_host)
|
||||||
|
|
||||||
print("cn=config updated.")
|
print("cn=config updated.")
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
dn: cn=config
|
||||||
|
changetype: modify
|
||||||
|
replace: olcSaslHost
|
||||||
|
olcSaslHost: {{ sasl_host }}
|
||||||
|
-
|
||||||
|
replace: olcSaslRealm
|
||||||
|
olcSaslRealm: {{ krb5_realm }}
|
||||||
|
-
|
||||||
|
replace: olcAuthzRegexp
|
||||||
|
olcAuthzRegexp: {0}uid=([^/]+)/admin,cn={{ krb5_realm | lower }},cn=gssapi,cn=auth cn=admin,{{ base_dn }}
|
||||||
|
olcAuthzRegexp: {1}uid=([^,]+),cn={{ krb5_realm | lower }},cn=gssapi,cn=auth uid=$1,ou=users,{{ base_dn }}
|
||||||
@@ -31,6 +31,15 @@ else
|
|||||||
echo "TLS : disabled"
|
echo "TLS : disabled"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
kerberos_enabled="0"
|
||||||
|
if [ "${KERBEROS_ENABLE:-0}" = "1" ]; then
|
||||||
|
kerberos_enabled="1"
|
||||||
|
export KRB5_KTNAME="${KRB5_KTNAME:-/etc/ldap/ldap.keytab}"
|
||||||
|
echo "Kerberos : enabled (keytab: $KRB5_KTNAME)"
|
||||||
|
else
|
||||||
|
echo "Kerberos : disabled"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Ensuring slapd runtime directory..."
|
echo "Ensuring slapd runtime directory..."
|
||||||
mkdir -p /var/run/slapd
|
mkdir -p /var/run/slapd
|
||||||
chown openldap:openldap /var/run/slapd
|
chown openldap:openldap /var/run/slapd
|
||||||
@@ -59,6 +68,7 @@ EOF
|
|||||||
LDAP_BASE_DN="$base_dn" \
|
LDAP_BASE_DN="$base_dn" \
|
||||||
LDAP_PASSWORD="$password" \
|
LDAP_PASSWORD="$password" \
|
||||||
TLS_ENABLED="$tls_enabled" \
|
TLS_ENABLED="$tls_enabled" \
|
||||||
|
KERBEROS_ENABLE="$kerberos_enabled" \
|
||||||
python3 -u /bootstrap/init.py
|
python3 -u /bootstrap/init.py
|
||||||
else
|
else
|
||||||
echo "Already initialised - skipping bootstrap."
|
echo "Already initialised - skipping bootstrap."
|
||||||
|
|||||||
@@ -3,3 +3,9 @@ LDAP_BASE_DN=dc=example,dc=org
|
|||||||
LDAP_ORG=Example Organization
|
LDAP_ORG=Example Organization
|
||||||
LDAP_PASSWORD=changeit
|
LDAP_PASSWORD=changeit
|
||||||
LDAP_ADMIN_PASSWORD=changeit
|
LDAP_ADMIN_PASSWORD=changeit
|
||||||
|
|
||||||
|
# Kerberos SASL/GSSAPI (optional)
|
||||||
|
KERBEROS_ENABLE=0
|
||||||
|
KRB5_REALM=EXAMPLE.ORG
|
||||||
|
KRB5_SASL_HOST=ldap.example.org
|
||||||
|
KRB5_KTNAME=/etc/ldap/ldap.keytab
|
||||||
|
|||||||
Reference in New Issue
Block a user