From 07beddb5a2d147e7f6251c3af01a8aef2067c37a Mon Sep 17 00:00:00 2001 From: Kevin Veen-Birkenbach Date: Fri, 21 Feb 2025 00:26:33 +0100 Subject: [PATCH] Redesigned LDAP (DRAFT) --- group_vars/all/11_iam.yml | 16 +++--- roles/docker-ldap/README.md | 6 ++ roles/docker-ldap/handlers/main.yml | 11 +++- roles/docker-ldap/tasks/create_ldif_files.yml | 7 +++ roles/docker-ldap/tasks/main.yml | 17 +++--- .../templates/ldif/04_access_roles.ldif.j2 | 57 ------------------- .../01_member_of_configuration.ldif.j2 | 0 .../02_member_of_configuration.ldif.j2 | 0 .../03_member_of_configuration.ldif.j2 | 0 .../templates/ldif/configuration/README.md | 1 + .../ldif/import/01_application_roles.ldif.j2 | 29 ++++++++++ .../templates/ldif/import/02_users.ldif.j2 | 39 +++++++++++++ .../templates/ldif/import/README.md | 1 + roles/docker-ldap/vars/main.yml | 18 +++--- 14 files changed, 115 insertions(+), 87 deletions(-) create mode 100644 roles/docker-ldap/tasks/create_ldif_files.yml delete mode 100644 roles/docker-ldap/templates/ldif/04_access_roles.ldif.j2 rename roles/docker-ldap/templates/ldif/{ => configuration}/01_member_of_configuration.ldif.j2 (100%) rename roles/docker-ldap/templates/ldif/{ => configuration}/02_member_of_configuration.ldif.j2 (100%) rename roles/docker-ldap/templates/ldif/{ => configuration}/03_member_of_configuration.ldif.j2 (100%) create mode 100644 roles/docker-ldap/templates/ldif/configuration/README.md create mode 100644 roles/docker-ldap/templates/ldif/import/01_application_roles.ldif.j2 create mode 100644 roles/docker-ldap/templates/ldif/import/02_users.ldif.j2 create mode 100644 roles/docker-ldap/templates/ldif/import/README.md diff --git a/group_vars/all/11_iam.yml b/group_vars/all/11_iam.yml index 82ac8cbc..7f81a08f 100644 --- a/group_vars/all/11_iam.yml +++ b/group_vars/all/11_iam.yml @@ -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 \ No newline at end of file diff --git a/roles/docker-ldap/README.md b/roles/docker-ldap/README.md index 289eca8e..e242a646 100644 --- a/roles/docker-ldap/README.md +++ b/roles/docker-ldap/README.md @@ -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:/// < 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" \ No newline at end of file + listen: "Import LDIF files" + ignore_errors: true + loop: "{{ lookup('fileglob', role_path ~ '/templates/ldif/import/*.j2', wantlist=True) }}" \ No newline at end of file diff --git a/roles/docker-ldap/tasks/create_ldif_files.yml b/roles/docker-ldap/tasks/create_ldif_files.yml new file mode 100644 index 00000000..c46b5a3b --- /dev/null +++ b/roles/docker-ldap/tasks/create_ldif_files.yml @@ -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 diff --git a/roles/docker-ldap/tasks/main.yml b/roles/docker-ldap/tasks/main.yml index d45dcd45..1507a576 100644 --- a/roles/docker-ldap/tasks/main.yml +++ b/roles/docker-ldap/tasks/main.yml @@ -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 diff --git a/roles/docker-ldap/templates/ldif/04_access_roles.ldif.j2 b/roles/docker-ldap/templates/ldif/04_access_roles.ldif.j2 deleted file mode 100644 index 1c5f0a6c..00000000 --- a/roles/docker-ldap/templates/ldif/04_access_roles.ldif.j2 +++ /dev/null @@ -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 \ No newline at end of file diff --git a/roles/docker-ldap/templates/ldif/01_member_of_configuration.ldif.j2 b/roles/docker-ldap/templates/ldif/configuration/01_member_of_configuration.ldif.j2 similarity index 100% rename from roles/docker-ldap/templates/ldif/01_member_of_configuration.ldif.j2 rename to roles/docker-ldap/templates/ldif/configuration/01_member_of_configuration.ldif.j2 diff --git a/roles/docker-ldap/templates/ldif/02_member_of_configuration.ldif.j2 b/roles/docker-ldap/templates/ldif/configuration/02_member_of_configuration.ldif.j2 similarity index 100% rename from roles/docker-ldap/templates/ldif/02_member_of_configuration.ldif.j2 rename to roles/docker-ldap/templates/ldif/configuration/02_member_of_configuration.ldif.j2 diff --git a/roles/docker-ldap/templates/ldif/03_member_of_configuration.ldif.j2 b/roles/docker-ldap/templates/ldif/configuration/03_member_of_configuration.ldif.j2 similarity index 100% rename from roles/docker-ldap/templates/ldif/03_member_of_configuration.ldif.j2 rename to roles/docker-ldap/templates/ldif/configuration/03_member_of_configuration.ldif.j2 diff --git a/roles/docker-ldap/templates/ldif/configuration/README.md b/roles/docker-ldap/templates/ldif/configuration/README.md new file mode 100644 index 00000000..b970835a --- /dev/null +++ b/roles/docker-ldap/templates/ldif/configuration/README.md @@ -0,0 +1 @@ +This folder contains configuration files where a specific logic needs to be applied. \ No newline at end of file diff --git a/roles/docker-ldap/templates/ldif/import/01_application_roles.ldif.j2 b/roles/docker-ldap/templates/ldif/import/01_application_roles.ldif.j2 new file mode 100644 index 00000000..0d63a2fb --- /dev/null +++ b/roles/docker-ldap/templates/ldif/import/01_application_roles.ldif.j2 @@ -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 %} diff --git a/roles/docker-ldap/templates/ldif/import/02_users.ldif.j2 b/roles/docker-ldap/templates/ldif/import/02_users.ldif.j2 new file mode 100644 index 00000000..984b65e1 --- /dev/null +++ b/roles/docker-ldap/templates/ldif/import/02_users.ldif.j2 @@ -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 %} diff --git a/roles/docker-ldap/templates/ldif/import/README.md b/roles/docker-ldap/templates/ldif/import/README.md new file mode 100644 index 00000000..cd7c375f --- /dev/null +++ b/roles/docker-ldap/templates/ldif/import/README.md @@ -0,0 +1 @@ +This folder contains files which are importet via ldapadd without any specific logic \ No newline at end of file diff --git a/roles/docker-ldap/vars/main.yml b/roles/docker-ldap/vars/main.yml index 655b0b51..435d37b2 100644 --- a/roles/docker-ldap/vars/main.yml +++ b/roles/docker-ldap/vars/main.yml @@ -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}}" \ No newline at end of file +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 \ No newline at end of file