Commit c3a356a9 authored by nimrod's avatar nimrod
Browse files

Major overhaul of the slapd (OpenLDAP) image.

- Use a single volume for the config and data LDAP directories, easier
to keep in sync in different cases (backups, migration).
- Add backup script, save to backup volume.
- Allow passing the location of the SSL key and cert to enable SSL,
otherwise a self-signed certificate and key are generated with the FQDN
of the container.
- Drop the dockerfile-lint linter, didn't give any useful advice.
- Change base image to Debian Buster.
- Set stopsignal for the container.
- Allow setting the log level.
- Unset the cleartext root password environment variable.
parent c65101a4
Loading
Loading
Loading
Loading
+18 −8
Original line number Diff line number Diff line
@@ -5,13 +5,17 @@ services:
  ldap:
    build:
      context: slapd/
    volumes:
      - _run_ldap:/run/slapd
      - ldap:/var/lib/ldap
    domainname: "${LDAP_HOSTNAME:-ldap}.${LDAP_DOMAIN:-nowhere.com}"
    environment:
      LDAP_ROOTPASS: "${LDAP_ROOTPASS:-foo}"
      LDAP_DOMAIN: "${LDAP_DOMAIN:-nowhere.com}"
      LDAP_ORGANIZATION: "${LDAP_ORGANIZATION:-none}"
    hostname: "${LDAP_HOSTNAME:-ldap}"
    restart: always
    volumes:
      - _run_slapd:/run/slapd
      - ldap:/var/lib/ldap
      - backup_ldap:/var/backups/ldap

  nss-pam-ldapd:
    build:
@@ -20,23 +24,29 @@ services:
    environment:
      LDAP_BASE_DN: "${LDAP_BASE_DN:-dc=nowhere,dc=com}"
    volumes:
      - _run_ldap:/run/slapd
      - _run_slapd:/run/slapd

  ldap-account-manager:
    build:
      context: ldap-account-manager/
    links:
      - ldap
    volumes:
      - _run_ldap:/run/slapd
      - ldap-account-manager:/var/lib/ldap-account-manager
    ports:
      - 80:80
    restart: always
    volumes:
      - _run_slapd:/run/slapd
      - ldap-account-manager:/var/lib/ldap-account-manager

volumes:
  _run_ldap:
  _run_slapd:
  ldap:
  ldap-account-manager:
    labels:
      snapshot: 'true'
  backup_ldap:
    labels:
      snapshot: 'true'

networks:
  default:
+27 −14
Original line number Diff line number Diff line
FROM debian:stretch-slim
RUN echo 'deb http://deb.debian.org/debian stretch-backports main' > /etc/apt/sources.list.d/backports.list && \
    apt-get update && \
FROM debian:buster-slim
# hadolint ignore=DL3008
RUN apt-get update && \
    DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
        gnutls-bin=3.5.8-5+deb9u4 \
        ldap-utils=2.4.44+dfsg-5+deb9u2 \
        slapd=2.4.44+dfsg-5+deb9u2 \
        gettext-base \
        gnutls-bin \
        ldap-utils \
        slapd \
        ssl-cert \
        time \
    && \
    mkdir -p /run/slapd && \
    rm -rf /tmp/* /var/tmp/* /var/lib/apt/lists/* /var/cache/apt/archives/*
COPY --chown=root:root entrypoint /
    usermod -aG ssl-cert openldap && \
    rm -rf /tmp/* /var/tmp/* /var/cache/apt/archives/* /var/lib/apt/lists/* && \
    rm -rf /etc/ssl/certs/ssl-cert-snakeoil.pem /etc/ssl/private/ssl-cert-snakeoil.key && \
    rm -rf /var/lib/ldap/* /var/backups/ldap/* /run/slapd/* /etc/ldap/slapd.d
COPY --chown=root:root config.ldif /usr/share/slapd/
COPY --chown=root:root skel.ldif /usr/share/slapd/
COPY --chown=root:root entrypoint /usr/local/sbin/
COPY --chown=root:root backup /usr/local/sbin/
EXPOSE 389 636
VOLUME [ "/var/lib/ldap" ]
VOLUME [ "/run/ldap" ]
VOLUME [ "/run/slapd" ]
VOLUME [ "/var/backups/ldap" ]
ENV LDAP_URLS="ldap:/// ldapi:/// ldaps:///" \
    SLAPD_DEBUG_LEVEL="NONE"
ENTRYPOINT [ "/entrypoint" ]
CMD [ "slapd", "-F", "/etc/ldap/slapd.d", "-u", "openldap", "-g", "openldap", "-h", "\"$LDAP_URLS\"", "-d", "$SLAPD_DEBUG_LEVEL" ]
HEALTHCHECK CMD ldapsearch -b cn=config -H ldapi:/// > /dev/null || exit 1
    SLAPD_DEBUG_LEVEL="stats,stats2,none" \
    SSL_CERT_FILE="/etc/ssl/certs/ssl-cert-snakeoil.pem" \
    SSL_KEY_FILE="/etc/ssl/private/ssl-cert-snakeoil.key" \
    SSL_CA_FILE="/etc/ssl/certs/ssl-cert-snakeoil.pem"
ENTRYPOINT [ "entrypoint" ]
CMD [ "slapd", "-F", "/var/lib/ldap/config", "-u", "openldap", "-g", "openldap", "-h", "\"$LDAP_URLS\"", "-d", "$SLAPD_DEBUG_LEVEL" ]
HEALTHCHECK CMD ldapsearch -b cn=config > /dev/null || exit 1
STOPSIGNAL INT
+18 −1
Original line number Diff line number Diff line
@@ -15,10 +15,27 @@ Name | Description | Default value
`LDAP_ROOTPASS` | Root password.
`LDAP_DOMAIN` | Domain.
`LDAP_ORGANIZATION` | Organization.
`SLAPD_DEBUG_LEVEL` | The `slapd` debug/ log level.
`SSL_CERT_FILE` | Location of the SSL certificate file.
`SSL_KEY_FILE` | Location of the SSL key file.
`SSL_CA_FILE` | Location of the SSL certificate authority file.

## SSL

If the relevant environment variables aren't changed from their default values,
on startup the container will generate a key and self-signed certificate with
the FQDN of the container. If the location of the SSL key and certificate are
provided, those are used instead.

## Persistence

The database is at `/var/lib/ldap`.
The configuration (`cn=config`) and data LDAP directories reside in the
`config` and `data` diretories respectively in the `/var/lib/ldap` volume.
The LDAP directories are generated only if they're missing. Changes to
environment variables afterwards won't change the configuration, since that is
persisted to a volume. There's also the `/var/backups/ldap` volume where the
`backup` script saves snapshots of the LDAP directories (config directory
included).

## License

slapd/backup

0 → 100755
+9 −0
Original line number Diff line number Diff line
#!/bin/sh
set -eux

slapcat -n0 -v -l /var/backups/ldap/config.ldif

for dn in $(ldapsearch -Y EXTERNAL -LLL -s base -b '' o namingContexts | sed -n '/namingContexts/ s/namingContexts: //gp')
do
    slapcat -b "$dn" -v -l "/var/backups/$dn.ldif"
done

slapd/config.ldif

0 → 100644
+108 −0
Original line number Diff line number Diff line
# Global config:
dn: cn=config
objectClass: olcGlobal
cn: config
# Where the pid file is put. The init.d script
# will not stop the server if you change this.
olcPidFile: /var/run/slapd/slapd.pid
# List of arguments that were passed to the server
olcArgsFile: /var/run/slapd/slapd.args
# Read slapd-config(5) for possible values
olcLogLevel: none
# The tool-threads parameter sets the actual amount of cpu's that is used
# for indexing.
olcToolThreads: 1
# TLS options.
olcTLSCACertificateFile: ${SSL_CA_FILE}
olcTLSCertificateFile: ${SSL_CERT_FILE}
olcTLSCertificateKeyFile: ${SSL_KEY_FILE}
olcTLSCipherSuite: SECURE256:+SECURE128
olcTLSProtocolMin: 3.1
olcTLSDHParamFile: /usr/share/slapd/dh.pem

# Frontend settings
dn: olcDatabase={-1}frontend,cn=config
objectClass: olcDatabaseConfig
objectClass: olcFrontendConfig
olcDatabase: {-1}frontend
# The maximum number of entries that is returned for a search operation
olcSizeLimit: 500
# Allow unlimited access to local connection from the local root user
olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break
# Allow unauthenticated read access for schema and base DN autodiscovery
olcAccess: {1}to dn.exact="" by * read
olcAccess: {2}to dn.base="cn=Subschema" by * read

# Config db settings
dn: olcDatabase=config,cn=config
objectClass: olcDatabaseConfig
olcDatabase: config
# Allow unlimited access to local connection from the local root user
olcAccess: to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break
olcRootDN: cn=admin,cn=config

# Load schemas
dn: cn=schema,cn=config
objectClass: olcSchemaConfig
cn: schema

include: file:///etc/ldap/schema/core.ldif
include: file:///etc/ldap/schema/cosine.ldif
include: file:///etc/ldap/schema/nis.ldif
include: file:///etc/ldap/schema/inetorgperson.ldif

# Load module
dn: cn=module{0},cn=config
objectClass: olcModuleList
cn: module{0}
# Where the dynamically loaded modules are stored
olcModulePath: /usr/lib/ldap
olcModuleLoad: back_mdb

# Set defaults for the backend
dn: olcBackend=mdb,cn=config
objectClass: olcBackendConfig
olcBackend: mdb

# The database definition.
dn: olcDatabase=mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: mdb
# Checkpoint the database periodically in case of system
# failure and to speed slapd shutdown.
olcDbCheckpoint: 512 30
olcDbMaxSize: 1073741824
# Save the time that the entry gets modified, for database #1
olcLastMod: TRUE
# The base of your directory in database #1
olcSuffix: ${BASE_DN}
# Where the database file are physically stored for database #1
olcDbDirectory: /var/lib/ldap/data
# olcRootDN directive for specifying a superuser on the database. This
# is needed for syncrepl.
olcRootDN: cn=admin,${BASE_DN}
olcRootPW: ${PASSWORD_HASH}
# Indexing options for database #1
olcDbIndex: objectClass eq
olcDbIndex: cn,uid eq
olcDbIndex: uidNumber,gidNumber eq
olcDbIndex: member,memberUid eq
# The userPassword by default can be changed by the entry owning it if
# they are authenticated. Others should not be able to see it, except
# the admin entry above.
olcAccess: to attrs=userPassword
  by self write
  by anonymous auth
  by * none
# Allow update of authenticated user's shadowLastChange attribute.
# Updating it on password change is implemented at least by libpam-ldap,
# libpam-ldapd, and the slapo-smbk5pwd overlay.
olcAccess: to attrs=shadowLastChange
  by self write
  by * read
# The admin dn (olcRootDN) bypasses ACLs and so has total access,
# everyone else can read everything.
olcAccess: to *
  by * read
Loading