diff --git a/dockerfile b/dockerfile index ee455e2..0f6d98f 100644 --- a/dockerfile +++ b/dockerfile @@ -1,22 +1,43 @@ FROM ubuntu:22.04 -# set container hostname +# set container hostname and DN in case we don't set it on the docker build/run command ARG LDAP_HOST=example.com ENV LDAP_HOST=${LDAP_HOST} # set non-interactive TERM for docker ENV DEBIAN_FRONTEND=noninteractive - -# install slapd, ldap-utils, and packages needed for ldapdock to work +#────────────────────────────────────────────────────────────── +# install OpenLDAP, ldap-utils, and packages needed for ldapdock to work +#────────────────────────────────────────────────────────────── RUN apt-get update && apt-get install -y --no-install-recommends \ slapd ldap-utils gnutls-bin ssl-cert ca-certificates schema2ldif vim mc && apt-get clean +#────────────────────────────────────────────────────────────── +# APACHE && PHP && neccesary related software +#────────────────────────────────────────────────────────────── +RUN apt-get update && apt-get install -y --no-install-recommends \ + apache2 \ + php libapache2-mod-php \ + php-ldap php-mbstring php-xml php-curl php-intl wget \ + && rm -rf /var/lib/apt/lists/* + +# Enable required Apache modules +RUN a2enmod rewrite headers ssl + +# Use mpm_prefork (required for PHP) +RUN a2dismod mpm_event && a2enmod mpm_prefork + +# Clean up default Apache site +RUN rm -rf /var/www/html/* && \ + echo "" > /var/www/html/info.php + # preconfigure slapd installation without using systemd RUN echo "slapd slapd/password1 password admin" | debconf-set-selections && \ echo "slapd slapd/password2 password admin" | debconf-set-selections && \ echo "slapd slapd/domain string example.com" | debconf-set-selections && \ echo "slapd slapd/no_configuration boolean false" | debconf-set-selections && \ echo "slapd slapd/purge_database boolean true" | debconf-set-selections && \ + echo "slapd slapd/ldapi_tls boolean false" | debconf-set-selections && \ echo "slapd slapd/move_old_database boolean true" | debconf-set-selections # make use of debconf-set-selections @@ -26,21 +47,27 @@ RUN dpkg-reconfigure -f noninteractive slapd COPY entrypoint.sh ./entrypoint.sh RUN chmod +x ./entrypoint.sh -# open up LDAP simple port +# open up LDAP StartTLS and SSL ports, and Apache ports EXPOSE 389 EXPOSE 636 +EXPOSE 80 +EXPOSE 443 +#────────────────────────────────────────────────────────────── # Create directory for exporting certs to host RUN mkdir -p /export-certs +#────────────────────────────────────────────────────────────── # set salvable volumes for LDAP data, configuration, certs VOLUME ["/var/lib/ldap", "/etc/ldap/slapd.d", "/etc/ldap/certs","/export-certs"] # set correct permissions for openldap user -RUN chown -R openldap:openldap /var/lib/ldap /etc/ldap/slapd.d +#RUN chown -R openldap:openldap /var/lib/ldap /etc/ldap/slapd.d +#────────────────────────────────────────────────────────────── # ENTRYPOINT ensures this sh file ALWAYS runs first before any CMD or command line instruction ENTRYPOINT ["./entrypoint.sh"] +#────────────────────────────────────────────────────────────── # CMD provides the default command (/bin/bash) which is passed as an argument to the ENTRYPOINT script CMD ["/bin/bash"] diff --git a/entrypoint.sh b/entrypoint.sh index 836bed6..f3a9483 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,32 +1,65 @@ #!/bin/bash -# this script runs INSIDE the container -# set -e # exit on any error? +set -euo pipefail + +# Fix permissions +chown -R openldap:openldap /var/lib/ldap /etc/ldap/slapd.d /etc/ldap/certs 2>/dev/null || true +chmod -R 777 /export-certs 2>/dev/null || true + +#────────────────────────────────────────────────────────────── +# Correct base DN and hostname +#export LDAP_HOST="${LDAP_HOST:-example.com}" +export LDAP_HOST="${LDAP_HOST:-$(hostname)}" +export LDAP_BASE_DN=dc=$(echo "$LDAP_HOST" | sed 's/\./,dc=/g') +echo "--> Using LDAP base DN: ${LDAP_BASE_DN}" +#────────────────────────────────────────────────────────────── echo "--> Starting ldapdock 0.10" -echo "--> Launching slapd (temp)..." -# start slapd temporarily for setup -/usr/sbin/slapd -h "ldap:/// ldapi:///" -g openldap -u openldap & -sleep 3 +# Temporarily "relax" strict security on start to configure stuff +if [ -d "/etc/ldap/slapd.d" ] && ls /etc/ldap/slapd.d/* >/dev/null 2>&1; then + echo "--> Temporarily relaxing security for init" + slapd -h "ldap:/// ldapi:///" -u openldap -g openldap & + sleep 6 + ldapmodify -Y EXTERNAL -H ldapi:/// >/dev/null 2>&1 < Populating directory with users and groups..." -cat > /tmp/add_content.ldif << EOF -dn: ou=People,dc=${LDAP_HOST} +# Start temporary slapd for Users and Groups addition +echo "--> Starting temporary slapd" +slapd -h "ldap:/// ldapi:///" -u openldap -g openldap & +SLAPD_PID=$! +sleep 8 + +# Full tree with root entry +cat > /tmp/base.ldif < Adding base structure..." -ldapadd -x -D "cn=admin,dc=${LDAP_HOST}" -w admin -f /tmp/add_content.ldif || \ - echo "--> Some entries already exist — continuing (this is normal)" -# setting up user marisa of group People password -ldappasswd -x -D "cn=admin,dc=${LDAP_HOST}" -w admin -s qwerty "uid=marisa,ou=People,dc=${LDAP_HOST}" -sleep 2 - -# load and enable policies module - -echo "--> Loading policies module..." -cat > modify_ppolicy_module.ldif << EOF -dn: cn=module{0},cn=config -changetype: modify -add: olcModuleLoad -olcModuleLoad: ppolicy.so +gecos: Marisa Kirisame EOF -ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f modify_ppolicy_module.ldif +echo "--> Adding base structure" +ldapadd -c -x -D "cn=admin,dc=example,dc=com" -w admin -f /tmp/base.ldif || true -# restarting slapd to load ppolicy.so +# Set a hardcoded password for Marisa to enable tests on the user +echo "--> Setting Marisa password to 'MarisaNewPass2025'" +slappasswd -h '{SSHA}' -s MarisaNewPass2025 | \ +ldapmodify -Y EXTERNAL -H ldapi:/// >/dev/null 2>&1 || true -slapd -h "ldap:/// ldapi:/// ldaps:///" -u openldap -g openldap & -sleep 3 - -cat > enable_ppolicy.ldif << EOF -dn: olcOverlay=ppolicy,olcDatabase={1}mdb,cn=config -changetype: add -objectClass: olcOverlayConfig -objectClass: olcPPolicyConfig -olcOverlay: ppolicy -EOF -#olcPPolicyDefault: cn=default,ou=policies,dc=${LDAP_HOST} - -ldapadd -Q -Y EXTERNAL -H ldapi:/// -f enable_ppolicy.ldif - -# display schemas loaded by default -echo "--> Schemas loaded by default..." -ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=schema,cn=config dn - -# kill temp slapd -pkill slapd -sleep 3 - -# === CERTIFICATES: ONLY IF NOT ALREADY EXPORTED === +#────────────────────────────────────────────────────────────── +# TLS BLOCK +#────────────────────────────────────────────────────────────── if [ ! -f "/export-certs/mycacert.crt" ]; then - echo "--> No CA found in /export-certs → generating certificates..." - + echo "--> No CA found → generating certificates..." mkdir -p /etc/ldap/certs cd /etc/ldap/certs - - # CA certtool --generate-privkey --bits 4096 --outfile ca-key.pem cat > ca.info < ldap01.info < ldap01_slapd_cert_full.pem chown root:openldap ldap01_slapd_cert_full.pem chmod 640 ldap01_slapd_cert_full.pem - - # start temp slapd to apply config + echo "--> Starting second temporary slapd to apply TLS config" slapd -h "ldap:/// ldapi:///" -u openldap -g openldap & - sleep 3 - - # apply TLS config + sleep 4 cat > /tmp/certinfo.ldif < Exporting CA to /export-certs..." + echo "--> Exporting certificates to host volume..." cp /etc/ldap/certs/ca-cert.pem /export-certs/mycacert.crt cp /etc/ldap/certs/ldap01_slapd_cert_full.pem /export-certs/server-cert.pem - echo "--> Certificate READY at ./hosts-certs/mycacert.crt on host" else - echo "--> CA already exists at /export-certs/mycacert.crt → skipping generation" + echo "--> Certificates already exist — skipping generation" fi -# === FINAL SLAPD START === -echo "--> Starting final slapd with LDAPS..." +# Kill temporary slapd +kill $SLAPD_PID 2>/dev/null || true +wait $SLAPD_PID 2>/dev/null || true + +# Start OpenLDAP in background +echo "--> Starting final OpenLDAP (background)" slapd -h "ldap:/// ldaps:/// ldapi:///" -u openldap -g openldap -d 0 & -sleep 3 +SLAPD_PID=$! -# === ENABLE TLS FOR ALL CLIENT TOOLS INSIDE CONTAINER === -export LDAPTLS_CACERT=/etc/ldap/certs/ca-cert.pem -echo "LDAPTLS_CACERT=$LDAPTLS_CACERT (all ldap* commands now work with TLS)" -echo 'export LDAPTLS_CACERT=/etc/ldap/certs/ca-cert.pem' >> ~/.bashrc -source ~/.bashrc +# Start Apache in background +echo "--> Starting Apache + PHP (background)" +apache2ctl -D FOREGROUND & +APACHE_PID=$! -echo "--> ldapdock framework ready." +# Victory message +echo "--> ldapdock ready — OpenLDAP + Apache + PHP running" +echo " → LDAP: 389/636" +echo " → Web: http://localhost/info.php" +echo " → Shell: you are here forever" +echo " → Stop with Ctrl+C" -# === KEEP CONTAINER ALIVE AND CONTINUE === +# THIS IS THE MAGIC LINE THAT KILLS CHILD PROCESSES ON EXIT +trap 'echo "Stopping services..."; kill $SLAPD_PID $APACHE_PID 2>/dev/null; wait' SIGINT SIGTERM -# 'exec' replaces the script process with the command (e.g., /bin/bash), -# ensuring the container stays alive as long as that command runs interactively. -echo "Executing: $@" +# Give you your interactive shell — forever exec "$@" -