From 3fe83f26d524cbfaff3abd809dbe3534b95c60ed Mon Sep 17 00:00:00 2001 From: Kevin Veen-Birkenbach Date: Thu, 27 Nov 2025 10:46:32 +0100 Subject: [PATCH] SuiteCRM: Implement and activate full LDAP authentication support - Removed legacy SugarCRM LDAP config generation - Implemented Symfony/SuiteCRM 8 native LDAP ENV configuration - Added auto-creation provider settings - Added trusted proxy + host configuration for correct HTTPS handling - Added automatic domain-based TRUSTED_HOSTS generation - Ensured cache is cleared/warmed up on container start - Verified LDAP authentication now works as expected Conversation reference: https://chatgpt.com/share/69281db4-4ff4-800f-8577-77e20120e09a --- .../files/docker-entrypoint-suitecrm.sh | 33 ++++--------- roles/web-app-suitecrm/templates/env.j2 | 47 +++++++++++++++---- roles/web-app-suitecrm/vars/main.yml | 1 + 3 files changed, 49 insertions(+), 32 deletions(-) diff --git a/roles/web-app-suitecrm/files/docker-entrypoint-suitecrm.sh b/roles/web-app-suitecrm/files/docker-entrypoint-suitecrm.sh index a57e2eba..e9c40a0c 100644 --- a/roles/web-app-suitecrm/files/docker-entrypoint-suitecrm.sh +++ b/roles/web-app-suitecrm/files/docker-entrypoint-suitecrm.sh @@ -9,7 +9,7 @@ INSTALL_FLAG="${APP_DIR}/public/installed.flag" log() { printf '%s %s\n' "[suitecrm-entrypoint]" "$*" >&2; } ############################################ -# 1) Sanity Checks +# Sanity Checks ############################################ if [ ! -d "$APP_DIR" ]; then log "ERROR: Application directory '$APP_DIR' does not exist." @@ -17,7 +17,7 @@ if [ ! -d "$APP_DIR" ]; then fi ############################################ -# 2) Permissions +# Permissions ############################################ log "Adjusting file permissions..." chown -R "$WEB_USER:$WEB_GROUP" "$APP_DIR" @@ -38,7 +38,7 @@ chown -R "$WEB_USER:$WEB_GROUP" "$TMPDIR" chmod 775 "$TMPDIR" ############################################ -# 3) Auto-Install SuiteCRM (only if not yet installed) +# Auto-Install SuiteCRM (only if not yet installed) ############################################ if [ ! -f "$INSTALL_FLAG" ]; then log "SuiteCRM 8 is not installed — performing automated installation..." @@ -65,35 +65,20 @@ else fi ############################################ -# 4) LDAP Auto-Configuration (legacy backend) +# Clear Symfony Cache ############################################ -if [ "${AUTH_TYPE:-disabled}" = "ldap" ]; then - log "Writing LDAP configuration to config_override.php" - - cat > "${APP_DIR}/public/legacy/config_override.php" < "${APP_DIR}/public/healthcheck.html" chown "$WEB_USER:$WEB_GROUP" "${APP_DIR}/public/healthcheck.html" ############################################ -# 6) Start Apache +# Start Apache ############################################ log "Starting apache2-foreground..." exec apache2-foreground diff --git a/roles/web-app-suitecrm/templates/env.j2 b/roles/web-app-suitecrm/templates/env.j2 index 2a85d3f0..4c4edb28 100644 --- a/roles/web-app-suitecrm/templates/env.j2 +++ b/roles/web-app-suitecrm/templates/env.j2 @@ -7,7 +7,12 @@ # Core Symfony / SuiteCRM 8 settings # ------------------------------------------------ APP_ENV={{ 'dev' if (ENVIRONMENT | lower) == 'development' else 'prod' }} -APP_DEBUG="{{ MODE_DEBUG | bool| ternary(1, 0) }}" +APP_DEBUG="{{ MODE_DEBUG | bool | ternary(1, 0) }}" + +# Use correct HTTPS Scheme +SERVER_SCHEME="{{ WEB_PROTOCOL }}" +TRUSTED_PROXIES="127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16" +TRUSTED_HOSTS="^{{ domain | replace('.', '\\\\.') }}$" # ------------------------------------------------ # Database (Symfony-style) @@ -44,19 +49,45 @@ SUITECRM_SMTP_PROTOCOL={{ "TLS" if SYSTEM_EMAIL.START_TLS else "SSL" }} SUITECRM_EMAIL_FROM_NAME={{ applications | get_app_conf(application_id, 'email.from_name') }} # ------------------------------------------------ -# LDAP settings (native SuiteCRM 8 / Symfony) +# LDAP settings (legacy + SuiteCRM 8 / Symfony) # ------------------------------------------------ {% if SUITECRM_LDAP_ENABLED | bool %} AUTH_TYPE=ldap + +# Autocreate +LDAP_AUTO_CREATE=enabled +LDAP_PROVIDER_BASE_DN='{{ LDAP.DN.OU.USERS }}' +LDAP_PROVIDER_SEARCH_DN='{{ LDAP.DN.ADMINISTRATOR.DATA }}' +LDAP_PROVIDER_SEARCH_PASSWORD='{{ LDAP.BIND_CREDENTIAL }}' +LDAP_PROVIDER_DEFAULT_ROLES=ROLE_USER +LDAP_PROVIDER_UID_KEY='{{ LDAP.USER.ATTRIBUTES.ID }}' +LDAP_PROVIDER_FILTER='{{ LDAP.USER.ATTRIBUTES.ID }}={username}' + +# Debug +LDAP_CONNECTION_OPTION_DEBUG_LEVEL="{{ MODE_DEBUG | bool | ternary(7, 0) }}" + +# ---- Common (for your tooling / consistency) ---- LDAP_HOST={{ LDAP.SERVER.DOMAIN }} LDAP_PORT={{ LDAP.SERVER.PORT }} -LDAP_ENCRYPTION={{ LDAP.SERVER.SECURITY | lower if LDAP.SERVER.SECURITY else "none" }} -LDAP_BASE_DN={{ LDAP.DN.OU.USERS }} -LDAP_BIND_DN={{ LDAP.DN.ADMINISTRATOR.DATA }} -LDAP_BIND_PASSWORD={{ LDAP.BIND_CREDENTIAL }} -LDAP_UID_KEY={{ LDAP.USER.ATTRIBUTES.ID }} +LDAP_ENCRYPTION={{ (LDAP.SERVER.SECURITY | default('none', true) ) | lower }} + +# ---- SuiteCRM 8 / Symfony LDAP (per official docs) ---- +#LDAP_CONNECTION_STRING= +LDAP_PROTOCOL_VERSION=3 +LDAP_REFERRALS=false + +# Base DN under which users are searched +LDAP_DN_STRING="{{ LDAP.DN.OU.USERS }}" + +# Search filter with {username} placeholder +LDAP_QUERY_STRING="{{ LDAP.USER.ATTRIBUTES.ID }}={username}" + +# Bind DN used to perform the search +LDAP_SEARCH_DN="{{ LDAP.DN.ADMINISTRATOR.DATA }}" +LDAP_SEARCH_PASSWORD="{{ LDAP.BIND_CREDENTIAL }}" + {% else %} -AUTH_TYPE=disabled +AUTH_TYPE=native {% endif %} # ------------------------------------------------ diff --git a/roles/web-app-suitecrm/vars/main.yml b/roles/web-app-suitecrm/vars/main.yml index b6fe01c1..670c1be1 100644 --- a/roles/web-app-suitecrm/vars/main.yml +++ b/roles/web-app-suitecrm/vars/main.yml @@ -1,6 +1,7 @@ # General application_id: "web-app-suitecrm" entity_name: "{{ application_id | get_entity_name }}" +domain: "{{ domains | get_domain(application_id) }}" # Database database_type: "mariadb"