diff --git a/apps/opencloud/OPENLDAP_DEPLOYMENT.md b/apps/opencloud/OPENLDAP_DEPLOYMENT.md deleted file mode 100644 index 3365068..0000000 --- a/apps/opencloud/OPENLDAP_DEPLOYMENT.md +++ /dev/null @@ -1,257 +0,0 @@ -# OpenCloud with External OpenLDAP Deployment Guide - -## Architecture Overview - -This deployment uses: -- **External OpenLDAP** for user/group storage -- **Pocket ID** (auth.basicstack.de) for authentication via OIDC -- **OpenCloud** as the file storage platform - -### Authentication Flow - -1. User accesses `https://opencloud.basicstack.de` -2. OpenCloud redirects to Pocket ID for authentication -3. User logs in at `https://auth.basicstack.de` -4. Pocket ID returns OIDC token to OpenCloud -5. OpenCloud auto-provisions user in external OpenLDAP -6. User is granted access based on OIDC group claims - -## Deployment Steps - -### 1. Create OpenLDAP Admin Secret - -First, generate strong passwords and create the sealed secret: - -```bash -# Generate passwords -ADMIN_PASSWORD=$(openssl rand -base64 32) -CONFIG_PASSWORD=$(openssl rand -base64 32) - -# Save them securely (e.g., password manager) -echo "Admin Password: $ADMIN_PASSWORD" -echo "Config Password: $CONFIG_PASSWORD" - -# Create sealed secret -kubectl create secret generic openldap-admin-secret \ - --namespace opencloud \ - --from-literal=admin-password="$ADMIN_PASSWORD" \ - --from-literal=config-password="$CONFIG_PASSWORD" \ - --dry-run=client -o yaml | \ - kubeseal --format yaml > openldap-admin-sealed.yaml - -# Apply sealed secret -kubectl apply -f openldap-admin-sealed.yaml -``` - -### 2. Deploy OpenLDAP - -```bash -# Deploy OpenLDAP -kubectl apply -f openldap-deployment.yaml - -# Wait for OpenLDAP to be ready -kubectl wait --for=condition=ready pod -l app=openldap -n opencloud --timeout=120s - -# Check OpenLDAP pod status -kubectl get pods -n opencloud -l app=openldap -kubectl logs -n opencloud -l app=openldap -f -``` - -### 3. Initialize LDAP Directory Structure - -Once OpenLDAP is running, initialize the directory with required OUs: - -```bash -# Get the OpenLDAP pod name -LDAP_POD=$(kubectl get pods -n opencloud -l app=openldap -o jsonpath='{.items[0].metadata.name}') - -# Copy the LDIF file to the pod -kubectl cp ldap-init-structure.ldif opencloud/$LDAP_POD:/tmp/init-structure.ldif - -# Apply the LDIF (replace with your actual password) -kubectl exec -n opencloud $LDAP_POD -- \ - ldapadd -x -D "cn=admin,dc=basicstack,dc=de" -w "" -f /tmp/init-structure.ldif - -# Verify structure was created -kubectl exec -n opencloud $LDAP_POD -- \ - ldapsearch -x -D "cn=admin,dc=basicstack,dc=de" -w "" -b "dc=basicstack,dc=de" -LLL -``` - -### 4. Deploy OpenCloud - -**Important:** Make sure the old OpenCloud PVC is deleted first to ensure fresh initialization with new LDAP configuration. - -```bash -# Scale down existing OpenCloud deployment (if running) -kubectl scale deployment -n opencloud opencloud --replicas=0 - -# Delete old PVC -kubectl delete pvc -n opencloud opencloud-data - -# Apply updated deployment -kubectl apply -f opencloud-deployment.yaml -kubectl apply -f opencloud-configmap.yaml - -# Scale up -kubectl scale deployment -n opencloud opencloud --replicas=1 - -# Watch initialization -kubectl logs -n opencloud -l app=opencloud -f -``` - -### 5. Verify Configuration - -```bash -# Check all pods are running -kubectl get pods -n opencloud - -# Verify OpenCloud can connect to LDAP -kubectl exec -n opencloud deployment/opencloud -- \ - ldapsearch -x -H ldap://openldap.opencloud.svc.cluster.local:389 \ - -D "cn=admin,dc=basicstack,dc=de" -w "" \ - -b "dc=basicstack,dc=de" -LLL - -# Check OpenCloud logs for LDAP connection -kubectl logs -n opencloud -l app=opencloud | grep -i ldap -``` - -### 6. Test OIDC Authentication - -1. Open browser to `https://opencloud.basicstack.de` -2. Should redirect to `https://auth.basicstack.de` -3. Login with Pocket ID credentials -4. Should redirect back to OpenCloud -5. User auto-provisioned in OpenLDAP - -## LDAP Directory Structure - -``` -dc=basicstack,dc=de -├── cn=admin (admin user) -├── ou=users -│ └── (auto-provisioned users from OIDC) -└── ou=groups - ├── cn=opencloudUsers (default users group) - └── cn=opencloudAdmins (administrators group) -``` - -## Configuration Details - -### OpenLDAP Connection Details - -- **Service:** `openldap.opencloud.svc.cluster.local` -- **Port:** 389 (LDAP), 636 (LDAPS - disabled for internal use) -- **Base DN:** `dc=basicstack,dc=de` -- **Admin DN:** `cn=admin,dc=basicstack,dc=de` -- **User Base:** `ou=users,dc=basicstack,dc=de` -- **Group Base:** `ou=groups,dc=basicstack,dc=de` - -### OpenCloud Services Excluded - -- **search** - Broken in v7.2.0 -- **idp** - Using external Pocket ID for authentication -- **idm** - Using external OpenLDAP for user storage - -### OIDC Configuration - -- **Issuer:** `https://auth.basicstack.de` -- **Client ID:** (from `opencloud-oidc-secret`) -- **Scopes:** `openid profile email groups offline_access` -- **Auto-provisioning:** Enabled -- **User claim:** `email` -- **Role claim:** `groups` - -### Role Mapping - -OIDC groups → OpenCloud roles: -- `opencloudAdmin` → admin -- `opencloudSpaceAdmin` → spaceadmin -- `opencloudUser` → user -- `opencloudGuest` → guest - -## Troubleshooting - -### OpenLDAP not starting - -```bash -# Check logs -kubectl logs -n opencloud -l app=openldap - -# Check PVCs -kubectl get pvc -n opencloud - -# Check events -kubectl get events -n opencloud --sort-by='.lastTimestamp' | tail -20 -``` - -### OpenCloud can't connect to LDAP - -```bash -# Test LDAP connectivity from OpenCloud pod -kubectl exec -n opencloud deployment/opencloud -- \ - nc -zv openldap.opencloud.svc.cluster.local 389 - -# Check LDAP service -kubectl get svc -n opencloud openldap - -# Check LDAP endpoints -kubectl get endpoints -n opencloud openldap -``` - -### Users not auto-provisioning - -```bash -# Check OpenCloud proxy logs -kubectl logs -n opencloud -l app=opencloud | grep -i provision - -# Check OIDC flow -kubectl logs -n opencloud -l app=opencloud | grep -i oidc - -# Verify LDAP directory structure -kubectl exec -n opencloud deployment/openldap -- \ - ldapsearch -x -D "cn=admin,dc=basicstack,dc=de" -w "" \ - -b "ou=users,dc=basicstack,dc=de" -LLL -``` - -### View auto-provisioned users - -```bash -# List all users in LDAP -kubectl exec -n opencloud deployment/openldap -- \ - ldapsearch -x -D "cn=admin,dc=basicstack,dc=de" -w "" \ - -b "ou=users,dc=basicstack,dc=de" -LLL "(objectClass=inetOrgPerson)" -``` - -## Backup and Maintenance - -### Backup LDAP Data - -```bash -# Backup entire LDAP directory -kubectl exec -n opencloud deployment/openldap -- \ - slapcat -l /tmp/backup.ldif - -kubectl cp opencloud/$LDAP_POD:/tmp/backup.ldif ./ldap-backup-$(date +%Y%m%d).ldif -``` - -### Monitor LDAP Performance - -```bash -# Check LDAP stats -kubectl exec -n opencloud deployment/openldap -- \ - ldapsearch -x -H ldapi:/// -Y EXTERNAL -b "cn=Monitor" -LLL -``` - -## Files - -- `openldap-deployment.yaml` - OpenLDAP Kubernetes deployment -- `openldap-admin-sealed.yaml` - Admin credentials (sealed secret) -- `ldap-init-structure.ldif` - Initial directory structure -- `opencloud-deployment.yaml` - OpenCloud deployment (updated for external LDAP) -- `opencloud-configmap.yaml` - OpenCloud configuration (updated for external LDAP) - -## References - -- OpenLDAP: https://www.openldap.org/ -- OpenCloud LDAP Configuration: https://docs.opencloud.eu/ -- Pocket ID: https://github.com/stonith404/pocket-id diff --git a/apps/opencloud/ldap-init-structure.ldif b/apps/opencloud/ldap-init-structure.ldif deleted file mode 100644 index fcd05b7..0000000 --- a/apps/opencloud/ldap-init-structure.ldif +++ /dev/null @@ -1,37 +0,0 @@ -# OpenLDAP Directory Structure Initialization -# This LDIF creates the organizational units needed by OpenCloud -# -# Apply with: -# kubectl exec -n opencloud deployment/openldap -- \ -# ldapadd -x -D "cn=admin,dc=basicstack,dc=de" -w -f /tmp/init-structure.ldif -# -# Or copy to pod and apply: -# kubectl cp ldap-init-structure.ldif opencloud/openldap-:/tmp/init-structure.ldif -# kubectl exec -n opencloud openldap- -- \ -# ldapadd -x -D "cn=admin,dc=basicstack,dc=de" -w -f /tmp/init-structure.ldif - -# Create Users Organizational Unit -dn: ou=users,dc=basicstack,dc=de -objectClass: organizationalUnit -ou: users -description: OpenCloud Users - -# Create Groups Organizational Unit -dn: ou=groups,dc=basicstack,dc=de -objectClass: organizationalUnit -ou: groups -description: OpenCloud Groups - -# Example: Create default user group -dn: cn=opencloudUsers,ou=groups,dc=basicstack,dc=de -objectClass: groupOfNames -cn: opencloudUsers -description: Default OpenCloud Users Group -member: cn=admin,dc=basicstack,dc=de - -# Example: Create admin group -dn: cn=opencloudAdmins,ou=groups,dc=basicstack,dc=de -objectClass: groupOfNames -cn: opencloudAdmins -description: OpenCloud Administrators -member: cn=admin,dc=basicstack,dc=de diff --git a/apps/opencloud/opencloud-deployment.yaml b/apps/opencloud/opencloud-deployment.yaml index 54baa9b..eabd72e 100644 --- a/apps/opencloud/opencloud-deployment.yaml +++ b/apps/opencloud/opencloud-deployment.yaml @@ -290,13 +290,6 @@ spec: name: opencloud-config-secrets key: ldap-bind-password - # External OpenLDAP admin password (for user/group storage) - - name: OPENLDAP_ADMIN_PASSWORD - valueFrom: - secretKeyRef: - name: openldap-admin-secret - key: admin-password - # IDM service user passwords - name: OC_IDM_ADMIN_PASSWORD valueFrom: diff --git a/apps/opencloud/opencloud-ldap-schema-job.yaml b/apps/opencloud/opencloud-ldap-schema-job.yaml deleted file mode 100644 index 156d5cd..0000000 --- a/apps/opencloud/opencloud-ldap-schema-job.yaml +++ /dev/null @@ -1,68 +0,0 @@ ---- -# One-shot Job to load the OpenCloud LDAP schema into the running OpenLDAP instance. -# Connect via network LDAP as cn=admin,cn=config (rootdn of the config database). -# Re-run by deleting and recreating the Job; idempotent (exits 0 if schema already present). -apiVersion: batch/v1 -kind: Job -metadata: - name: opencloud-ldap-schema-loader - namespace: opencloud -spec: - ttlSecondsAfterFinished: 86400 - backoffLimit: 10 - template: - spec: - restartPolicy: OnFailure - containers: - - name: schema-loader - image: osixia/openldap:1.5.0 - command: - - /bin/bash - - -c - - | - set -e - - echo "Waiting for OpenLDAP to be ready..." - until ldapsearch -x -H ldap://openldap:389 \ - -D "cn=admin,dc=basicstack,dc=de" \ - -w "$LDAP_ADMIN_PASSWORD" \ - -b "dc=basicstack,dc=de" \ - -s base "(objectClass=*)" dn 2>&1 | grep -q "result: 0"; do - echo "Not ready yet, retrying in 5s..." - sleep 5 - done - echo "OpenLDAP is ready" - - if ldapsearch -x -H ldap://openldap:389 \ - -D "cn=admin,cn=config" \ - -w "$LDAP_CONFIG_PASSWORD" \ - -b "cn=schema,cn=config" \ - "(cn={*}opencloud)" dn 2>/dev/null | grep -qi "opencloud"; then - echo "OpenCloud schema already present, nothing to do" - exit 0 - fi - - echo "Loading OpenCloud LDAP schema..." - ldapadd -x -H ldap://openldap:389 \ - -D "cn=admin,cn=config" \ - -w "$LDAP_CONFIG_PASSWORD" \ - -f /schemas/10_opencloud_schema.ldif - echo "OpenCloud schema loaded successfully" - env: - - name: LDAP_ADMIN_PASSWORD - valueFrom: - secretKeyRef: - name: openldap-admin-secret - key: admin-password - - name: LDAP_CONFIG_PASSWORD - valueFrom: - secretKeyRef: - name: openldap-admin-secret - key: config-password - volumeMounts: - - name: schemas - mountPath: /schemas - volumes: - - name: schemas - configMap: - name: opencloud-ldap-schema diff --git a/apps/opencloud/opencloud-ldap-schema.yaml b/apps/opencloud/opencloud-ldap-schema.yaml deleted file mode 100644 index aeae6c7..0000000 --- a/apps/opencloud/opencloud-ldap-schema.yaml +++ /dev/null @@ -1,58 +0,0 @@ ---- -# OpenCloud LDAP schema ConfigMap -# Defines openCloudUser objectClass and related attributes (OIDs under 1.3.6.1.4.1.63016) -# Mounted into OpenLDAP pod and loaded via lifecycle postStart hook -apiVersion: v1 -kind: ConfigMap -metadata: - name: opencloud-ldap-schema - namespace: opencloud -data: - 10_opencloud_schema.ldif: | - dn: cn=opencloud,cn=schema,cn=config - objectClass: olcSchemaConfig - cn: opencloud - olcAttributeTypes: ( 1.3.6.1.4.1.63016.1.1.1 - NAME 'openCloudUUID' - DESC 'A non-reassignable and persistent account ID' - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} - SINGLE-VALUE ) - olcAttributeTypes: ( 1.3.6.1.4.1.63016.1.1.2 - NAME 'openCloudExternalIdentity' - DESC 'Represents the objectIdentity resource type of the Graph API' - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) - olcAttributeTypes: ( 1.3.6.1.4.1.63016.1.1.3 - NAME 'openCloudUserEnabled' - DESC 'Indicates if the user account is enabled' - EQUALITY booleanMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 - SINGLE-VALUE ) - olcAttributeTypes: ( 1.3.6.1.4.1.63016.1.1.4 - NAME 'openCloudUserType' - DESC 'Specifies the user type (Member or Guest)' - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 - SINGLE-VALUE ) - olcAttributeTypes: ( 1.3.6.1.4.1.63016.1.1.5 - NAME 'openCloudLastSignInTimestamp' - DESC 'Timestamp of the most recent authentication event' - EQUALITY generalizedTimeMatch - ORDERING generalizedTimeOrderingMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 - SINGLE-VALUE ) - olcObjectClasses: ( 1.3.6.1.4.1.63016.1.2.1 - NAME 'openCloudObject' - DESC 'Base auxiliary class for OpenCloud objects' - AUXILIARY - MAY ( openCloudUUID ) ) - olcObjectClasses: ( 1.3.6.1.4.1.63016.1.2.2 - NAME 'openCloudUser' - DESC 'Auxiliary class for OpenCloud user accounts' - AUXILIARY - SUP openCloudObject - MAY ( openCloudExternalIdentity $ openCloudUserEnabled $ openCloudUserType $ openCloudLastSignInTimestamp ) ) diff --git a/apps/opencloud/openldap-admin-sealed.yaml b/apps/opencloud/openldap-admin-sealed.yaml deleted file mode 100644 index 796f408..0000000 --- a/apps/opencloud/openldap-admin-sealed.yaml +++ /dev/null @@ -1,16 +0,0 @@ ---- -apiVersion: bitnami.com/v1alpha1 -kind: SealedSecret -metadata: - creationTimestamp: null - name: openldap-admin-secret - namespace: opencloud -spec: - encryptedData: - admin-password: AgCfe8Y89Uy1gGJtkD/8QUn0KJMGKHvVc53f8N0tJk0KECT5Bxas9zNxL6UF+3Uxz/IgP4F3ZMgQ0AEy5GpnOHHZkWxjXjs64WGiUauA59MCxMQT6kwKtLkTX7M632S0HKwbS+vJi2S/r6JmMjSfCQJrsf2XKrfeyeg3+MqxwDSjIYdfyUTvNJ190QA0guqEpJltch8+Mr7Va0oxbwO64gDSXyjIipOCEHiGlMEiYlFXgEI/xUBEsvWN5jwgjmCkNTvx0id5+5ZhZHtWbLVBTP0caAqPhgsxjI0OhNPb8ZSzLx2uPgBK4m2jw6Kw4TvL+mJq1tvGjxnxVnDil4GhB4sjm0PKsL1EOeXzJphQWHvk6wDgrf3KW9uQPBODfVH1xUYCkrFWa/YzYM+rYJtnKdUVfqV6U//Vd64BXjz0Opx8twd9ljwlMBnW+8RRy8940m1bGEaKWeZNdXU+gVGEd+E4dYdqycz46UvktQmyFQgNjesGNbpwc+fVw4E2uDCLM8Lo35PnIcGeaMRQeurQuSFbKntFazB6nggkweesiFcPLSoHWUsvrdyK7h9lkLOg0KG5SoUs4aUkd2L4UpLHGMxV2PioxMPI6epe3AFIkcuMO/ukJuA7Cg58P9ZUZiED2dhkF9hOoUibaAKndwdPtQzBQUofj0LMVqHcSKjH3jC1eOAbKzvTHELfdWql5fldE5IEFP/HkfguGAqvV8XGm4QPb4D1Tj2raMHiiG39rq4mHgcdF++9IGjxdTYnaw== - config-password: AgBtWsvBgzOq6mHKZ7HLd/SqEVGFozSkXKWyqLUVKFNNnjwVwvZU/vUFKzKxC7xqoNjccqrQjcxbAPAA8USxZyUrW+Qws/v7J4w2bvtg3nklZfG8FGZZvaLFkUJKV0ZWa+kg3CFoFk5hHH3IpesfZTOCJPTiCey61os0m8DS1g9fre1eKVZz5RFk3d79Pv+O8P4ao9RF+dXPYuBMLHxg+b77p/LzeV0sCIicdLKNrQaPGj8OP9JyGpD8XLX3enWFtFNtX48gLnVGrzNLWo/Ic2LQZoqM7XUB2d/zlB6CN6KrnkZEoR3L5GPU7fVXAga6L1JqTiPD8SG7BnWlxdKZEeoko94NciBQcIG1igE4+HTMBx3kbES+eh+kV2ImLzKTYuUuoN7TUJnOXP10x2zf1OhdKumqFqNFVPPJW8zDtzIflkzwFN79cY+WP5XOL/XUnLIISIGGpW4tTyfsLL3BnoWtkfuSjeH6JEsq8xOcVSyg0/6hCmz9ZztkmqMjTEkL0++agaXxPQgyvsxX8r/8TCwVt02RGRbPUQqH9r6/xdIX4SQEzoFhbINqPgCVuY7U/cNqAOxwP7FmG6Dcm8wAEtFTEFqU3T5eo0iuQqpfN3iXsFahf7e28Jh2N5JS344RiqA0HAmu4QT67maXLQrvkbL6zYY5pROsm2y2xgZP432AZ98hw3BooDelkLZZ9A5HNgBg8I/kSBgX2xLZR+Nc5L7KH240zR5/0Hc0jh9fjzdibISQ76y4gTEp1Y2KSg== - template: - metadata: - creationTimestamp: null - name: openldap-admin-secret - namespace: opencloud diff --git a/apps/opencloud/openldap-deployment.yaml b/apps/opencloud/openldap-deployment.yaml deleted file mode 100644 index 8885843..0000000 --- a/apps/opencloud/openldap-deployment.yaml +++ /dev/null @@ -1,147 +0,0 @@ ---- -# OpenLDAP Deployment for OpenCloud -# Provides external LDAP directory for user and group storage -# OpenLDAP Data Storage -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: openldap-data - namespace: opencloud -spec: - accessModes: - - ReadWriteOnce - storageClassName: hcloud-volumes-encrypted - resources: - requests: - storage: 10Gi ---- -# OpenLDAP Config Storage -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: openldap-config - namespace: opencloud -spec: - accessModes: - - ReadWriteOnce - storageClassName: hcloud-volumes-encrypted - resources: - requests: - storage: 1Gi ---- -# OpenLDAP Service -apiVersion: v1 -kind: Service -metadata: - name: openldap - namespace: opencloud -spec: - type: ClusterIP - selector: - app: openldap - ports: - - name: ldap - port: 389 - targetPort: 389 - protocol: TCP - - name: ldaps - port: 636 - targetPort: 636 - protocol: TCP ---- -# OpenLDAP Deployment -apiVersion: apps/v1 -kind: Deployment -metadata: - name: openldap - namespace: opencloud -spec: - replicas: 1 - selector: - matchLabels: - app: openldap - template: - metadata: - labels: - app: openldap - spec: - containers: - - name: openldap - image: osixia/openldap:1.5.0 - env: - # Organization and domain - - name: LDAP_ORGANISATION - value: "BasicStack" - - name: LDAP_DOMAIN - value: "basicstack.de" - - # Admin credentials - - name: LDAP_ADMIN_PASSWORD - valueFrom: - secretKeyRef: - name: openldap-admin-secret - key: admin-password - - # Config admin password - - name: LDAP_CONFIG_PASSWORD - valueFrom: - secretKeyRef: - name: openldap-admin-secret - key: config-password - - # Base DN will be: dc=basicstack,dc=de - # Admin DN will be: cn=admin,dc=basicstack,dc=de - - # Logging - - name: LDAP_LOG_LEVEL - value: "256" - - # TLS disabled for internal cluster communication - - name: LDAP_TLS - value: "false" - - # Remove default database and start fresh - - name: LDAP_REMOVE_CONFIG_AFTER_SETUP - value: "false" - - ports: - - containerPort: 389 - name: ldap - - containerPort: 636 - name: ldaps - - volumeMounts: - - name: openldap-data - mountPath: /var/lib/ldap - - name: openldap-config - mountPath: /etc/ldap/slapd.d - - resources: - requests: - memory: "256Mi" - cpu: "100m" - limits: - memory: "512Mi" - cpu: "500m" - - livenessProbe: - tcpSocket: - port: 389 - initialDelaySeconds: 30 - periodSeconds: 10 - timeoutSeconds: 5 - - readinessProbe: - tcpSocket: - port: 389 - initialDelaySeconds: 20 - periodSeconds: 5 - timeoutSeconds: 3 - - volumes: - - name: openldap-data - persistentVolumeClaim: - claimName: openldap-data - - name: openldap-config - persistentVolumeClaim: - claimName: openldap-config