Optimized openldap role

This commit is contained in:
Kevin Veen-Birkenbach 2025-07-14 12:00:18 +02:00
parent bfd1a2ee70
commit 67122800f3
No known key found for this signature in database
GPG Key ID: 44D8F11FD62F878E
11 changed files with 56 additions and 44 deletions

View File

@ -4,8 +4,12 @@ network:
local: True # Activates local network. Necessary for LDIF import routines local: True # Activates local network. Necessary for LDIF import routines
docker: True # Activates docker network to allow other docker containers to connect docker: True # Activates docker network to allow other docker containers to connect
public: False # Set to true in inventory file if you want to expose the LDAP port to the internet public: False # Set to true in inventory file if you want to expose the LDAP port to the internet
images: docker:
openldap: "bitnami/openldap:latest" services:
openldap:
image: "bitnami/openldap"
version: "latest"
container: "<< defaults_applications[svc-db-openldap].hostname >>"
webinterface: "lam" # The webinterface which should be used. Possible: lam and phpldapadmin webinterface: "lam" # The webinterface which should be used. Possible: lam and phpldapadmin
features: features:
ldap: true ldap: true

View File

@ -1,6 +1,6 @@
- name: Load memberof module from file in OpenLDAP container - name: Load memberof module from file in OpenLDAP container
shell: > shell: >
docker exec -i {{ applications | get_app_conf(application_id, 'hostname', True) }} ldapmodify -Y EXTERNAL -H ldapi:/// -f {{ldif_docker_path}}configuration/01_member_of_configuration.ldif docker exec -i {{ applications | get_app_conf(application_id, 'hostname', True) }} ldapmodify -Y EXTERNAL -H ldapi:/// -f {{openldap_ldif_docker_path}}configuration/01_member_of_configuration.ldif
listen: listen:
- "Import configuration LDIF files" - "Import configuration LDIF files"
- "Import all LDIF files" - "Import all LDIF files"
@ -10,7 +10,7 @@
- name: Refint Module Activation for OpenLDAP - name: Refint Module Activation for OpenLDAP
shell: > shell: >
docker exec -i {{ applications | get_app_conf(application_id, 'hostname', True) }} ldapadd -Y EXTERNAL -H ldapi:/// -f {{ldif_docker_path}}configuration/02_member_of_configuration.ldif docker exec -i {{ applications | get_app_conf(application_id, 'hostname', True) }} ldapadd -Y EXTERNAL -H ldapi:/// -f {{openldap_ldif_docker_path}}configuration/02_member_of_configuration.ldif
listen: listen:
- "Import configuration LDIF files" - "Import configuration LDIF files"
- "Import all LDIF files" - "Import all LDIF files"
@ -22,7 +22,7 @@
- name: "Import schemas" - name: "Import schemas"
shell: > shell: >
docker exec -i {{ applications | get_app_conf(application_id, 'hostname', True) }} ldapadd -Y EXTERNAL -H ldapi:/// -f "{{ldif_docker_path}}schema/{{ item | basename | regex_replace('\.j2$', '') }}" docker exec -i {{ applications | get_app_conf(application_id, 'hostname', True) }} ldapadd -Y EXTERNAL -H ldapi:/// -f "{{openldap_ldif_docker_path}}schema/{{ item | basename | regex_replace('\.j2$', '') }}"
register: ldapadd_result register: ldapadd_result
changed_when: "'adding new entry' in ldapadd_result.stdout" changed_when: "'adding new entry' in ldapadd_result.stdout"
failed_when: ldapadd_result.rc not in [0, 80] failed_when: ldapadd_result.rc not in [0, 80]
@ -33,7 +33,7 @@
- name: Refint Overlay Configuration for OpenLDAP - name: Refint Overlay Configuration for OpenLDAP
shell: > shell: >
docker exec -i {{ applications | get_app_conf(application_id, 'hostname', True) }} ldapmodify -Y EXTERNAL -H ldapi:/// -f {{ldif_docker_path}}configuration/03_member_of_configuration.ldif docker exec -i {{ applications | get_app_conf(application_id, 'hostname', True) }} ldapmodify -Y EXTERNAL -H ldapi:/// -f {{openldap_ldif_docker_path}}configuration/03_member_of_configuration.ldif
listen: listen:
- "Import configuration LDIF files" - "Import configuration LDIF files"
- "Import all LDIF files" - "Import all LDIF files"
@ -45,7 +45,7 @@
- name: "Import users, groups, etc. to LDAP" - name: "Import users, groups, etc. to LDAP"
shell: > shell: >
docker exec -i {{ applications | get_app_conf(application_id, 'hostname', True) }} ldapadd -x -D "{{ldap.dn.administrator.data}}" -w "{{ldap.bind_credential}}" -c -f "{{ldif_docker_path}}data/{{ item | basename | regex_replace('\.j2$', '') }}" docker exec -i {{ applications | get_app_conf(application_id, 'hostname', True) }} ldapadd -x -D "{{ldap.dn.administrator.data}}" -w "{{ldap.bind_credential}}" -c -f "{{openldap_ldif_docker_path}}data/{{ item | basename | regex_replace('\.j2$', '') }}"
register: ldapadd_result register: ldapadd_result
changed_when: "'adding new entry' in ldapadd_result.stdout" changed_when: "'adding new entry' in ldapadd_result.stdout"
failed_when: ldapadd_result.rc not in [0, 20, 68, 65] failed_when: ldapadd_result.rc not in [0, 20, 68, 65]

View File

@ -4,7 +4,7 @@
- name: Ensure LDAP users exist - name: Ensure LDAP users exist
community.general.ldap_entry: community.general.ldap_entry:
dn: "{{ ldap.user.attributes.id }}={{ item.key }},{{ ldap.dn.ou.users }}" dn: "{{ ldap.user.attributes.id }}={{ item.key }},{{ ldap.dn.ou.users }}"
server_uri: "{{ ldap_server_uri }}" server_uri: "{{ openldap_server_uri }}"
bind_dn: "{{ ldap.dn.administrator.data }}" bind_dn: "{{ ldap.dn.administrator.data }}"
bind_pw: "{{ ldap.bind_credential }}" bind_pw: "{{ ldap.bind_credential }}"
objectClass: "{{ ldap.user.objects.structural }}" objectClass: "{{ ldap.user.objects.structural }}"
@ -30,7 +30,7 @@
- name: Ensure required objectClass values and mail address are present - name: Ensure required objectClass values and mail address are present
community.general.ldap_attrs: community.general.ldap_attrs:
dn: "{{ ldap.user.attributes.id }}={{ item.key }},{{ ldap.dn.ou.users }}" dn: "{{ ldap.user.attributes.id }}={{ item.key }},{{ ldap.dn.ou.users }}"
server_uri: "{{ ldap_server_uri }}" server_uri: "{{ openldap_server_uri }}"
bind_dn: "{{ ldap.dn.administrator.data }}" bind_dn: "{{ ldap.dn.administrator.data }}"
bind_pw: "{{ ldap.bind_credential }}" bind_pw: "{{ ldap.bind_credential }}"
attributes: attributes:
@ -46,7 +46,7 @@
- name: "Ensure container for application roles exists" - name: "Ensure container for application roles exists"
community.general.ldap_entry: community.general.ldap_entry:
dn: "{{ ldap.dn.ou.roles }}" dn: "{{ ldap.dn.ou.roles }}"
server_uri: "{{ ldap_server_uri }}" server_uri: "{{ openldap_server_uri }}"
bind_dn: "{{ ldap.dn.administrator.data }}" bind_dn: "{{ ldap.dn.administrator.data }}"
bind_pw: "{{ ldap.bind_credential }}" bind_pw: "{{ ldap.bind_credential }}"
objectClass: organizationalUnit objectClass: organizationalUnit

View File

@ -1,6 +1,6 @@
- name: Gather all users with their current objectClass list - name: Gather all users with their current objectClass list
community.general.ldap_search: community.general.ldap_search:
server_uri: "{{ ldap_server_uri }}" server_uri: "{{ openldap_server_uri }}"
bind_dn: "{{ ldap.dn.administrator.data }}" bind_dn: "{{ ldap.dn.administrator.data }}"
bind_pw: "{{ ldap.bind_credential }}" bind_pw: "{{ ldap.bind_credential }}"
dn: "{{ ldap.dn.ou.users }}" dn: "{{ ldap.dn.ou.users }}"
@ -14,7 +14,7 @@
- name: Add only missing auxiliary classes - name: Add only missing auxiliary classes
community.general.ldap_attrs: community.general.ldap_attrs:
server_uri: "{{ ldap_server_uri }}" server_uri: "{{ openldap_server_uri }}"
bind_dn: "{{ ldap.dn.administrator.data }}" bind_dn: "{{ ldap.dn.administrator.data }}"
bind_pw: "{{ ldap.bind_credential }}" bind_pw: "{{ ldap.bind_credential }}"
dn: "{{ item.dn }}" dn: "{{ item.dn }}"

View File

@ -1,7 +1,7 @@
- name: "Create LDIF files at {{ ldif_host_path }}{{ folder }}" - name: "Create LDIF files at {{ openldap_ldif_host_path }}{{ folder }}"
template: template:
src: "{{ item }}" src: "{{ item }}"
dest: "{{ ldif_host_path }}{{ folder }}/{{ item | basename | regex_replace('\\.j2$', '') }}" dest: "{{ openldap_ldif_host_path }}{{ folder }}/{{ item | basename | regex_replace('\\.j2$', '') }}"
mode: '770' mode: '770'
loop: >- loop: >-
{{ {{

View File

@ -22,14 +22,14 @@
name: "{{ applications | get_app_conf(application_id, 'network.name', True) }}" name: "{{ applications | get_app_conf(application_id, 'network.name', True) }}"
state: present state: present
ipam_config: ipam_config:
- subnet: "{{ networks.local['svc-db-openldap'].subnet }}" - subnet: "{{ networks.local[application_id].subnet }}"
- meta: flush_handlers - meta: flush_handlers
- name: "Wait for LDAP to be available" - name: "Wait for LDAP to be available"
wait_for: wait_for:
host: "127.0.0.1" host: "127.0.0.1"
port: "{{ ports.localhost.ldap['svc-db-openldap'] }}" port: "{{ ports.localhost.ldap[application_id] }}"
delay: 5 delay: 5
timeout: 120 timeout: 120
state: started state: started
@ -40,12 +40,12 @@
- applications | get_app_conf(application_id, 'network.local', True) - applications | get_app_conf(application_id, 'network.local', True)
- applications | get_app_conf(application_id, 'provisioning.credentials', True) - applications | get_app_conf(application_id, 'provisioning.credentials', True)
- name: "create directory {{ldif_host_path}}{{item}}" - name: "create directory {{openldap_ldif_host_path}}{{item}}"
file: file:
path: "{{ldif_host_path}}{{item}}" path: "{{openldap_ldif_host_path}}{{item}}"
state: directory state: directory
mode: 0755 mode: 0755
loop: "{{ldif_types}}" loop: "{{openldap_ldif_types}}"
- name: "Import LDIF Configuration" - name: "Import LDIF Configuration"
include_tasks: ldifs_creation.yml include_tasks: ldifs_creation.yml

View File

@ -13,9 +13,9 @@
- "( 1.3.6.1.4.1.99999.2 NAME 'nextcloudUser' DESC 'Auxiliary class for Nextcloud attributes' AUXILIARY MAY ( {{ ldap.user.attributes.nextcloud_quota }} ) )" - "( 1.3.6.1.4.1.99999.2 NAME 'nextcloudUser' DESC 'Auxiliary class for Nextcloud attributes' AUXILIARY MAY ( {{ ldap.user.attributes.nextcloud_quota }} ) )"
command: > command: >
ldapsm ldapsm
-s {{ ldap_server_uri }} -s {{ openldap_server_uri }}
-D '{{ ldap_bind_dn }}' -D '{{ openldap_bind_dn }}'
-W '{{ ldap_bind_pw }}' -W '{{ openldap_bind_pw }}'
-n {{ schema_name }} -n {{ schema_name }}
{% for at in attribute_defs %} {% for at in attribute_defs %}
-a "{{ at }}" -a "{{ at }}"

View File

@ -21,9 +21,9 @@
command: > command: >
ldapsm ldapsm
-s {{ ldap_server_uri }} -s {{ openldap_server_uri }}
-D '{{ ldap_bind_dn }}' -D '{{ openldap_bind_dn }}'
-W '{{ ldap_bind_pw }}' -W '{{ openldap_bind_pw }}'
-n {{ schema_name }} -n {{ schema_name }}
{% for at in attribute_defs %} {% for at in attribute_defs %}
-a "{{ at }}" -a "{{ at }}"

View File

@ -1,20 +1,20 @@
{% include 'roles/docker-compose/templates/base.yml.j2' %} {% include 'roles/docker-compose/templates/base.yml.j2' %}
application: application:
image: "{{ applications | get_app_conf(application_id, 'images.openldap', True) }}" image: "{{ openldap_image }}:{{ openldap_version }}"
container_name: {{ applications | get_app_conf(application_id, 'hostname', True) }} container_name: "{{ openldap_container }}"
{% include 'roles/docker-container/templates/base.yml.j2' %} {% include 'roles/docker-container/templates/base.yml.j2' %}
{% if applications | get_app_conf(application_id, 'network.public', True) | bool or applications | get_app_conf(application_id, 'network.local', True) | bool %} {% if openldap_network_expose_local %}
ports: ports:
- 127.0.0.1:{{ports.localhost.ldap['svc-db-openldap']}}:{{ldap_docker_port}} - 127.0.0.1:{{ports.localhost.ldap['svc-db-openldap']}}:{{openldap_docker_port_open}}
{% endif %} {% endif %}
volumes: volumes:
- 'data:/bitnami/openldap' - 'data:/bitnami/openldap'
- '{{ldif_host_path}}:{{ldif_docker_path}}:ro' - '{{openldap_ldif_host_path}}:{{openldap_ldif_docker_path}}:ro'
healthcheck: healthcheck:
test: > test: >
bash -c ' bash -c '
ldapsearch -x -H ldap://localhost:{{ ldap_docker_port }} \ ldapsearch -x -H ldap://localhost:{{ openldap_docker_port_open }} \
-D "{{ ldap.dn.administrator.data }}" -w "{{ ldap.bind_credential }}" -b "{{ ldap.dn.root }}" > /dev/null \ -D "{{ ldap.dn.administrator.data }}" -w "{{ ldap.bind_credential }}" -b "{{ ldap.dn.root }}" > /dev/null \
&& ldapsearch -Y EXTERNAL -H ldapi:/// \ && ldapsearch -Y EXTERNAL -H ldapi:/// \
-b cn=config "(&(objectClass=olcOverlayConfig)(olcOverlay=memberof))" \ -b cn=config "(&(objectClass=olcOverlayConfig)(olcOverlay=memberof))" \
@ -24,5 +24,6 @@
{% include 'roles/docker-compose/templates/volumes.yml.j2' %} {% include 'roles/docker-compose/templates/volumes.yml.j2' %}
data: data:
name: "{{ openldap_volume }}"
{% include 'roles/docker-compose/templates/networks.yml.j2' %} {% include 'roles/docker-compose/templates/networks.yml.j2' %}

View File

@ -18,9 +18,9 @@ LDAP_CONFIG_ADMIN_USERNAME= {{applications | get_app_conf(application_id, 'users
LDAP_CONFIG_ADMIN_PASSWORD= {{applications | get_app_conf(application_id, 'credentials.administrator_password', True)}} LDAP_CONFIG_ADMIN_PASSWORD= {{applications | get_app_conf(application_id, 'credentials.administrator_password', True)}}
# Network # Network
LDAP_PORT_NUMBER= {{ldap_docker_port}} # Route to default port LDAP_PORT_NUMBER= {{openldap_docker_port_open}} # Route to default port
LDAP_ENABLE_TLS= no # Using nginx proxy for tls LDAP_ENABLE_TLS= no # Using nginx proxy for tls
LDAP_LDAPS_PORT_NUMBER= {{ldaps_docker_port}} # Port used for TLS secure traffic. Priviledged port is supported (e.g. 636). Default: 1636 (non privileged port). LDAP_LDAPS_PORT_NUMBER= {{openldap_docker_port_secure}} # Port used for TLS secure traffic. Priviledged port is supported (e.g. 636). Default: 1636 (non privileged port).
# Security # Security
LDAP_ALLOW_ANON_BINDING= no # Allow anonymous bindings to the LDAP server. Default: yes. LDAP_ALLOW_ANON_BINDING= no # Allow anonymous bindings to the LDAP server. Default: yes.

View File

@ -1,17 +1,24 @@
application_id: "svc-db-openldap" application_id: "svc-db-openldap"
# LDAP Variables # LDAP Variables
ldaps_docker_port: 636 openldap_docker_port_secure: 636
ldap_docker_port: 389 openldap_docker_port_open: 389
ldap_server_uri: "ldap://127.0.0.1:{{ ports.localhost.ldap['svc-db-openldap'] }}" openldap_server_uri: "ldap://127.0.0.1:{{ ports.localhost.ldap[application_id] }}"
ldap_hostname: "{{ applications | get_app_conf(application_id, 'hostname', True) }}" openldap_hostname: "{{ applications | get_app_conf(application_id, 'hostname', True) }}"
ldap_bind_dn: "{{ ldap.dn.administrator.configuration }}" openldap_bind_dn: "{{ ldap.dn.administrator.configuration }}"
ldap_bind_pw: "{{ applications | get_app_conf(application_id, 'credentials.administrator_password', True) }}" openldap_bind_pw: "{{ applications | get_app_conf(application_id, 'credentials.administrator_password', True) }}"
# LDIF Variables # LDIF Variables
ldif_host_path: "{{docker_compose.directories.volumes}}ldif/" openldap_ldif_host_path: "{{docker_compose.directories.volumes}}ldif/"
ldif_docker_path: "/tmp/ldif/" openldap_ldif_docker_path: "/tmp/ldif/"
ldif_types: openldap_ldif_types:
- configuration - configuration
- data - data
- schema # Don't know if this is still needed, it's now setup via tasks - schema # Don't know if this is still needed, it's now setup via tasks
openldap_container: "{{ applications | get_app_conf(application_id, 'docker.services.openldap.container', True) }}"
openldap_image: "{{ applications | get_app_conf(application_id, 'docker.services.openldap.image', True) }}"
openldap_version: "{{ applications | get_app_conf(application_id, 'docker.services.openldap.version', True) }}"
openldap_volume: "{{ application_id }}_data"
openldap_network_expose_local: "{{ applications | get_app_conf(application_id, 'network.public', True) | bool or applications | get_app_conf(application_id, 'network.local', True) | bool }}"