Redesigned LDAP (DRAFT)

This commit is contained in:
Kevin Veen-Birkenbach 2025-02-21 00:26:33 +01:00
parent a39f1914ea
commit 07beddb5a2
14 changed files with 115 additions and 87 deletions

View File

@ -37,16 +37,18 @@ ldap:
# Distinguished Names (DN)
dn:
# Defines the base Distinguished Name (DN) for the LDAP directory, constructed from the second-level domain (SLD) and top-level domain (TLD).
root: "{{_ldap_dn_base}}"
root: "{{_ldap_dn_base}}"
# Specifies the Distinguished Name (DN) of the LDAP administrator, combining the admin's username with the LDAP root domain.
bind: "cn={{applications.ldap.administrator_username}},{{_ldap_dn_base}}"
bind: "cn={{applications.ldap.administrator_username}},{{_ldap_dn_base}}"
# Dn from which the users should be read
users: "ou=users,{{_ldap_dn_base}}"
users: "ou=users,{{_ldap_dn_base}}"
# Dn for all application roles of the users
application_roles: "ou=application_roles,{{_ldap_dn_base}}"
# Password to access dn.bind
bind_credential: "{{applications.ldap.administrator_database_password}}"
bind_credential: "{{applications.ldap.administrator_database_password}}"
server:
domain: "{{applications.ldap.openldap.hostname if applications.ldap.openldap.network.local | bool else domains.ldap}}" # Mapping for public or locale access
uri: "{% if applications.ldap.openldap.network.local | bool %}ldap://{{ applications.ldap.openldap.hostname }}:{{ ports.localhost.ldap.openldap }}{% else %}ldaps://{{ domains.ldap }}:{{ ports.public.ldaps.openldap }}{% endif %}"
domain: "{{applications.ldap.openldap.hostname if applications.ldap.openldap.network.local | bool else domains.ldap}}" # Mapping for public or locale access
uri: "{% if applications.ldap.openldap.network.local | bool %}ldap://{{ applications.ldap.openldap.hostname }}:{{ ports.localhost.ldap.openldap }}{% else %}ldaps://{{ domains.ldap }}:{{ ports.public.ldaps.openldap }}{% endif %}"
network:
local: "{{applications.ldap.openldap.network.local}}" # Uses the application configuration to define if local network should be available or not
local: "{{applications.ldap.openldap.network.local}}" # Uses the application configuration to define if local network should be available or not

View File

@ -36,6 +36,7 @@ docker exec -it openldap bash -c "ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b 'c
### MemberOf
```bash
# Activate
ldapmodify -Y EXTERNAL -H ldapi:/// <<EOF
dn: cn=module{0},cn=config
changetype: modify
@ -43,6 +44,9 @@ add: olcModuleLoad
olcModuleLoad: /opt/bitnami/openldap/lib/openldap/memberof.so
EOF
# Verify
ldapsearch -Q -Y EXTERNAL -H ldapi:/// -b "cn=module{0},cn=config" olcModuleLoad
ldapadd -Y EXTERNAL -H ldapi:/// <<EOF
dn: olcOverlay=memberof,olcDatabase={2}mdb,cn=config
objectClass: olcOverlayConfig
@ -104,6 +108,8 @@ The following directories are mounted in the container:
- [Bitnami OpenLDAP](https://hub.docker.com/r/bitnami/openldap)
- [phpLDAPadmin Documentation](https://github.com/leenooks/phpLDAPadmin/wiki/Docker-Container)
- [LDAP Account Manager](https://github.com/LDAPAccountManager/docker)
- [RBAC](https://www.entrust.com/de/resources/learn/what-is-role-based-access-control#:~:text=Rollenbasierte%20Zugriffskontrolle%20(Role%2Dbased%20Access,eine%20Ressource%20gew%C3%A4hrt%20werden%20soll.)
- [RBAC Wikipedia](https://de.wikipedia.org/wiki/Role_Based_Access_Control)
---

View File

@ -2,6 +2,7 @@
shell: >
docker exec -i openldap ldapmodify -Y EXTERNAL -H ldapi:/// -f {{ldif_docker_path}}01_member_of_configuration.ldif
listen: "Import LDIF files"
ignore_errors: true # @todo check if this works
- name: Refint Module Activation for OpenLDAP
shell: >
@ -9,6 +10,7 @@
listen: "Import LDIF files"
register: ldapadd_result
failed_when: ldapadd_result.rc not in [0, 68]
ignore_errors: true # @todo check if this works
- name: Refint Overlay Configuration for OpenLDAP
shell: >
@ -16,12 +18,15 @@
listen: "Import LDIF files"
register: ldapadd_result
failed_when: ldapadd_result.rc not in [0, 68]
ignore_errors: true # @todo check if this works
- name: "Import Access Roles to OpenLDAP"
- name: "Import users, groups, etc. to LDAP"
shell: >
docker exec -i openldap ldapadd -x -D "{{ldap.dn.bind}}" -w "{{ldap.bind_credential}}" -c -f "{{ldif_docker_path}}04_access_profiles.ldif"
docker exec -i openldap ldapadd -x -D "{{ldap.dn.bind}}" -w "{{ldap.bind_credential}}" -c -f "{{ldif_docker_path}}/import/{{ item | basename | regex_replace('\\.j2$', '') }}"
register: ldapadd_result
changed_when: "'adding new entry' in ldapadd_result.stdout"
# Allow return code 0 (all entries added) or 68 (entry already exists)
failed_when: ldapadd_result.rc not in [0, 68]
listen: "Import LDIF files"
listen: "Import LDIF files"
ignore_errors: true
loop: "{{ lookup('fileglob', role_path ~ '/templates/ldif/import/*.j2', wantlist=True) }}"

View File

@ -0,0 +1,7 @@
- name: "Create LDIF files at {{ ldif_host_path }}/{{ folder }}"
template:
src: "{{ item }}"
dest: "{{ ldif_host_path }}/{{ folder }}/{{ item | basename | regex_replace('\\.j2$', '') }}"
mode: '770'
loop: "{{ lookup('fileglob', role_path ~ '/templates/ldif/' ~ folder ~ '/*.j2', wantlist=True) }}"
notify: Import LDIF files

View File

@ -51,19 +51,18 @@
- name: flush docker service
meta: flush_handlers
- name: "create directory {{ldif_host_path}}"
- name: "create directory {{ldif_host_path}}{{item}}"
file:
path: "{{ldif_host_path}}"
path: "{{ldif_host_path}}{{item}}"
state: directory
mode: 0755
loop: "{{ldif_types}}"
- name: "Create LDIF files at {{ ldif_host_path }}"
template:
src: "{{ item }}"
dest: "{{ ldif_host_path }}/{{ item | basename | regex_replace('\\.j2$', '') }}"
mode: '770'
loop: "{{ lookup('fileglob', '{{ role_path }}/templates/ldif/*.j2', wantlist=True) }}"
notify: Import LDIF files
- name: "Process all LDIF types"
include_tasks: create_ldif_files.yml
loop: "{{ ldif_types }}"
loop_control:
loop_var: folder
- name: Force LDIF files import
command: /bin/true

View File

@ -1,57 +0,0 @@
#######################################################################
# This file contains the CyMaIS default roles (converted to posix groups)
# Roles define which kind of rights users have.
#######################################################################
#######################################################################
# Generic container for IT roles
#######################################################################
dn: {{dn_roles}}
objectClass: organizationalUnit
ou: roles
description: Container for IT access profiles (for rights management)
#######################################################################
# Role: Super Administrator
#######################################################################
dn: cn=superadministrator,{{dn_roles}}
objectClass: posixGroup
cn: superadministrator
gidNumber: 1000
description: Role: Super Administrator has full control over all systems and settings.
#######################################################################
# Role: Administrator
#######################################################################
dn: cn=administrator,{{dn_roles}}
objectClass: posixGroup
cn: administrator
gidNumber: 1001
description: Role: Administrator responsible for overall system management and configuration.
#######################################################################
# Role: Manager
#######################################################################
dn: cn=manager,{{dn_roles}}
objectClass: posixGroup
cn: manager
gidNumber: 1002
description: Role: Manager oversees operations, approves changes, and coordinates teams.
#######################################################################
# Role: Moderator
#######################################################################
dn: cn=moderator,{{dn_roles}}
objectClass: posixGroup
cn: moderator
gidNumber: 1003
description: Role: Moderator monitors activity and handles conflict resolution.
#######################################################################
# Role: User
#######################################################################
dn: cn=user,{{dn_roles}}
objectClass: posixGroup
cn: user
gidNumber: 1004
description: Role: User - Uses the software

View File

@ -0,0 +1 @@
This folder contains configuration files where a specific logic needs to be applied.

View File

@ -0,0 +1,29 @@
#######################################################################
# Generic container for Application roles
#######################################################################
dn: {{ldap.dn.application_roles}}
objectClass: organizationalUnit
ou: roles
description: Container for application access profiles
{#
This template generates two LDIF entries for each application in defaults_applications:
one for the administrator role and one for the standard user role.
Please adjust the base DN (dc=example,dc=com) and other attributes as necessary.
#}
{% for app, config in defaults_applications.items() %}
dn: cn={{ app }}-administrator,{{ldap.dn.application_roles}}
objectClass: top
objectClass: organizationalRole
cn: {{ app }}-administrator
description: Administrator role for {{ app }} (automatically generated)
dn: cn={{ app }}-user,{{ldap.dn.application_roles}}
objectClass: top
objectClass: organizationalRole
cn: {{ app }}-user
description: Standard user role for {{ app }} (automatically generated)
{% endfor %}

View File

@ -0,0 +1,39 @@
#######################################################################
# Container for Application Roles (if not already created)
#######################################################################
dn: {{ ldap.dn.application_roles }}
objectClass: organizationalUnit
ou: roles
description: Container for application access profiles
#######################################################################
# Create Admin User
#######################################################################
dn: uid={{administrator_username}},{{ldap.dn.users}}
objectClass: top
objectClass: inetOrgPerson
objectClass: posixAccount
uid: {{administrator_username}}
sn: Administrator
cn: Administrator
userPassword: {SSHA}CHANGE_THIS_PASSWORD
loginShell: /bin/bash
homeDirectory: /home/admin
#######################################################################
# Add Admin User to All Application Role Groups
#######################################################################
{# Loop over each application defined in defaults_applications #}
{% for app, config in defaults_applications.items() %}
dn: cn={{ app }}-administrator,{{ ldap.dn.application_roles }}
changetype: modify
add: roleOccupant
roleOccupant: uid={{administrator_username}},{{ldap.dn.users}}
dn: cn={{ app }}-user,{{ ldap.dn.application_roles }}
changetype: modify
add: roleOccupant
roleOccupant: uid={{administrator_username}},{{ldap.dn.users}}
{% endfor %}

View File

@ -0,0 +1 @@
This folder contains files which are importet via ldapadd without any specific logic

View File

@ -2,15 +2,11 @@ application_id: "ldap"
ldaps_docker_port: 636
ldap_docker_port: 389
enable_wildcard_certificate: false # Activate dedicated Certificate
enable_wildcard_certificate: false # Deactivate dedicated Certificate
# Configuration for ldif import
ldif_files:
- "01_member_of_configuration.ldif"
- "02_member_of_configuration.ldif"
- "03_member_of_configuration.ldif"
- "04_access_profiles.ldif"
ldif_host_path: "{{docker_compose.directories.volumes}}ldif/"
ldif_docker_path: "/tmp/ldif/"
dn_roles: "ou=access_roles,{{ldap.dn.root}}"
ldif_host_path: "{{docker_compose.directories.volumes}}ldif/"
ldif_docker_path: "/tmp/ldif/"
ldap.dn.application_roles: "ou=application_roles,{{ldap.dn.root}}"
ldif_types:
- configuration
- import