diff --git a/config/ldap/schemas/10_opencloud_schema.ldif b/config/ldap/schemas/10_opencloud_schema.ldif new file mode 100644 index 0000000..faf2404 --- /dev/null +++ b/config/ldap/schemas/10_opencloud_schema.ldif @@ -0,0 +1,39 @@ +# This LDIF files describes the OpenCloud schema +dn: cn=opencloud,cn=schema,cn=config +objectClass: olcSchemaConfig +cn: opencloud +olcObjectIdentifier: openCloudOid 1.3.6.1.4.1.63016 +# We'll use openCloudOid:1 subarc for LDAP related stuff +# openCloudOid:1.1 for AttributeTypes and openCloudOid:1.2 for ObjectClasses +olcAttributeTypes: ( openCloudOid:1.1.1 NAME 'openCloudUUID' + DESC 'A non-reassignable and persistent account ID)' + EQUALITY uuidMatch + SUBSTR caseIgnoreSubstringsMatch + SYNTAX 1.3.6.1.1.16.1 SINGLE-VALUE ) +olcAttributeTypes: ( openCloudOid:1.1.2 NAME 'openCloudExternalIdentity' + DESC 'A triple separated by "$" representing the objectIdentity resource type of the Graph API ( signInType $ issuer $ issuerAssignedId )' + EQUALITY caseIgnoreMatch + SUBSTR caseIgnoreSubstringsMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +olcAttributeTypes: ( openCloudOid:1.1.3 NAME 'openCloudUserEnabled' + DESC 'A boolean value indicating if the user is enabled' + EQUALITY booleanMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE) +olcAttributeTypes: ( openCloudOid:1.1.4 NAME 'openCloudUserType' + DESC 'User type (e.g. Member or Guest)' + EQUALITY caseIgnoreMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +olcAttributeTypes: ( openCloudOid:1.1.5 NAME 'openCloudLastSignInTimestamp' + DESC 'The timestamp of the last sign-in' + EQUALITY generalizedTimeMatch + ORDERING generalizedTimeOrderingMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE ) +olcObjectClasses: ( openCloudOid:1.2.1 NAME 'openCloudObject' + DESC 'OpenCloud base objectclass' + AUXILIARY + MAY ( openCloudUUID ) ) +olcObjectClasses: ( openCloudOid:1.2.2 NAME 'openCloudUser' + DESC 'OpenCloud User objectclass' + SUP openCloudObject + AUXILIARY + MAY ( openCloudExternalIdentity $ openCloudUserEnabled $ openCloudUserType $ openCloudLastSignInTimestamp) ) diff --git a/idm/keycloak.yml b/idm/keycloak.yml new file mode 100644 index 0000000..d20570a --- /dev/null +++ b/idm/keycloak.yml @@ -0,0 +1,75 @@ +--- +services: + opencloud: + environment: + # Ldap IDP specific configuration + OC_LDAP_URI: ldaps://ldap-server:1636 + OC_LDAP_INSECURE: "true" + OC_LDAP_BIND_DN: "cn=admin,dc=opencloud,dc=eu" + OC_LDAP_BIND_PASSWORD: ${LDAP_BIND_PASSWORD:-admin} + OC_LDAP_GROUP_BASE_DN: "ou=groups,dc=opencloud,dc=eu" + OC_LDAP_USER_BASE_DN: "ou=users,dc=opencloud,dc=eu" + OC_LDAP_USER_FILTER: "(objectclass=inetOrgPerson)" + GRAPH_LDAP_SERVER_UUID: "false" + GRAPH_LDAP_GROUP_CREATE_BASE_DN: "ou=custom,ou=groups,dc=opencloud,dc=eu" + GRAPH_LDAP_REFINT_ENABLED: "true" # osixia has refint enabled. + FRONTEND_READONLY_USER_ATTRIBUTES: "user.onPremisesSamAccountName,user.displayName,user.mail,user.passwordProfile,user.accountEnabled,user.appRoleAssignments" + PROXY_OIDC_REWRITE_WELLKNOWN: "true" + WEB_OIDC_CLIENT_ID: ${OC_OIDC_CLIENT_ID:-web} + PROXY_ROLE_ASSIGNMENT_DRIVER: "oidc" + OC_OIDC_ISSUER: https://${KEYCLOAK_DOMAIN:-keycloak.opencloud.test}/realms/openCloud + # This specifies to start all services except idm and idp. These are replaced by external services. + OC_EXCLUDE_RUN_SERVICES: idm,idp + # Keycloak IDP specific configuration for auto-provisioning + OC_LDAP_SERVER_WRITE_ENABLED: "true" + PROXY_AUTOPROVISION_ACCOUNTS: "true" + # Use the `sub` claim from keycloak for the user ID + # Keycloak uses the keycloak user ID as the `sub` claim + PROXY_USER_OIDC_CLAIM: "sub" + # Use the `sub` claim as identifier during autoprovisioning + # That mitigates problems when a user is renamed in keycloak + PROXY_AUTOPROVISION_CLAIM_USERNAME: "sub" + PROXY_USER_CS3_CLAIM: "username" + # This is the default value, we need to set it here because we overwrite the values + OC_LDAP_USER_SCHEMA_ID: "opencloudUUID" + # This is the default value, we need to set it here because we overwrite the values + OC_LDAP_GROUP_SCHEMA_ID: "opencloudUUID" + # This is the default value, we need to set it here because we overwrite the values + OC_LDAP_DISABLE_USER_MECHANISM: "attribute" + OC_ADMIN_USER_ID: "" + SETTINGS_SETUP_DEFAULT_ASSIGNMENTS: "false" + GRAPH_ASSIGN_DEFAULT_USER_ROLE: "false" + GRAPH_USERNAME_MATCH: "none" + IDP_DOMAIN: ${KEYCLOAK_DOMAIN:-keycloak.opencloud.test} + ldap-server: + image: bitnami/openldap:2.6 + networks: + opencloud-net: + entrypoint: [ "/bin/sh", "/opt/bitnami/scripts/openldap/docker-entrypoint-override.sh", "/opt/bitnami/scripts/openldap/run.sh" ] + environment: + BITNAMI_DEBUG: true + LDAP_TLS_VERIFY_CLIENT: never + LDAP_ENABLE_TLS: "yes" + LDAP_TLS_CA_FILE: /opt/bitnami/openldap/share/openldap.crt + LDAP_TLS_CERT_FILE: /opt/bitnami/openldap/share/openldap.crt + LDAP_TLS_KEY_FILE: /opt/bitnami/openldap/share/openldap.key + LDAP_ROOT: "dc=opencloud,dc=eu" + LDAP_ADMIN_PASSWORD: ${LDAP_BIND_PASSWORD:-admin} + ports: + - "127.0.0.1:389:1389" + - "127.0.0.1:636:1636" + volumes: + # Only use the base ldif file to create the base structure + - ./config/ldap/ldif/10_base.ldif:/ldifs/10_base.ldif + # Use the custom schema from opencloud because we are in full control of the ldap server + - ./config/ldap/schemas/10_opencloud_schema.ldif:/schemas/10_opencloud_schema.ldif + - ./config/ldap/docker-entrypoint-override.sh:/opt/bitnami/scripts/openldap/docker-entrypoint-override.sh + - ldap-certs:/opt/bitnami/openldap/share + - ldap-data:/bitnami/openldap + keycloak: + volumes: + - "./config/keycloak/docker-entrypoint-override.sh:/opt/keycloak/bin/docker-entrypoint-override.sh" + - "./config/keycloak/opencloud-realm-autoprovisioning.dist.json:/opt/keycloak/data/import-dist/opencloud-realm.json" +volumes: + ldap-certs: + ldap-data: diff --git a/testing/external-keycloak.yml b/testing/external-keycloak.yml new file mode 100644 index 0000000..378e99a --- /dev/null +++ b/testing/external-keycloak.yml @@ -0,0 +1,44 @@ +--- +services: + postgres: + image: postgres:alpine + networks: + opencloud-net: + volumes: + - keycloak_postgres_data:/var/lib/postgresql/data + environment: + POSTGRES_DB: keycloak + POSTGRES_USER: ${KC_DB_USERNAME:-keycloak} + POSTGRES_PASSWORD: ${KC_DB_PASSWORD:-keycloak} + logging: + driver: ${LOG_DRIVER:-local} + restart: always + + keycloak: + image: quay.io/keycloak/keycloak:25.0.0 + networks: + opencloud-net: + command: [ "start", "--proxy=edge", "--spi-connections-http-client-default-disable-trust-manager=${INSECURE:-false}", "--import-realm" ] + entrypoint: [ "/bin/sh", "/opt/keycloak/bin/docker-entrypoint-override.sh" ] + volumes: + - "./config/keycloak/docker-entrypoint-override.sh:/opt/keycloak/bin/docker-entrypoint-override.sh" + - "./config/keycloak/opencloud-realm-autoprovisioning.dist.json:/opt/keycloak/data/import-dist/opencloud-realm.json" + - "./config/keycloak/themes/opencloud:/opt/keycloak/themes/opencloud" + environment: + OC_DOMAIN: ${OC_DOMAIN:-cloud.opencloud.test} + KC_HOSTNAME: ${KEYCLOAK_DOMAIN:-keycloak.opencloud.test} + KC_DB: postgres + KC_DB_URL: "jdbc:postgresql://postgres:5432/keycloak" + KC_DB_USERNAME: ${KC_DB_USERNAME:-keycloak} + KC_DB_PASSWORD: ${KC_DB_PASSWORD:-keycloak} + KC_FEATURES: impersonation + KEYCLOAK_ADMIN: ${KEYCLOAK_ADMIN:-kcadmin} + KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD:-admin} + depends_on: + - postgres + logging: + driver: ${LOG_DRIVER:-local} + restart: always + +volumes: + keycloak_postgres_data: diff --git a/testing/ldap-manager.yml b/testing/ldap-manager.yml new file mode 100644 index 0000000..5626ea0 --- /dev/null +++ b/testing/ldap-manager.yml @@ -0,0 +1,24 @@ +--- +# This file can be used to be added to the opencloud_full example +# to browse the LDAP server with a web interface. +# This is not a production ready setup. +services: + ldap-manager: + image: phpldapadmin/phpldapadmin:latest + networks: + opencloud-net: + environment: + LDAP_HOST: ldap-server + LDAP_PORT: 1389 + LDAP_LOGIN_OBJECTCLASS: "inetOrgPerson" + APP_URL: "https://${LDAP_MANAGER_DOMAIN:-ldap.opencloud.test}" + labels: + - "traefik.enable=true" + - "traefik.http.routers.ldap-manager.entrypoints=https" + - "traefik.http.routers.ldap-manager.rule=Host(`${LDAP_MANAGER_DOMAIN:-ldap.opencloud.test}`)" + - "traefik.http.routers.ldap-manager.tls.certresolver=letsencrypt" + - "traefik.http.routers.ldap-manager.service=ldap-manager" + - "traefik.http.services.ldap-manager.loadbalancer.server.port=8080" + logging: + driver: ${LOG_DRIVER:-local} + restart: always \ No newline at end of file