more or less working entrypoint
This commit is contained in:
parent
0244610e28
commit
214e40f367
39
Dockerfile
39
Dockerfile
@ -1,27 +1,40 @@
|
|||||||
FROM eumau/debian:buster-slim
|
FROM eumau/debian:buster-slim
|
||||||
|
|
||||||
ENV OPENLDAP_ADMIN_PASSWORD="root"
|
ENV LDAP_ADMIN_CN="admin"
|
||||||
|
# admin CN, DN => cn=%%ADMIN_DN%%,%%DOMAIN_DN%%
|
||||||
|
ENV LDAP_ADMIN_PASSWORD="admin"
|
||||||
|
# password for cn=%%ADMIN_DN%%,%%DOMAIN_DN%%
|
||||||
|
ENV LDAP_CONFIG_PASSWORD="${LDAP_ADMIN_PASSWORD}"
|
||||||
|
# password for cn=admin,cn=config
|
||||||
|
ENV LDAP_DOMAIN=""
|
||||||
|
# domain O (example.org)
|
||||||
|
ENV LDAP_DOMAIN_ACCESS="{0}to attrs=userPassword by self write by anonymous auth by * none\n{1}to attrs=shadowLastChange by self write by * read\n{2}to * by * read"
|
||||||
|
# olcDbAccess attribute for domain entry (newline-separated)
|
||||||
|
ENV LDAP_DOMAIN_DN=""
|
||||||
|
# domain DN (dc=example,dc=org)
|
||||||
|
ENV LDAP_DOMAIN_INDEX="cn,uid eq\nmember,memberUid eq\nobjectClass eq\nuidNumber,gidNumber eq"
|
||||||
|
# olcDbIndex attribute for domain entry (newline-separated)
|
||||||
|
ENV LDAP_DOMAIN_OUS="People Alias Group"
|
||||||
|
# domain OUs (space-separated)
|
||||||
|
ENV LDAP_MEMBEROF="true"
|
||||||
|
# enable memberOf module
|
||||||
|
ENV LDAP_SCHEMAS="core cosine inetorgperson misc nis"
|
||||||
|
# space-separated list of schemas to load
|
||||||
|
|
||||||
# space-separated list of schemas
|
RUN apt-get update \
|
||||||
ENV OPENLDAP_SCHEMAS="misc"
|
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||||
|
|
||||||
RUN apt-get update && \
|
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
|
||||||
slapd \
|
slapd \
|
||||||
ldap-utils && \
|
ldap-utils && \
|
||||||
apt-get clean && \
|
apt-get clean && \
|
||||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||||
|
|
||||||
COPY entrypoint.sh /entrypoint.sh
|
ADD entrypoint.sh /
|
||||||
|
|
||||||
# ADD my_custom_schema: install by setting OPENLDAP_SCHEMAS=my_custom_schema
|
|
||||||
# COPY my_custom_schema.ldif /etc/ldap/schema/my_custom_schema.ldif
|
|
||||||
|
|
||||||
EXPOSE 389
|
EXPOSE 389
|
||||||
|
|
||||||
VOLUME ["/etc/ldap/slapd.d", "/var/lib/ldap", "/var/backups/ldap"]
|
VOLUME ["/etc/ldap/schema", "/etc/ldap/slapd.d", "/var/lib/ldap", "/var/backups/ldap"]
|
||||||
|
|
||||||
|
ENTRYPOINT ["/entrypoint.sh"]
|
||||||
|
|
||||||
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
|
|
||||||
# log level info:
|
# log level info:
|
||||||
|
|
||||||
CMD ["slapd", "-d", "32768", "-u", "openldap", "-g", "openldap"]
|
CMD ["slapd", "-d", "32768", "-u", "openldap", "-g", "openldap"]
|
||||||
|
202
entrypoint.sh
202
entrypoint.sh
@ -1,28 +1,25 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
msg(){ ${VERBOSE:-true} && echo ${@} ; }
|
assert(){ [[ $? -eq 0 ]] || { [[ -n ${1} ]] && echo ${@} ; exit 1 ; } }
|
||||||
assert(){ [[ $? -eq 0 ]] || { [[ -n ${1} ]] && msg ${@} ; exit 1 ; } }
|
|
||||||
|
|
||||||
# from https://github.com/dinkel/docker-openldap/blob/master/entrypoint.sh:
|
# from https://github.com/dinkel/docker-openldap/blob/master/entrypoint.sh:
|
||||||
# When not limiting the open file descritors limit, the memory consumption of
|
# When not limiting the open file descritors limit, the memory consumption of
|
||||||
# slapd is absurdly high. See https://github.com/docker/docker/issues/8231
|
# slapd is absurdly high. See https://github.com/docker/docker/issues/8231
|
||||||
ulimit -n 8192
|
ulimit -n 8192
|
||||||
|
|
||||||
msg "I: running slapd for initial setup..."
|
echo "I: running slapd for initial setup..."
|
||||||
slapd -u openldap -g openldap -h ldapi:///
|
slapd -u openldap -g openldap -h ldapi:///
|
||||||
assert "E: openldap died unexpectedly!"
|
assert "E: openldap died unexpectedly!"
|
||||||
|
|
||||||
PIDFILE=$(ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b "cn=config" -s base \
|
PIDFILE=$(ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b "cn=config" -s base \
|
||||||
"" olcPidFile | grep olcPidFile | awk "{print $2}")
|
"" olcPidFile | grep olcPidFile | awk "{print $2}")
|
||||||
msg "I: slapd running with PID ${PIDFILE}"
|
echo "I: slapd running with PID ${PIDFILE}"
|
||||||
|
|
||||||
[[ -n "${OPENLDAP_ADMIN_PASSWORD}" ]]
|
[[ -n "${LDAP_CONFIG_PASSWORD}" ]]
|
||||||
assert "E: please set non-empty password in OPENLDAP_ADMIN_PASSWORD and retry."
|
assert "E: please set non-empty password in LDAP_CONFIG_PASSWORD and retry."
|
||||||
|
|
||||||
HASHED_PW=$(slappasswd -h {SSHA} -s "${OPENLDAP_ADMIN_PASSWORD}")
|
HASHED_PW=$(slappasswd -h "{SSHA}" -s "${LDAP_CONFIG_PASSWORD}")
|
||||||
[[ -n "${HASHED_PW}" ]]
|
|
||||||
assert "E: password hash unexpectedly empty!"
|
|
||||||
|
|
||||||
msg "I: Setting administrator password..."
|
echo "I: Setting administrator password..."
|
||||||
ldapmodify -Y EXTERNAL -H ldapi:/// <<EOF
|
ldapmodify -Y EXTERNAL -H ldapi:/// <<EOF
|
||||||
dn: olcDatabase={0}config,cn=config
|
dn: olcDatabase={0}config,cn=config
|
||||||
changetype: modify
|
changetype: modify
|
||||||
@ -36,15 +33,15 @@ assert "FATAL: failure setting administrator password!"
|
|||||||
eval "declare -A LOADED_SCHEMAS=( $(ldapsearch -LLL -Y EXTERNAL -H ldapi:/// \
|
eval "declare -A LOADED_SCHEMAS=( $(ldapsearch -LLL -Y EXTERNAL -H ldapi:/// \
|
||||||
-b "cn=schema,cn=config" -s one cn \
|
-b "cn=schema,cn=config" -s one cn \
|
||||||
| sed -n 's/^cn:.*[{].*[}]\(.*\)$/[\1]=loaded/p') )"
|
| sed -n 's/^cn:.*[{].*[}]\(.*\)$/[\1]=loaded/p') )"
|
||||||
msg "I: currently loaded schemas: ${!LOADED_SCHEMAS[@]}"
|
echo "I: currently loaded schemas: ${!LOADED_SCHEMAS[@]}"
|
||||||
|
|
||||||
# load schemas
|
# load schemas
|
||||||
# built-in: core, cosine, nis, inetorgperson
|
# built-in: core, cosine, nis, inetorgperson
|
||||||
# available: collective, corba, duaconf, dyngroup, java, misc, nis, openldap, pmi, ppolicy
|
# available: collective, corba, duaconf, dyngroup, java, misc, nis, openldap, pmi, ppolicy
|
||||||
for schema in ${OPENLDAP_SCHEMAS}
|
for schema in ${LDAP_SCHEMAS}
|
||||||
do
|
do
|
||||||
[[ -z "${LOADED_SCHEMAS[$schema]}" ]] || continue;
|
[[ -z "${LOADED_SCHEMAS[$schema]}" ]] || continue;
|
||||||
msg "I: loading schema ${schema}..."
|
echo "I: loading schema ${schema}..."
|
||||||
[[ -f /etc/ldap/schema/${schema}.ldif ]]
|
[[ -f /etc/ldap/schema/${schema}.ldif ]]
|
||||||
assert "E: schema /etc/ldap/schema/${schema}.ldif not found!"
|
assert "E: schema /etc/ldap/schema/${schema}.ldif not found!"
|
||||||
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/${schema}.ldif
|
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/${schema}.ldif
|
||||||
@ -52,9 +49,9 @@ do
|
|||||||
done
|
done
|
||||||
|
|
||||||
# enable memberof module
|
# enable memberof module
|
||||||
if ${OPENLDAP_ENABLE_MEMBEROF}
|
if ${LDAP_MEMBEROF}
|
||||||
then
|
then
|
||||||
msg "I: enabling memberof module ..."
|
echo "I: enabling memberof module ..."
|
||||||
ldapmodify -Y EXTERNAL -H ldapi:/// <<EOF
|
ldapmodify -Y EXTERNAL -H ldapi:/// <<EOF
|
||||||
dn: cn=module{0},cn=config
|
dn: cn=module{0},cn=config
|
||||||
changetype: modify
|
changetype: modify
|
||||||
@ -65,21 +62,188 @@ EOF
|
|||||||
RES=$?
|
RES=$?
|
||||||
[[ $RES -eq 0 ]] || [[ $RES -eq 20 ]]
|
[[ $RES -eq 0 ]] || [[ $RES -eq 20 ]]
|
||||||
assert "E: failed loading memberof module (${RES})"
|
assert "E: failed loading memberof module (${RES})"
|
||||||
msg "I: module memberof enabled (${RES})"
|
echo "I: module memberof enabled (${RES})"
|
||||||
unset RES
|
unset RES
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# 0. calcular DN a partir del dominio
|
||||||
|
|
||||||
|
# 1.3.0 crear password admin
|
||||||
|
ADMIN_PW_HASH=$(slappasswd -h "{SSHA}" -s "${LDAP_ADMIN_PASSWORD}")
|
||||||
|
|
||||||
|
# 1.2 buscar dominio
|
||||||
|
if ldapsearch -LLL -H ldapi:/// -Y EXTERNAL -s one -b "cn=config" \
|
||||||
|
"(&(olcSuffix=\"${LDAP_DOMAIN_DN}\")(olcDatabase=mdb))" | \
|
||||||
|
egrep -q '^dn: '
|
||||||
|
then
|
||||||
|
echo "Found cn=config entry for ${LDAP_DOMAIN_DN}"
|
||||||
|
else
|
||||||
|
echo "No cn=config entry for ${LDAP_DOMAIN_DN}."
|
||||||
|
echo "Creating directory /var/lib/ldap/${LDAP_DOMAIN_DN}"
|
||||||
|
mkdir "/var/lib/ldap/${LDAP_DOMAIN_DN}"
|
||||||
|
chown -R openldap:openldap "/var/lib/ldap/${LDAP_DOMAIN_DN}"
|
||||||
|
|
||||||
|
echo "Creating cn=config entry for ${LDAP_DOMAIN_DN}"
|
||||||
|
|
||||||
|
ldapadd -Y EXTERNAL -H ldapi:/// <<EOF
|
||||||
|
dn: olcDatabase=mdb,cn=config
|
||||||
|
objectClass: olcDatabaseConfig
|
||||||
|
objectClass: olcMdbConfig
|
||||||
|
olcDbMaxSize: 1073741824
|
||||||
|
olcSuffix: ${LDAP_DOMAIN_DN}
|
||||||
|
olcDbDirectory: /var/lib/ldap/${LDAP_DOMAIN_DN}
|
||||||
|
olcRootDN: cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN}
|
||||||
|
olcRootPW: ${ADMIN_PW_HASH}
|
||||||
|
$(echo -ne "${LDAP_DOMAIN_ACCESS}" | sed -e 's/^/olcAccess: /g')
|
||||||
|
olcDbCheckpoint: 512 30
|
||||||
|
olcLastMod: TRUE
|
||||||
|
$(echo -ne "${LDAP_DOMAIN_INDEX}" | sed -e 's/^/olcDbIndex: /g')
|
||||||
|
$(echo -ne "${LDAP_DOMAIN_LIMITS}" | sed -e 's/^/olcLimits: /g')
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Get DN of cn=config entry for ${LDAP_DOMAIN_DN}"
|
||||||
|
CN_CONFIG_DN=$(ldapsearch -LLL -H ldapi:/// -Y EXTERNAL -s one -b cn=config "(&(olcSuffix=${LDAP_DOMAIN_DN})(olcDatabase=mdb))" | egrep '^dn: ' | sed -e 's/^dn: //g')
|
||||||
|
|
||||||
|
if [[ -n ${CN_CONFIG_DN} ]]
|
||||||
|
then echo "Found DN = ${CN_CONFIG_DN}"
|
||||||
|
else
|
||||||
|
echo "FATAL: could not find cn=config entry for ${LDAP_DOMAIN_DN}"
|
||||||
|
echo "PLEASE NOTE: only MDB database format is supported (PR welcome :)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. olcovrlay memberof
|
||||||
|
if [[ ${LDAP_MEMBEROF} ]]
|
||||||
|
then
|
||||||
|
echo "Check if memberOf is enabled"
|
||||||
|
MEMBEROF_DN=$(ldapsearch -LLL -H ldapi:/// -Y EXTERNAL -s one -b "${CN_CONFIG_DN}" "(olcOverlay=memberOf)" | egrep '^dn: ' | sed -e 's/^dn: //g')
|
||||||
|
|
||||||
|
if [[ -n ${MEMBEROF_DN} ]]
|
||||||
|
then echo "memberOf overlay already enabled for ${CN_CONFIG_DN}"
|
||||||
|
else
|
||||||
|
echo "Enabling memberOf overlay"
|
||||||
|
ldapadd -Y EXTERNAL -H ldapi:/// <<EOF
|
||||||
|
dn: olcOverlay=memberof,${CN_CONFIG_DN}
|
||||||
|
objectClass: olcOverlayConfig
|
||||||
|
objectClass: olcConfig
|
||||||
|
objectClass: olcMemberOf
|
||||||
|
olcMemberOfDangling: ignore
|
||||||
|
olcMemberOfRefInt: FALSE
|
||||||
|
olcMemberOfGroupOC: groupOfNames
|
||||||
|
olcMemberOfMemberAD: member
|
||||||
|
olcMemberOfMemberOfAD: memberOf
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ -n "${LDAP_ADMIN_PASSWORD}" ]]
|
||||||
|
assert "E: please set non-empty password in LDAP_ADMIN_PASSWORD and retry."
|
||||||
|
|
||||||
|
HASHED_PW=$(slappasswd -h "{SSHA}" -s "${LDAP_ADMIN_PASSWORD}")
|
||||||
|
|
||||||
|
echo "I: Setting domain administrator password..."
|
||||||
|
ldapmodify -Y EXTERNAL -H ldapi:/// <<EOF
|
||||||
|
dn: ${CN_CONFIG_DN}
|
||||||
|
changetype: modify
|
||||||
|
replace: olcRootPW
|
||||||
|
olcRootPW: ${HASHED_PW}
|
||||||
|
|
||||||
|
EOF
|
||||||
|
assert "FATAL: failure setting administrator password!"
|
||||||
|
|
||||||
|
# -------------------------------------------
|
||||||
|
|
||||||
|
# create base dn
|
||||||
|
|
||||||
|
echo "Check if ${LDAP_DOMAIN_DN} exists"
|
||||||
|
DOM_DN=$(ldapsearch -LLL -H ldapi:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} -w "${LDAP_ADMIN_PASSWORD}" -s base -b "${LDAP_DOMAIN_DN}" "(objectClass=*)" | egrep '^dn: ' | sed -e 's/^dn: //g')
|
||||||
|
|
||||||
|
if [[ -n ${DOM_DN} ]]
|
||||||
|
then echo "${LDAP_DOMAIN_DN} already present"
|
||||||
|
else
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
|
dn: ${LDAP_DOMAIN_DN}
|
||||||
|
objectClass: dcObject
|
||||||
|
objectClass: organization
|
||||||
|
objectClass: top
|
||||||
|
dc: $(echo -n "${LDAP_DOMAIN_DN#dc=}" | sed 's/,.*$//g')
|
||||||
|
o: ${LDAP_DOMAIN}
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "Creating ${LDAP_DOMAIN_DN}"
|
||||||
|
ldapadd -H ldapi:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} -w "${LDAP_ADMIN_PASSWORD}" <<EOF
|
||||||
|
dn: ${LDAP_DOMAIN_DN}
|
||||||
|
objectClass: dcObject
|
||||||
|
objectClass: organization
|
||||||
|
objectClass: top
|
||||||
|
dc: $(echo -n "${LDAP_DOMAIN_DN#dc=}" | sed 's/,.*$//g')
|
||||||
|
o: ${LDAP_DOMAIN}
|
||||||
|
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
# create admin user
|
||||||
|
|
||||||
|
echo "Check if cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} exists"
|
||||||
|
ADM_DN=$(ldapsearch -LLL -H ldapi:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} -w "${LDAP_ADMIN_PASSWORD}" -s base -b "cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN}" "(objectClass=*)" | egrep '^dn: ' | sed -e 's/^dn: //g')
|
||||||
|
|
||||||
|
if [[ -n ${ADM_DN} ]]
|
||||||
|
then echo "cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} already present"
|
||||||
|
else
|
||||||
|
|
||||||
|
echo "Creating cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN}"
|
||||||
|
ldapadd -H ldapi:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} -w "${LDAP_ADMIN_PASSWORD}" <<EOF
|
||||||
|
dn: cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN}
|
||||||
|
objectClass: organizationalRole
|
||||||
|
objectClass: simpleSecurityObject
|
||||||
|
cn: ${LDAP_ADMIN_CN}
|
||||||
|
description: LDAP Administrator role for domain ${LDAP_DOMAIN}
|
||||||
|
userPassword: ${ADMIN_PW_HASH}
|
||||||
|
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
# update admin password
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
|
||||||
|
# create OUs
|
||||||
|
|
||||||
|
for OU in ${LDAP_DOMAIN_OUS}
|
||||||
|
do
|
||||||
|
echo "Check if ou=${OU},${LDAP_DOMAIN_DN} exists"
|
||||||
|
OU_DN=$(ldapsearch -LLL -H ldapi:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} -w "${LDAP_ADMIN_PASSWORD}" -s base -b "ou=${OU},${LDAP_DOMAIN_DN}" "(objectClass=*)" | egrep '^dn: ' | sed -e 's/^dn: //g')
|
||||||
|
|
||||||
|
if [[ -n ${OU_DN} ]]
|
||||||
|
then echo "ou=${OU} already present in ${LDAP_DOMAIN_DN}"
|
||||||
|
else
|
||||||
|
echo "Creating ou=${OU},${LDAP_DOMAIN_DN}"
|
||||||
|
ldapadd -H ldapi:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} -w "${LDAP_ADMIN_PASSWORD}" <<EOF
|
||||||
|
dn: ou=${OU},${LDAP_DOMAIN_DN}
|
||||||
|
objectClass: organizationalUnit
|
||||||
|
objectClass: top
|
||||||
|
ou: ${OU}
|
||||||
|
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# -------------------------------------------
|
||||||
|
|
||||||
# kill slapd after initial setup
|
# kill slapd after initial setup
|
||||||
msg "I: killing initial server..."
|
echo "I: killing initial server..."
|
||||||
kill -INT $(cat ${PIDFILE})
|
kill -INT $(cat ${PIDFILE})
|
||||||
|
|
||||||
# unset sensitive variables
|
# unset sensitive variables
|
||||||
unset OPENLDAP_ROOT_PASSWORD
|
unset OPENLDAP_ADMIN_PASSWORD
|
||||||
unset HASHED_PW
|
unset HASHED_PW
|
||||||
unset LOADED_SCHEMAS
|
unset LOADED_SCHEMAS
|
||||||
unset PIDFILE
|
unset PIDFILE
|
||||||
|
|
||||||
# run Dockerfile CMD
|
# run Dockerfile CMD
|
||||||
msg "I: running CMD $@"
|
echo "I: running CMD $@"
|
||||||
set -e
|
set -e
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user