From 2afe411f443842d82fd3f5e7ad1184d40f5b5f8b Mon Sep 17 00:00:00 2001
From: Adar Nimrod <nimrod@shore.co.il>
Date: Sat, 23 Nov 2019 21:31:23 +0200
Subject: [PATCH] Updates.

A lot of different fixes. What I have in production right now.
---
 .gitlab-ci.yml                  | 46 +++++++++++++++++++++++++++++++++
 .pre-commit-config.yaml         | 11 +++++---
 docker-compose.yml              | 45 +++++++++++++++-----------------
 ldap-account-manager/Dockerfile |  6 ++---
 ldap-account-manager/README.md  |  2 +-
 ldap-account-manager/patch.diff |  2 +-
 slapd/Dockerfile                |  2 +-
 slapd/backup                    |  4 ++-
 slapd/config.ldif               | 12 ++++++---
 slapd/entrypoint                | 14 +++++++---
 10 files changed, 102 insertions(+), 42 deletions(-)
 create mode 100644 .gitlab-ci.yml

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..b9e25f2
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,46 @@
+---
+image: adarnimrod/ci-images:docker
+
+stages:
+  - test
+  - build
+  - run
+
+pre-commit:
+  stage: test
+  image: adarnimrod/ci-images:pre-commit
+  variables:
+    XDG_CACHE_HOME: "$CI_PROJECT_DIR/.cache"
+    # Disabled until https://github.com/pre-commit/pre-commit/issues/1387 is
+    # resolved.
+    SKIP: "hadolint,docker-compose"
+  script:
+    - pre-commit run --all-files
+  cache:
+    paths:
+      - .cache/
+
+build:
+  stage: build
+  tags: ["host01.shore.co.il"]
+  variables:
+    # COMPOSE_DOCKER_CLI_BUILD: "1"
+    # DOCKER_BUILDKIT: "1"
+  script:
+    - docker-compose build --no-cache --pull
+    - docker-compose pull --quiet
+
+run:
+  stage: run
+  tags: ["host01.shore.co.il"]
+  when: manual
+  script:
+    - docker-compose up --detach --remove-orphans
+    # yamllint disable rule:line-length
+    - |
+        for i in $(seq 12)
+        do
+            docker container inspect --format '{{ .State.Health.Status }}' $(docker-compose ps -q) | grep -v '^healthy$' || break
+            sleep 10
+        done
+        ! docker container inspect --format '{{ .State.Health.Status }}' $(docker-compose ps -q) | grep -v '^healthy$'
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 7dfd794..593c19f 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -19,14 +19,19 @@ repos:
     hooks:
       - id: proselint
         types: [plain-text]
-        exclude: LICENSE|requirements
-  - repo: https://www.shore.co.il/git/shell-pre-commit/
+        exclude: LICENSE
+  - repo: https://git.shore.co.il/nimrod/shell-pre-commit.git/
     rev: v0.6.0
     hooks:
       - id: shell-lint
       - id: shellcheck
-  - repo: https://www.shore.co.il/git/docker-pre-commit
+  - repo: https://git.shore.co.il/nimrod/docker-pre-commit.git/
     rev: v0.3.0
     hooks:
       - id: hadolint
       - id: docker-compose
+  - repo: https://github.com/Yelp/detect-secrets
+    rev: v0.13.0
+    hooks:
+      - id: detect-secrets
+        exclude: \.diff$
diff --git a/docker-compose.yml b/docker-compose.yml
index 5aab814..ec4f4d4 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -10,53 +10,50 @@ services:
 
   ldap:
     build:
-      cache_from:
-        - adarnimrod/slapd
       context: slapd/
-    domainname: "${LDAP_HOSTNAME:-ldap}.${LDAP_DOMAIN:-nowhere.com}"
     environment:
       LDAP_ROOTPASS: &password "${LDAP_ROOTPASS:-foo}"
-      LDAP_DOMAIN: "${LDAP_DOMAIN:-nowhere.com}"
-      LDAP_ORGANIZATION: "${LDAP_ORGANIZATION:-none}"
-    hostname: "${LDAP_HOSTNAME:-ldap}"
+      LDAP_DOMAIN: "${LDAP_DOMAIN:-shore.co.il}"
+      LDAP_ORGANIZATION: "${LDAP_ORGANIZATION:-shore}"
+      #SLAPD_DEBUG_LEVEL: "any"
+      SSL_DHPARAMS_FILE: /var/ssl/dhparams
+    hostname: "${LDAP_HOSTNAME:-ldap}.${LDAP_DOMAIN:-shore.co.il}"
     image: adarnimrod/slapd
     restart: always
     volumes:
       - _run_slapd:/run/slapd
       - ldap:/var/lib/ldap
       - backup_ldap:/var/backups/ldap
-
-  nss-pam-ldapd:
-    build:
-      context: nss-pam-ldapd/
-    command: /usr/sbin/nslcd --debug --nofork
-    depends_on:
-      - ldap
-    environment:
-      LDAP_BASE_DN: &base_dn "${LDAP_BASE_DN:-dc=nowhere,dc=com}"
-    volumes:
-      - _run_slapd:/run/slapd
+      - /var/ssl/dhparams:/var/ssl/dhparams:ro
 
   ldap-account-manager:
     build:
-      cache_from:
-        - adarnimrod/ldap-account-manager
       context: ldap-account-manager/
     depends_on:
       - ldap
     environment:
-      LAM_PASSWORD: *password
-      LDAP_ADMIN_DN: "cn=admin,${LDAP_BASE_DN:-dc=nowhere,dc=com}"
-      LDAP_BASE_DN: *base_dn
+      LAM_PASSWORD: *password  # pragma: allowlist secret
+      LDAP_ADMIN_DN: "cn=admin,${LDAP_BASE_DN:-dc=shore,dc=co,dc=il}"
+      LDAP_BASE_DN: &base_dn "${LDAP_BASE_DN:-dc=shore,dc=co,dc=il}"
     image: adarnimrod/ldap-account-manager
-    ports:
-      - 80:80
     restart: always
     volumes:
       - _run_slapd:/run/slapd
 
+  # nss-pam-ldapd:
+  #   build:
+  #     context: nss-pam-ldapd/
+  #   command: /usr/sbin/nslcd --debug --nofork
+  #   depends_on:
+  #     - ldap
+  #   environment:
+  #     LDAP_BASE_DN: *base_dn
+  #   volumes:
+  #     - _run_slapd:/run/slapd
+
 volumes:
   _run_slapd:
+    name: run_slapd
   ldap:
   backup_ldap:
     labels:
diff --git a/ldap-account-manager/Dockerfile b/ldap-account-manager/Dockerfile
index ea9a02c..67bfa93 100644
--- a/ldap-account-manager/Dockerfile
+++ b/ldap-account-manager/Dockerfile
@@ -1,4 +1,4 @@
-FROM debian:sid-slim
+FROM debian:bullseye-slim
 # hadolint ignore=DL3008
 RUN apt-get update && \
     DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
@@ -15,7 +15,6 @@ RUN apt-get update && \
     a2enmod status && \
     ln -sf /dev/stdout /var/log/apache2/access.log && \
     ln -sf /dev/stderr /var/log/apache2/error.log && \
-    ln -sf /dev/stdout /var/log/apache2/lam.log && \
     ln -sf /dev/stdout /var/log/apache2/other_vhosts_access.log && \
     rm -rf /tmp/* /var/tmp/* /var/lib/apt/lists/* /var/cache/apt/archives/*
 ENV APACHE_RUN_DIR=/run/apache2 \
@@ -28,8 +27,7 @@ COPY --chown=root:root entrypoint /usr/local/bin/
 COPY --chown=root:root lam-setpass /usr/local/bin/
 RUN patch --strip 0 --verbose --directory / --input /root/patch.diff && \
     apache2 -t
-ENV LDAP_URI=ldapi:/// \
-    LAM_PASSWORD=lam
+ENV LDAP_URI=ldapi:///
 EXPOSE 80
 USER "www-data"
 WORKDIR /var/www
diff --git a/ldap-account-manager/README.md b/ldap-account-manager/README.md
index b333d63..7d55bf1 100644
--- a/ldap-account-manager/README.md
+++ b/ldap-account-manager/README.md
@@ -6,7 +6,7 @@
 
 Name | Description | Default value
 --- | --- | ---
-`LAM_PASSWORD` | Password for administrating LAM | `lam`
+`LAM_PASSWORD` | Password for administering LAM | `lam`
 `LDAP_URI` | URI of the LDAP service | `ldapi:///`
 `LDAP_ADMIN_DN` | DN of the admin account
 `LDAP_BASE_DN` | Base DN
diff --git a/ldap-account-manager/patch.diff b/ldap-account-manager/patch.diff
index d39c2fb..a796b93 100644
--- a/ldap-account-manager/patch.diff
+++ b/ldap-account-manager/patch.diff
@@ -5,7 +5,7 @@
  
  # log destination
 -logDestination: SYSLOG
-+logDestination: /var/log/apache2/lam.log
++logDestination: /dev/stdout
 --- /etc/apache2/sites-available/000-default.conf	2018-11-03 13:34:33.000000000 +0200
 +++ /etc/apache2/sites-available/000-default.conf	2019-06-25 14:55:43.956626591 +0300
 @@ -18,7 +18,7 @@
diff --git a/slapd/Dockerfile b/slapd/Dockerfile
index 85c0540..118c59e 100644
--- a/slapd/Dockerfile
+++ b/slapd/Dockerfile
@@ -43,5 +43,5 @@ WORKDIR /var/lib/ldap
 USER openldap
 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
+HEALTHCHECK --start-period=5m CMD ldapsearch -b cn=config > /dev/null || exit 1
 STOPSIGNAL INT
diff --git a/slapd/backup b/slapd/backup
index 6ba3110..320d7ff 100755
--- a/slapd/backup
+++ b/slapd/backup
@@ -1,9 +1,11 @@
 #!/bin/sh
 set -eux
 
+alias slapcat='slapcat -vF /var/lib/ldap/config'
+
 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"
+    slapcat -b "$dn" -v -l "/var/backups/ldap/$dn.ldif"
 done
diff --git a/slapd/config.ldif b/slapd/config.ldif
index 433d826..e10040d 100644
--- a/slapd/config.ldif
+++ b/slapd/config.ldif
@@ -18,7 +18,7 @@ olcTLSCertificateFile: ${SSL_CERT_FILE}
 olcTLSCertificateKeyFile: ${SSL_KEY_FILE}
 olcTLSCipherSuite: SECURE256:+SECURE128
 olcTLSProtocolMin: 3.1
-olcTLSDHParamFile: /usr/share/slapd/dh.pem
+olcTLSDHParamFile: ${SSL_DHPARAMS_FILE}
 
 # Frontend settings
 dn: olcDatabase={-1}frontend,cn=config
@@ -29,16 +29,20 @@ olcDatabase: {-1}frontend
 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 unlimited access to local connection from the local slapd user
+olcAccess: {1}to * by dn.exact=gidNumber=${SLAPD_GID}+uidNumber=${SLAPD_UID},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
+olcAccess: {2}to dn.exact="" by * read
+olcAccess: {3}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
+olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break
+# Allow unlimited access to local connection from the local slapd user
+olcAccess: {1}to * by dn.exact=gidNumber=${SLAPD_GID}+uidNumber=${SLAPD_UID},cn=peercred,cn=external,cn=auth manage by * break
 olcRootDN: cn=admin,cn=config
 
 # Load schemas
diff --git a/slapd/entrypoint b/slapd/entrypoint
index 862d622..95c232b 100755
--- a/slapd/entrypoint
+++ b/slapd/entrypoint
@@ -27,8 +27,12 @@ then
 fi
 
 # Generate random DH parameters.
-echo Generating DH parameters, this will take a while. >&2
-time openssl dhparam -out /usr/share/slapd/dh.pem 2048
+if [ -z "${SSL_DHPARAMS_FILE:-}" ] || [ ! -f "${SSL_DHPARAMS_FILE:-}" ]
+then
+    echo Generating DH parameters, this will take a while. >&2
+    export SSL_DHPARAMS_FILE='/usr/share/slapd/dh.pem'
+    time openssl dhparam -out "$SSL_DHPARAMS_FILE" 2048
+fi
 
 # Run slapadd with the correct user and location of the config directory.
 alias slapadd='slapadd -gv -F /var/lib/ldap/config'
@@ -37,6 +41,10 @@ alias slapadd='slapadd -gv -F /var/lib/ldap/config'
 if [ -z "$(find /var/lib/ldap/config -maxdepth 1 -mindepth  1)" ]
 then
     echo No configuration found, generating a new one. >&2
+    SLAPD_UID="$(id -u openldap)"
+    export SLAPD_UID
+    SLAPD_GID="$(id -g openldap)"
+    export SLAPD_GID
     # shellcheck disable=SC2002
     cat /usr/share/slapd/config.ldif | envsubst | slapadd -b 'cn=config'
 fi
@@ -50,7 +58,7 @@ then
 fi
 
 # Configure the client.
-cat << EOF >> /etc/ldap/ldap.conf
+cat >> /etc/ldap/ldap.conf <<EOF
 URI         ldapi:///
 SASL_MECH   EXTERNAL
 BASE        $BASE_DN
-- 
GitLab