diff --git a/charts/ds389/Chart.yaml b/charts/ds389/Chart.yaml new file mode 100644 index 0000000..83e34cc --- /dev/null +++ b/charts/ds389/Chart.yaml @@ -0,0 +1,12 @@ +apiVersion: v2 +name: ds389-helm-chart +description: A Helm chart for deploying the 389 Directory Server +version: 1.0.0 +appVersion: "1.0" +maintainers: + - name: rmahique + email: raul.mahiques@suse.com +keywords: + - ldap + - '389' + - '636' diff --git a/charts/ds389/templates/secrets.yaml b/charts/ds389/templates/secrets.yaml new file mode 100644 index 0000000..7bb1002 --- /dev/null +++ b/charts/ds389/templates/secrets.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + name: dirsrv-tls-secret +# namespace: {{ .Values.ds389.nsName }} +data: + tls.key: {{ .Values.ds389.tlsKey | b64enc | quote }} + tls.crt: {{ .Values.ds389.tlsCert | b64enc | quote }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: dirsrv-dm-password +# namespace: {{ .Values.ds389.nsName }} +data: + dm-password: {{ .Values.ds389.dmPassword | quote }} diff --git a/charts/ds389/templates/service-external.yaml b/charts/ds389/templates/service-external.yaml new file mode 100644 index 0000000..ff09ae6 --- /dev/null +++ b/charts/ds389/templates/service-external.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: {{ .Values.ds389.name }} + name: {{ .Values.ds389.name }}-external-svc +# namespace: {{ .Values.ds389.nsName }} +spec: + ports: + - name: {{ .Values.ds389.name }}-port + port: {{ .Values.ds389.internalPort }} + protocol: TCP + targetPort: {{ .Values.ds389.internalPort }} + nodePort: {{ .Values.ds389.nodePort }} + - name: {{ .Values.ds389.name }}-tls-port + port: {{ .Values.ds389.tlsPort }} + protocol: TCP + targetPort: {{ .Values.ds389.tlsPort }} + nodePort: {{ .Values.ds389.nodePortTls }} + selector: + app: {{ .Values.ds389.name }} + type: NodePort diff --git a/charts/ds389/templates/service-internal.yaml b/charts/ds389/templates/service-internal.yaml new file mode 100644 index 0000000..73176ba --- /dev/null +++ b/charts/ds389/templates/service-internal.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: {{ .Values.ds389.name }} + name: {{ .Values.ds389.name }}-internal-svc +# namespace: {{ .Values.ds389.nsName }} +spec: + clusterIP: None + ports: + - name: {{ .Values.ds389.name }}-port + port: {{ .Values.ds389.internalPort }} + protocol: TCP + targetPort: {{ .Values.ds389.internalPort }} + - name: {{ .Values.ds389.name }}-tls-port + port: {{ .Values.ds389.tlsPort }} + protocol: TCP + targetPort: {{ .Values.ds389.tlsPort }} + selector: + app: {{ .Values.ds389.name }} + type: ClusterIP diff --git a/charts/ds389/templates/serviceaccount.yaml b/charts/ds389/templates/serviceaccount.yaml new file mode 100644 index 0000000..516cf7a --- /dev/null +++ b/charts/ds389/templates/serviceaccount.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.ds389.name }}-sa +# namespace: {{ .Values.ds389.nsName }} diff --git a/charts/ds389/templates/statefulset.yaml b/charts/ds389/templates/statefulset.yaml new file mode 100644 index 0000000..e546584 --- /dev/null +++ b/charts/ds389/templates/statefulset.yaml @@ -0,0 +1,93 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ .Values.ds389.name }} +# namespace: {{ .Values.ds389.nsName }} +spec: + serviceName: {{ .Values.ds389.name }}-internal-svc + replicas: 1 + selector: + matchLabels: + app: {{ .Values.ds389.name }} + template: + metadata: + labels: + app: {{ .Values.ds389.name }} + spec: + serviceAccountName: {{ .Values.ds389.name }}-sa + securityContext: + fsGroup: 499 + initContainers: + - name: {{ .Values.ds389.name }}-init-container + image: busybox + command: ["/bin/sh", "-c", "chown -R 499:499 /data"] + volumeMounts: + - name: {{ .Values.ds389.name }}-data + mountPath: /data + containers: + - name: dirsrv-container + image: {{ .Values.ds389.image }} + lifecycle: + postStart: + exec: + command: ["/bin/sh", "-c", "sleep 60; + dsconf localhost backend create --suffix {{ .Values.ds389.rootDN }} --be-name userroot --create-suffix --create-entries ; + dsconf localhost pwpolicy set --pwdscheme=CRYPT-SHA512 ; + dsconf localhost config replace nsslapd-rootpwstoragescheme=CRYPT-SHA512 ; + dsconf localhost config replace nsslapd-rootpw={{ .Values.ds389.dm_pwd }} ; + dsconf localhost plugin referential-integrity enable ; + dsconf localhost plugin memberof enable ; + dsconf localhost config replace nsslapd-allow-anonymous-access=off ; + dsidm localhost --basedn {{ .Values.ds389.rootDN }} user create --uid ldap_user --cn ldap_user --displayName ldap_user --uidNumber 1001 --gidNumber 1001 --homeDirectory /home/ldap_user ; + dsidm localhost -b {{ .Values.ds389.rootDN }} account change_password uid=ldap_user,ou=people,{{ .Values.ds389.rootDN }} {{ .Values.ds389.users_pwd }} ; + dsidm localhost --basedn {{ .Values.ds389.rootDN }} user create --uid developer --cn developer --displayName developer --uidNumber 1002 --gidNumber 1002 --homeDirectory /home/developer ; + dsidm localhost -b {{ .Values.ds389.rootDN }} account change_password uid=developer,ou=people,{{ .Values.ds389.rootDN }} {{ .Values.ds389.users_pwd }} ; + dsidm localhost --basedn {{ .Values.ds389.rootDN }} group create --cn developers; + dsidm localhost -b {{ .Values.ds389.rootDN }} group add_member developers uid=developer,ou=people,{{ .Values.ds389.rootDN }} + "] + env: + - name: DS_DM_PASSWORD + valueFrom: + secretKeyRef: + name: dirsrv-dm-password + key: dm-password + - name: DS_SUFFIX_NAME + value: "{{ .Values.ds389.rootDN }}" + - name: DS_ERRORLOG_LEVEL + value: "8192" + - name: DS_MEMORY_PERCENTAGE + value: "10" + - name: DS_REINDEX + value: "True" + - name: DS_STARTUP_TIMEOUT + value: "120" + ports: + - containerPort: {{ .Values.ds389.internalPort }} + protocol: TCP + - containerPort: {{ .Values.ds389.tlsPort }} + protocol: TCP + securityContext: + runAsUser: 489 + volumeMounts: + - name: {{ .Values.ds389.name }}-data + mountPath: "/data" + - name: dirsrv-tls + mountPath: '/data/tls/' + readOnly: true + volumes: + - name: dirsrv-tls + secret: + secretName: dirsrv-tls-secret + items: + - key: tls.key + path: server.key + - key: tls.crt + path: server.crt + volumeClaimTemplates: + - metadata: + name: {{ .Values.ds389.name }}-data + spec: + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: {{ .Values.ds389.vcSize }} diff --git a/charts/ds389/values.yaml b/charts/ds389/values.yaml new file mode 100644 index 0000000..bed3109 --- /dev/null +++ b/charts/ds389/values.yaml @@ -0,0 +1,15 @@ +# Default values for ds389-helm-chart +ds389: + nsName: "ds389" + name: "ds389" + image: "docker.io/389ds/dirsrv" + tlsKey: "LS0tLS1CRUdJTiBFTkNSWVBURUQgUFJJVkFURSBLRVktLS0tLQpNSUlKbnpCSkJna3Foa2lHOXcwQkJRMHdQREFiQmdrcWhraUc5dzBCQlF3d0RnUUlMZmtpMDkwcnZsb0NBZ2dBCk1CMEdDV0NHU0FGbEF3UUJLZy4uLkdOWWM3aTlTVkRCb0E9PQotLS0tLUVORCBFTkNSWVBURUQgUFJJVkFURSBLRVktLS0tLQ==" + tlsCert: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZ4akNDQTY0Q0NRQ05UK2VQMnZqSnh6QU5CZ2txaGtpRzl3MEJBUXNGQURDQnBERUxNQWtHQTFVRUJoTUMKUmxJeEVqQVFCZ05WQkFnTUMuLi51ZEp3RTdIbm5BN2xwQQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0t" + dmPassword: "YWRtaW4xMjM=" + rootDN: "dc=mydemo,dc=lab" + userPassword: "supersecret123" + vcSize: "5Gi" + internalPort: 3389 + tlsPort: 3636 + nodePort: 30389 + nodePortTls: 30636 diff --git a/scripts/authentication/ds389.sh b/scripts/authentication/ds389.sh new file mode 100644 index 0000000..855ee49 --- /dev/null +++ b/scripts/authentication/ds389.sh @@ -0,0 +1,135 @@ +#!/bin/bash +# This library contains some functions to use and setup 389 +# directory server ( https://www.port389.org/index.html ) +# which is an "enterprise-class Open Source LDAP server for Linux.". +# SPDX-License-Identifier: GPL-3.0-only or GPL-3.0-or-later +# +# Copyright (C) 2024 Raul Mahiques +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# For more details find a copy of the license here: +# https://www.gnu.org/licenses/gpl-3.0.txt +# + + + +####################################### +# DS389 - restrict permissions: +# - prevent normal users from reading the whole directory +# Arguments: +# 1 - _ldap_uri +# 2 - _ldap_basedn +# 3 - _admin_user +# 4 - _admin_pwd +# Examples: +# ds389_restrict_permissions "<_ldap_uri>" "<_ldap_basedn>" "<_admin_user>" "<_admin_pwd>" +####################################### +function ds389_restrict_permissions() { + local _ldap_uri="$1" + local _ldap_basedn="$2" + local _admin_user="$3" + local _admin_pwd="$4" + ldapmodify -D "${_admin_user}" -w "${_admin_pwd}" -x -H "${_ldap_uri}" << EOL +dn: ou=people,${_ldap_basedn} +changetype: modify +delete: aci +aci: (targetattr="objectClass || description || nsUniqueId || uid || displayName || loginShell || uidNumber || gidNumber || gecos || homeDirectory || cn || memberOf || mail || nsSshPublicKey || nsAccountLock || userCertificate")(targetfilter="(objectClass=posixaccount)")(version 3.0; acl "Enable anyone user read"; allow (read, search, compare)(userdn="ldap:///anyone");) + +dn: ou=people,${_ldap_basedn} +changetype: modify +add: aci +aci: (targetattr="objectClass || description || nsUniqueId || uid || displayName || loginShell || uidNumber || gidNumber || gecos || homeDirectory || cn || memberOf || mail || nsSshPublicKey || nsAccountLock || userCertificate")(targetfilter="(objectClass=posixaccount)")(version 3.0; acl "Enable self user read"; allow (read, search, compare)(userdn="ldap:///self");) +EOL +} + +####################################### +# DS389 - Grant user privileges to read the whole directory +# Arguments: +# 1 - _ldap_uri +# 2 - _ldap_basedn +# 3 - _admin_user +# 4 - _admin_pwd +# 5 - Username (Default: ldap_user) +# Examples: +# ds389_user_private_read "ldap://ldap.mydemo.lab:389" "dc=mydemo,dc=lab" "cn=Directory Manager" "secret" "ldap_user" +####################################### +function ds389_ldap_user_user_private_read() { + local _ldap_uri="$1" + local _ldap_basedn="$2" + local _admin_user="$3" + local _admin_pwd="$4" + local ldap_user="$5" + ldapmodify -D "${_admin_user}" -w "${_admin_pwd}" -x -H "${_ldap_uri}" << EOL +dn: cn=user_private_read,ou=permissions,${_ldap_basedn} +changetype: modify +add: member +member: uid=${ldap_user},ou=people,${_ldap_basedn} +EOL +} + +####################################### +# DS389 - Verify user has access +# Arguments: +# 1 - ldap user DN +# 2 - ldap user pwd +# 3 - _ldap_uri +# 4 - _ldap_basedn +# Examples: +# ds389_ldap_user_access_check "cn=Directory Manager" "secret" "uid=ldap_user,ou=people,dc=mydemo,dc=lab" "mypassword" +####################################### +function ds389_ldap_user_access_check() { + local _ldap_user_dn="${1}" + local _ldap_user_pwd="${2}" + local _ldap_uri="${3}" + local _ldap_basedn="${4}" + ldapsearch -x -D "${_ldap_user_dn}" -w "${_ldap_user_pwd}" -H "${_ldap_uri}" -b "${_ldap_basedn}" +} + +####################################### +# DS389 - Install 389 Directory server +# Arguments: +# 1 - _ldap_uri +# 2 - _ldap_basedn +# 3 - _admin_user +# 4 - _admin_pwd +# Examples: +# ds389_install "ldap://ldap.mydemo.lab:389" "dc=mydemo,dc=lab" "cn=Directory Manager" "secret" +####################################### +function ds389_install() { + local _ldap_uri="${1}" + local _ldap_basedn="${2}" + local _admin_user="${3}" + local _admin_pwd="${4}" + # add the repo + helm repo add suse-lab-setup https://opensource.suse.com/lab-setup + helm repo update + # installs the chart with default parameters + if [[ -f values.yaml ]] + then + helm upgrade --install ds389 --namespace ds389 suse-lab-setup/ds389 -f values.yaml + else + helm upgrade --install ds389 --namespace ds389 suse-lab-setup/ds389 + fi + sleep 60 + ds389_restrict_permissions "${_ldap_uri}" "${_ldap_basedn}" "${_admin_user}" "${_admin_pwd}" + ds389_ldap_user_user_private_read "${_ldap_uri}" "${_ldap_basedn}" "${_admin_user}" "${_admin_pwd}" "ldap_user" +} + +####################################### +# DS389 - Uninstall 389 Directory server +# Examples: +# ds389_uninstall +####################################### +function ds389_uninstall() { + helm uninstall ds389 + sleep 15 +}