From fbe4909a8e4c78fd541facea4bd052d10100ea71 Mon Sep 17 00:00:00 2001 From: openDesk Bot Date: Tue, 23 Jul 2024 03:36:56 +0000 Subject: [PATCH] feat(services): [bmi/opendesk/deployment/opendesk#66] Add dkimpy-milter to sign outgoing emails with DKIM and use local postfix as mail relay in all components. --- README.md | 2 +- docs/components.md | 1 + docs/getting-started.md | 34 +- .../apps/element/values-synapse.yaml.gotmpl | 14 +- .../values-nextcloud-mgmt.yaml.gotmpl | 11 +- helmfile/apps/nubus/values-nubus.yaml.gotmpl | 28 +- ...es-opendesk-keycloak-bootstrap.yaml.gotmpl | 293 +++++++++++++++++- .../open-xchange/values-dovecot.yaml.gotmpl | 2 +- helmfile/apps/openproject/values.yaml.gotmpl | 14 +- helmfile/apps/services/helmfile-child.yaml | 19 ++ .../apps/services/values-dkimpy.yaml.gotmpl | 44 +++ .../apps/services/values-postfix.yaml.gotmpl | 3 + helmfile/apps/xwiki/values.yaml.gotmpl | 8 +- helmfile/environments/default/charts.yaml | 26 +- helmfile/environments/default/images.yaml | 10 +- .../environments/default/opendesk_main.gotmpl | 3 + helmfile/environments/default/replicas.yaml | 2 + helmfile/environments/default/resources.yaml | 7 + helmfile/environments/default/selinux.yaml | 1 + helmfile/environments/default/smtp.gotmpl | 13 + 20 files changed, 483 insertions(+), 52 deletions(-) create mode 100644 helmfile/apps/services/values-dkimpy.yaml.gotmpl diff --git a/README.md b/README.md index ac063168..6b2f420f 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ openDesk is a Kubernetes based, open-source and cloud-native digital workplace s openDesk currently features the following functional main components: | Function | Functional Component | Component
Version | Upstream Documentation | -| -------------------- | --------------------------- | ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | +| -------------------- | --------------------------- |---------------------------------------------------------------------------------------| -------------------------------------------------------------------------------------------------------------------------------------------- | | Chat & collaboration | Element ft. Nordeck widgets | [1.11.67](https://github.com/element-hq/element-desktop/releases/tag/v1.11.67) | [For the most recent release](https://element.io/user-guide) | | Diagram editor | CryptPad ft. diagrams.net | [5.6.0](https://github.com/cryptpad/cryptpad/releases/tag/5.6.0) | [For the most recent release](https://docs.cryptpad.org/en/) | | File management | Nextcloud | [28.0.5](https://nextcloud.com/de/changelog/#28-0-5) | [Nextcloud 28](https://docs.nextcloud.com/) | diff --git a/docs/components.md b/docs/components.md index 9b24752c..0c30f753 100644 --- a/docs/components.md +++ b/docs/components.md @@ -33,6 +33,7 @@ they need to be replaced in production deployments. | ClamAV (Simple) | Antivirus engine | Eval | | Collabora | Weboffice | Functional | | CryptPad | Weboffice | Functional | +| dkimpy-milter | DKIM milter for Postfix | Eval | | Element | Secure communications platform | Functional | | Intercom Service | Cross service data exchange | Functional | | Jitsi | Videoconferencing | Functional | diff --git a/docs/getting-started.md b/docs/getting-started.md index b09a8488..e6c74925 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -60,16 +60,16 @@ The deployment is designed to deploy each application/service under a dedicated For your convenience, we recommend to create a `*.domain.tld` A-Record to your cluster ingress controller, otherwise you need to create an A-Record for each subdomain. -| Record name | Type | Value | Additional information | -| ----------------------- | ---- | -------------------------------------------------- | ---------------------------------------------------------------------------------- | -| *.domain.tld | A | IPv4 address of your Ingress Controller | | -| *.domain.tld | AAAA | IPv6 address of your Ingress Controller | | -| mail.domain.tld | A | IPv4 address of your postfix NodePort/LoadBalancer | Optional mail should directly be delivered to openDesk's Postfix | -| mail.domain.tld | AAAA | IPv6 address of your postfix NodePort/LoadBalancer | Optional mail should directly be delivered to openDesk's Postfix | -| domain.tld | MX | `10 mail.domain.tld` | | -| domain.tld | TXT | `v=spf1 +a +mx +a:mail.domain.tld ~all` | Optional, use proper MTA record if present | -| _dmarc.domain.tld | TXT | `v=DMARC1; p=quarantine` | Optional | -| _matrix._tcp.domain.tld | SRV | `1 10 PORT matrix.domain.tld` | `PORT` is your NodePort/LoadBalancer port of `opendesk-synapse-federation` service | +| Record name | Type | Value | Additional information | +|-------------------------------|------|----------------------------------------------------|------------------------------------------------------------------| +| *.domain.tld | A | IPv4 address of your Ingress Controller | | +| *.domain.tld | AAAA | IPv6 address of your Ingress Controller | | +| mail.domain.tld | A | IPv4 address of your postfix NodePort/LoadBalancer | Optional mail should directly be delivered to openDesk's Postfix | +| mail.domain.tld | AAAA | IPv6 address of your postfix NodePort/LoadBalancer | Optional mail should directly be delivered to openDesk's Postfix | +| domain.tld | MX | `10 mail.domain.tld` | | +| domain.tld | TXT | `v=spf1 +a +mx +a:mail.domain.tld ~all` | Optional, use proper MTA record if present | +| _dmarc.domain.tld | TXT | `v=DMARC1; p=quarantine` | Optional | +| default._domainkey.domain.tld | TXT | `v=DKIM1; k=rsa; h=sha256; ...` | Optional DKIM settings | ## Domain @@ -288,6 +288,20 @@ smtp: password: "secret" ``` +Enabling DKIM signing of emails helps to reduce spam and increases trust. +openDesk ships dkimpy-milter as Postfix milter for signing mails. + +```yaml +dkimpy: + enable: true + dkim: + key: + value: | + HzZs08QF1O7UiAkcM9T3U7rePPECtSFvWZIvyKqdg8E= + selector: "default" + useED25519: true # when false, RSA is used +``` + ### TURN configuration Some components (Jitsi, Element) use for direct communication a TURN server. You can configure your own TURN server with diff --git a/helmfile/apps/element/values-synapse.yaml.gotmpl b/helmfile/apps/element/values-synapse.yaml.gotmpl index 44099960..9d41d51a 100644 --- a/helmfile/apps/element/values-synapse.yaml.gotmpl +++ b/helmfile/apps/element/values-synapse.yaml.gotmpl @@ -50,15 +50,17 @@ configuration: url: null sender_localpart: ox-appsuite - presence: + presence: enabled: {{ .Values.functional.dataProtection.matrixPresence.enabled }} - + smtp: senderAddress: "{{ .Values.smtp.localpartNoReply }}@{{ if .Values.functional.email.systemGenerated.useComponentInSenderdomain }}{{ .Values.global.hosts.element }}.{{ end }}{{ .Values.global.domain }}" - host: {{ .Values.smtp.host | quote }} - port: {{ .Values.smtp.port }} - username: {{ .Values.smtp.username | quote }} - password: {{ .Values.smtp.password | quote }} + host: {{ printf "%s.%s.svc.%s" "postfix" (.Values.postfix.namespace | default .Release.Namespace) .Values.cluster.networking.domain | quote }} + port: 25 + tls: false + starttls: false + username: "" + password: "" oidc: clientId: "opendesk-matrix" diff --git a/helmfile/apps/nextcloud/values-nextcloud-mgmt.yaml.gotmpl b/helmfile/apps/nextcloud/values-nextcloud-mgmt.yaml.gotmpl index ce5694c7..aeeebe65 100644 --- a/helmfile/apps/nextcloud/values-nextcloud-mgmt.yaml.gotmpl +++ b/helmfile/apps/nextcloud/values-nextcloud-mgmt.yaml.gotmpl @@ -75,14 +75,17 @@ configuration: value: {{ .Values.secrets.centralnavigation.apiKey | quote }} smtp: auth: + enabled: false username: - value: {{ .Values.smtp.username | quote }} + value: "" password: - value: {{ .Values.smtp.password | quote }} - host: {{ .Values.smtp.host | quote }} - port: {{ .Values.smtp.port | quote }} + value: "" + host: {{ printf "%s.%s.svc.%s" "postfix" (.Values.postfix.namespace | default .Release.Namespace) .Values.cluster.networking.domain | quote }} + port: 25 fromAddress: {{ .Values.smtp.localpartNoReply | quote }} mailDomain: "{{ if .Values.functional.email.systemGenerated.useComponentInSenderdomain }}{{ .Values.global.hosts.nextcloud }}.{{ end }}{{ .Values.global.domain }}" + security: "" + skipVerifyPeer: true quota: default: "{{ .Values.functional.filestore.quota.default }} GB" retentionObligation: diff --git a/helmfile/apps/nubus/values-nubus.yaml.gotmpl b/helmfile/apps/nubus/values-nubus.yaml.gotmpl index 7b70dd3c..ad81d8de 100644 --- a/helmfile/apps/nubus/values-nubus.yaml.gotmpl +++ b/helmfile/apps/nubus/values-nubus.yaml.gotmpl @@ -83,7 +83,7 @@ keycloak: nubusGuardian: provisioning: - enabled: true + enabled: false config: keycloak: credentialSecret: @@ -152,10 +152,13 @@ nubusKeycloakExtensions: key: "umcKeycloakExtensionsDatabasePassword" smtp: connection: - host: {{ .Values.smtp.host | quote }} - port: {{ .Values.smtp.port | quote }} + host: {{ printf "%s.%s.svc.%s" "postfix" (.Values.postfix.namespace | default .Release.Namespace) .Values.cluster.networking.domain | quote }} + port: 25 + ssl: false + starttls: false auth: - username: {{ .Values.smtp.username | quote }} + enabled: false + username: "" credentialSecret: name: "ums-keycloak-extensions-smtp-opendesk-credentials" key: "umcKeycloakExtensionsSmtpPassword" @@ -213,6 +216,12 @@ nubusStackDataUms: # TODO: Remove values when upstreaming fixes nubusStackDataSwp: + stackDataSwp: + {{- if .Values.functional.admin.portal.deploymentInformation.enabled }} + systemInformation: + deployDate: "Deployed: {{ now | date "2006-01-02T15:04:05-0700" }}" + releaseVersion: "Release: {{ .Values.global.systemInformation.releaseVersion }}" + {{- end }} stackDataContext: ldapSearchUsers: {{- range $username, $password := .Values.secrets.nubus.ldapSearch }} @@ -221,9 +230,10 @@ nubusStackDataSwp: lastname: "LDAP-Search-User" {{- end }} externalMailDomain: {{ .Values.global.mailDomain | default .Values.global.domain }} - smtpHost: {{ .Values.smtp.host | quote }} - smtpPort: {{ .Values.smtp.port | quote }} - smtpUser: {{ .Values.smtp.username | quote }} + smtpHost: {{ printf "%s.%s.svc.%s" "postfix" (.Values.postfix.namespace | default .Release.Namespace) .Values.cluster.networking.domain | quote }} + smtpPort: 25 + smtpUser: "" + smtpStartTls: false ldapBase: {{ .Values.ldap.baseDn }} # FIXME: Should be templated correctly in the future portalRealtimeCollaborationLinkBase: {{ printf "https://%s.%s" .Values.global.hosts.element .Values.global.domain }} @@ -309,7 +319,7 @@ extraSecrets: umcKeycloakExtensionsDatabasePassword: {{ .Values.databases.keycloakExtension.password | default .Values.secrets.postgresql.keycloakExtensionUser | quote }} - name: "ums-keycloak-extensions-smtp-opendesk-credentials" stringData: - umcKeycloakExtensionsSmtpPassword: {{ .Values.smtp.password | quote }} + umcKeycloakExtensionsSmtpPassword: "" - name: "ums-portal-server-minio-opendesk-credentials" stringData: access-key-id: {{ .Values.objectstores.nubus.username | quote }} @@ -320,4 +330,4 @@ extraSecrets: secret-key-id: {{ .Values.objectstores.nubus.secretKey | default .Values.secrets.minio.umsUser | quote }} - name: "ums-umc-server-smtp-credentials-custom" stringData: - password: {{ .Values.smtp.password | quote }} + password: "" diff --git a/helmfile/apps/nubus/values-opendesk-keycloak-bootstrap.yaml.gotmpl b/helmfile/apps/nubus/values-opendesk-keycloak-bootstrap.yaml.gotmpl index 2ce5881a..6044601d 100644 --- a/helmfile/apps/nubus/values-opendesk-keycloak-bootstrap.yaml.gotmpl +++ b/helmfile/apps/nubus/values-opendesk-keycloak-bootstrap.yaml.gotmpl @@ -28,7 +28,8 @@ config: {{ .Values.functional.authentication.oidc.clients | toYaml | nindent 6 }} managed: clientScopes: [ 'acr', 'web-origins', 'email', 'profile', 'microprofile-jwt', 'role_list', 'offline_access', 'roles', 'address', 'phone' ] - clients: [ 'UMC', 'guardian-management-api', 'guardian-scripts', 'guardian-ui', '${client_account}', '${client_account-console}', '${client_admin-cli}', '${client_broker}', '${client_realm-management}', '${client_security-admin-console}' ] + # 'guardian-management-api', 'guardian-scripts', 'guardian-ui' clients have been added explicitly for the moment (see further down this file) + clients: [ 'UMC', '${client_account}', '${client_account-console}', '${client_admin-cli}', '${client_broker}', '${client_realm-management}', '${client_security-admin-console}' ] keycloak: adminUser: "kcadmin" adminPassword: {{ .Values.secrets.keycloak.adminPassword | quote }} @@ -570,6 +571,296 @@ config: post.logout.redirect.uris: "https://{{ .Values.global.hosts.xwiki }}.{{ .Values.global.domain }}/*##https://{{ .Values.global.hosts.nubus }}.{{ .Values.global.domain }}/*" defaultClientScopes: - "opendesk-xwiki-scope" + - name: "guardian-management-api" + clientId: "guardian-management-api" + rootUrl: "https://{{ .Values.global.hosts.nubus }}.{{ .Values.global.domain }}" + baseUrl: "https://{{ .Values.global.hosts.nubus }}.{{ .Values.global.domain }}" + protocol: "openid-connect" + publicClient: false + clientAuthenticatorType: "client-secret" + secret: {{ .Values.secrets.keycloak.clientSecret.guardian | quote }} + redirectUris: + - "https://{{ .Values.global.hosts.nubus }}.{{ .Values.global.domain }}/guardian/*" + fullScopeAllowed: true + standardFlowEnabled: true + implicitFlowEnabled: false + directAccessGrantsEnabled: false + serviceAccountsEnabled: true + protocolMappers: + - name: "Client Host" + protocol: "openid-connect" + protocolMapper: "oidc-usersessionmodel-note-mapper" + consentRequired: false + config: + user.session.note: "clientHost" + userinfo.token.claim: true + id.token.claim: true + access.token.claim: true + claim.name: "clientHost" + jsonType.label: "String" + - name: "Client ID" + protocol: "openid-connect" + protocolMapper: "oidc-usersessionmodel-note-mapper" + consentRequired: false + config: + user.session.note: "client_id" + userinfo.token.claim: true + id.token.claim: true + access.token.claim: true + claim.name: "client_id" + jsonType.label: "String" + - name: "guardian-audience" + protocol: "openid-connect" + protocolMapper: "oidc-audience-mapper" + consentRequired: false + config: + included.client.audience: "guardian" + userinfo.token.claim: false + id.token.claim: false + access.token.claim: true + - name: "audiencemap" + protocol: "openid-connect" + protocolMapper: "oidc-audience-mapper" + consentRequired: false + config: + included.client.audience: "guardian-cli" + userinfo.token.claim: true + id.token.claim: true + access.token.claim: true + - name: "dn" + protocol: "openid-connect" + protocolMapper: "oidc-usermodel-attribute-mapper" + consentRequired: false + config: + userinfo.token.claim: false + user.attribute: "LDAP_ENTRY_DN" + id.token.claim: false + access.token.claim: true + claim.name: "dn" + jsonType.label: "String" + - name: "username" + protocol: "openid-connect" + protocolMapper: "oidc-usermodel-property-mapper" + consentRequired: false + config: + userinfo.token.claim: true + user.attribute: "username" + id.token.claim: true + access.token.claim: true + claim.name: "preferred_username" + jsonType.label: "String" + - name: "uid" + protocol: "openid-connect" + protocolMapper: "oidc-usermodel-attribute-mapper" + consentRequired: false + config: + userinfo.token.claim: true + user.attribute: "uid" + id.token.claim: true + access.token.claim: true + claim.name: "uid" + jsonType.label: "String" + - name: "email" + protocol: "openid-connect" + protocolMapper: "oidc-usermodel-property-mapper" + consentRequired: false + config: + userinfo.token.claim: true + user.attribute: "email" + id.token.claim: true + access.token.claim: true + claim.name: "email" + jsonType.label: "String" + - name: "Client IP Address" + protocol: "openid-connect" + protocolMapper: "oidc-usersessionmodel-note-mapper" + consentRequired: false + config: + user.session.note: "clientAddress" + userinfo.token.claim: true + id.token.claim: true + access.token.claim: true + claim.name: "clientAddress" + jsonType.label: "String" + - name: "guardian-scripts" + clientId: "guardian-scripts" + description: "" + rootUrl: "https://{{ .Values.global.hosts.nubus }}.{{ .Values.global.domain }}" + adminUrl: "https://{{ .Values.global.hosts.nubus }}.{{ .Values.global.domain }}" + baseUrl: "https://{{ .Values.global.hosts.nubus }}.{{ .Values.global.domain }}" + surrogateAuthRequired: false + enabled: true + alwaysDisplayInConsole: false + clientAuthenticatorType: "client-secret" + redirectUris: + - "https://{{ .Values.global.hosts.nubus }}.{{ .Values.global.domain }}/univention/guardian/*" + - "https://{{ .Values.global.hosts.nubus }}.{{ .Values.global.domain }}" + - "https://{{ .Values.global.hosts.nubus }}.{{ .Values.global.domain }}/guardian/*" + webOrigins: + - "https://{{ .Values.global.hosts.nubus }}.{{ .Values.global.domain }}" + bearerOnly: false + consentRequired: false + standardFlowEnabled: true + implicitFlowEnabled: false + directAccessGrantsEnabled: true + serviceAccountsEnabled: false + publicClient: true + frontchannelLogout: false + protocol: "openid-connect" + fullScopeAllowed: true + protocolMappers: + - name: "email" + protocol: "openid-connect" + protocolMapper: "oidc-usermodel-property-mapper" + consentRequired: false + config: + userinfo.token.claim: true + user.attribute: "email" + id.token.claim: true + access.token.claim: true + claim.name: "email" + jsonType.label: "String" + - name: "guardian-audience" + protocol: "openid-connect" + protocolMapper: "oidc-audience-mapper" + consentRequired: false + config: + included.client.audience: "guardian" + id.token.claim: false + access.token.claim: true + userinfo.token.claim: false + - name: "username" + protocol: "openid-connect" + protocolMapper: "oidc-usermodel-property-mapper" + consentRequired: false + config: + userinfo.token.claim: true + user.attribute: "username" + id.token.claim: true + access.token.claim: true + claim.name: "preferred_username" + jsonType.label: "String" + - name: "uid" + protocol: "openid-connect" + protocolMapper: "oidc-usermodel-attribute-mapper" + consentRequired: false + config: + userinfo.token.claim: true + user.attribute: "uid" + id.token.claim: true + access.token.claim: true + claim.name: "uid" + jsonType.label: "String" + - name: "audiencemap" + protocol: "openid-connect" + protocolMapper: "oidc-audience-mapper" + consentRequired: false + config: + included.client.audience: "guardian-scripts" + id.token.claim: true + access.token.claim: true + userinfo.token.claim: true + - name: "dn" + protocol: "openid-connect" + protocolMapper: "oidc-usermodel-attribute-mapper" + consentRequired: false + config: + aggregate.attrs: false + multivalued: false + userinfo.token.claim: false + user.attribute: "LDAP_ENTRY_DN" + id.token.claim: false + access.token.claim: true + claim.name: "dn" + jsonType.label: "String" + defaultClientScopes: + - "web-origins" + - "acr" + - "roles" + - "profile" + - "email" + optionalClientScopes: + - "address" + - "phone" + - "offline_access" + - "microprofile-jwt" + - name: "guardian-ui" + clientId: "guardian-ui" + rootUrl: "https://{{ .Values.global.hosts.nubus }}.{{ .Values.global.domain }}" + baseUrl: "https://{{ .Values.global.hosts.nubus }}.{{ .Values.global.domain }}" + clientAuthenticatorType: "client-secret" + redirectUris: + - "https://{{ .Values.global.hosts.nubus }}.{{ .Values.global.domain }}/univention/guardian/*" + standardFlowEnabled: true + publicClient: true + implicitFlowEnabled: false + directAccessGrantsEnabled: false + serviceAccountsEnabled: false + protocol: "openid-connect" + fullScopeAllowed: true + protocolMappers: + - name: "uid" + protocol: "openid-connect" + protocolMapper: "oidc-usermodel-attribute-mapper" + consentRequired: false + config: + userinfo.token.claim: true + user.attribute: "uid" + id.token.claim: true + access.token.claim: true + claim.name: "uid" + jsonType.label: "String" + - name: "username" + protocol: "openid-connect" + protocolMapper: "oidc-usermodel-property-mapper" + consentRequired: false + config: + userinfo.token.claim: true + user.attribute: "username" + id.token.claim: true + access.token.claim: true + claim.name: "preferred_username" + jsonType.label: "String" + - name: "dn" + protocol: "openid-connect" + protocolMapper: "oidc-usermodel-attribute-mapper" + consentRequired: false + config: + userinfo.token.claim: "false" + user.attribute: "LDAP_ENTRY_DN" + id.token.claim: false + access.token.claim: true + claim.name: "dn" + jsonType.label: "String" + - name: "audiencemap" + protocol: "openid-connect" + protocolMapper: "oidc-audience-mapper" + consentRequired: false + config: + included.client.audience: "guardian" + id.token.claim: true + access.token.claim: true + userinfo.token.claim: true + - name: "email" + protocol: "openid-connect" + protocolMapper: "oidc-usermodel-property-mapper" + consentRequired: false + config: + userinfo.token.claim: true + user.attribute: "email" + id.token.claim: true + access.token.claim: true + claim.name: "email" + jsonType.label: "String" + - name: "guardian-audience" + protocol: "openid-connect" + protocolMapper: "oidc-audience-mapper" + consentRequired: false + config: + included.client.audience: "guardian" + id.token.claim: false + access.token.claim: true + userinfo.token.claim: false containerSecurityContext: allowPrivilegeEscalation: false diff --git a/helmfile/apps/open-xchange/values-dovecot.yaml.gotmpl b/helmfile/apps/open-xchange/values-dovecot.yaml.gotmpl index 0b98959e..b2d9982b 100644 --- a/helmfile/apps/open-xchange/values-dovecot.yaml.gotmpl +++ b/helmfile/apps/open-xchange/values-dovecot.yaml.gotmpl @@ -36,7 +36,7 @@ dovecot: submission: enabled: true ssl: "no" - host: "postfix:25" + host: "{{ printf "%s.%s.svc.%s" "postfix" (.Values.postfix.namespace | default .Release.Namespace) .Values.cluster.networking.domain }}:25" certificate: secretName: {{ .Values.ingress.tls.secretName | quote }} diff --git a/helmfile/apps/openproject/values.yaml.gotmpl b/helmfile/apps/openproject/values.yaml.gotmpl index 76a0d22e..858d6390 100644 --- a/helmfile/apps/openproject/values.yaml.gotmpl +++ b/helmfile/apps/openproject/values.yaml.gotmpl @@ -59,14 +59,14 @@ environment: OPENPROJECT_SOUVAP__NAVIGATION__SECRET: {{ .Values.secrets.centralnavigation.apiKey | quote }} OPENPROJECT_SOUVAP__NAVIGATION__URL: "https://{{ .Values.global.hosts.nubus }}.{{ .Values.global.domain }}/univention/portal/navigation.json?base=https%3A//{{ .Values.global.hosts.nubus }}.{{ .Values.global.domain }}" OPENPROJECT_SMTP__DOMAIN: {{ .Values.global.mailDomain | default .Values.global.domain | quote }} - OPENPROJECT_SMTP__USER__NAME: {{ .Values.smtp.username | quote }} - OPENPROJECT_SMTP__PASSWORD: {{ .Values.smtp.password | quote }} - OPENPROJECT_SMTP__PORT: {{ .Values.smtp.port | quote }} + OPENPROJECT_SMTP__USER__NAME: "" + OPENPROJECT_SMTP__PASSWORD: "" + OPENPROJECT_SMTP__PORT: 25 OPENPROJECT_SMTP__SSL: "false" # (default=false) - OPENPROJECT_SMTP__ADDRESS: {{ .Values.smtp.host | quote }} - OPENPROJECT_SMTP__AUTHENTICATION: "plain" - OPENPROJECT_SMTP__ENABLE__STARTTLS__AUTO: "true" - OPENPROJECT_SMTP__OPENSSL__VERIFY__MODE: "peer" + OPENPROJECT_SMTP__ADDRESS: {{ printf "%s.%s.svc.%s" "postfix" (.Values.postfix.namespace | default .Release.Namespace) .Values.cluster.networking.domain | quote }} + OPENPROJECT_SMTP__AUTHENTICATION: "none" + OPENPROJECT_SMTP__ENABLE__STARTTLS__AUTO: "false" + OPENPROJECT_SMTP__OPENSSL__VERIFY__MODE: "none" OPENPROJECT_MAIL__FROM: "{{ .Values.smtp.localpartNoReply }}@{{ if .Values.functional.email.systemGenerated.useComponentInSenderdomain }}{{ .Values.global.hosts.openproject }}.{{ end }}{{ .Values.global.domain }}" OPENPROJECT_HOME__URL: {{ printf "https://%s.%s/" .Values.global.hosts.nubus .Values.global.domain | quote }} OPENPROJECT_OPENID__CONNECT_KEYCLOAK_ISSUER: "https://{{ .Values.global.hosts.keycloak }}.{{ .Values.global.domain }}/realms/{{ .Values.platform.realm }}" diff --git a/helmfile/apps/services/helmfile-child.yaml b/helmfile/apps/services/helmfile-child.yaml index c0a1a0d7..60c3856b 100644 --- a/helmfile/apps/services/helmfile-child.yaml +++ b/helmfile/apps/services/helmfile-child.yaml @@ -57,6 +57,17 @@ repositories: url: "{{ .Values.global.helmRegistry | default .Values.charts.mariadb.registry }}/\ {{ .Values.charts.mariadb.repository }}" + # openDesk dkimpy-milter + # https://gitlab.opencode.de/bmi/opendesk/components/platform-development/charts/opendesk-dkimpy-milter + - name: "dkimpy-repo" + keyring: "../../files/gpg-pubkeys/opencode.gpg" + verify: {{ .Values.charts.dkimpy.verify }} + username: {{ env "OD_PRIVATE_REGISTRY_USERNAME" | quote }} + password: {{ env "OD_PRIVATE_REGISTRY_PASSWORD" | quote }} + oci: true + url: "{{ .Values.global.helmRegistry | default .Values.charts.dkimpy.registry }}/\ + {{ .Values.charts.dkimpy.repository }}" + # openDesk Postfix # https://gitlab.opencode.de/bmi/opendesk/components/platform-development/charts/opendesk-postfix - name: "postfix-repo" @@ -178,6 +189,14 @@ releases: installed: {{ .Values.postfix.enabled }} timeout: 900 + - name: "opendesk-dkimpy-milter" + chart: "dkimpy-repo/{{ .Values.charts.dkimpy.name }}" + version: "{{ .Values.charts.dkimpy.version }}" + values: + - "values-dkimpy.yaml.gotmpl" + installed: {{ .Values.dkimpy.enabled }} + timeout: 900 + - name: "clamav" chart: "clamav-repo/{{ .Values.charts.clamav.name }}" version: "{{ .Values.charts.clamav.version }}" diff --git a/helmfile/apps/services/values-dkimpy.yaml.gotmpl b/helmfile/apps/services/values-dkimpy.yaml.gotmpl new file mode 100644 index 00000000..71d9edc3 --- /dev/null +++ b/helmfile/apps/services/values-dkimpy.yaml.gotmpl @@ -0,0 +1,44 @@ +# SPDX-FileCopyrightText: Zentrum für Digitale Souveränität der Öffentlichen Verwaltung (ZenDiS) GmbH +# SPDX-License-Identifier: Apache-2.0 +--- +containerSecurityContext: + allowPrivilegeEscalation: true + capabilities: {} + enabled: true + seccompProfile: + type: "RuntimeDefault" + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + privileged: false + seLinuxOptions: + {{ .Values.seLinuxOptions.dkimpy | toYaml | nindent 4 }} + +global: + imagePullSecrets: + {{ .Values.global.imagePullSecrets | toYaml | nindent 4 }} + +image: + registry: {{ .Values.global.imageRegistry | default .Values.images.dkimpy.registry | quote }} + repository: {{ .Values.images.dkimpy.repository | quote }} + tag: {{ .Values.images.dkimpy.tag | quote }} + imagePullPolicy: {{ .Values.global.imagePullPolicy | quote }} + +podSecurityContext: + enabled: true + fsGroup: 1000 + +configuration: + domain: "{{ .Values.global.domain }}{{ if .Values.global.mailDomain }}, {{ .Values.global.mailDomain }}{{ end }}" + key: + {{ .Values.smtp.dkim.key | toYaml | nindent 4 }} + mode: "s" + selector: {{ .Values.smtp.dkim.selector }} + useED25519: {{ .Values.smtp.dkim.useED25519 }} + +replicaCount: {{ .Values.replicas.dkimpy }} + +resources: + {{ .Values.resources.dkimpy | toYaml | nindent 2 }} +... diff --git a/helmfile/apps/services/values-postfix.yaml.gotmpl b/helmfile/apps/services/values-postfix.yaml.gotmpl index 9528e429..82b45177 100644 --- a/helmfile/apps/services/values-postfix.yaml.gotmpl +++ b/helmfile/apps/services/values-postfix.yaml.gotmpl @@ -49,6 +49,9 @@ postfix: - fileName: "sasl_passwd.map" content: - {{ printf "%s %s:%s" .Values.smtp.host .Values.smtp.username .Values.smtp.password | quote }} + {{- if .Values.dkimpy.enabled }} + dkimpyHost: "opendesk-dkimpy-milter.{{ .Release.Namespace }}.svc.{{.Values.cluster.networking.domain }}:8892" + {{- end }} rspamdHost: "" relayHost: {{ if .Values.smtp.host }}{{ printf "[%s]:%d" .Values.smtp.host .Values.smtp.port | quote }}{{ else }}""{{ end }} relayNets: {{ join " " .Values.cluster.networking.cidr | quote }} diff --git a/helmfile/apps/xwiki/values.yaml.gotmpl b/helmfile/apps/xwiki/values.yaml.gotmpl index d73b4b55..24448bde 100644 --- a/helmfile/apps/xwiki/values.yaml.gotmpl +++ b/helmfile/apps/xwiki/values.yaml.gotmpl @@ -138,11 +138,9 @@ properties: "property:xwiki:XWiki.XWikiServerXwiki^XWiki.XWikiServerClass.port": 443 ## SMTP settings "property:xwiki:Mail.MailConfig^Mail.SendMailConfigClass.from": "{{ .Values.smtp.localpartNoReply }}@{{ if .Values.functional.email.systemGenerated.useComponentInSenderdomain }}{{ .Values.global.hosts.xwiki }}.{{ end }}{{ .Values.global.domain }}" - "property:xwiki:Mail.MailConfig^Mail.SendMailConfigClass.host": {{ .Values.smtp.host | quote }} - "property:xwiki:Mail.MailConfig^Mail.SendMailConfigClass.port": {{ .Values.smtp.port | quote }} - "property:xwiki:Mail.MailConfig^Mail.SendMailConfigClass.username": {{ .Values.smtp.username | quote }} - "property:xwiki:Mail.MailConfig^Mail.SendMailConfigClass.password": {{ .Values.smtp.password | quote }} - "property:xwiki:Mail.MailConfig^Mail.SendMailConfigClass.properties": "mail.smtp.starttls.enable=true" + "property:xwiki:Mail.MailConfig^Mail.SendMailConfigClass.host": {{ printf "%s.%s.svc.%s" "postfix" (.Values.postfix.namespace | default .Release.Namespace) .Values.cluster.networking.domain | quote }} + "property:xwiki:Mail.MailConfig^Mail.SendMailConfigClass.port": 25 + "property:xwiki:Mail.MailConfig^Mail.SendMailConfigClass.properties": "mail.smtp.starttls.enable=false" ## Link LDAP users and users authenticated through OIDC "property:xwiki:LDAPUserImport.WebHome^LDAPUserImport.LDAPUserImportConfigClass.addOIDCObject": 1 "property:xwiki:LDAPUserImport.WebHome^LDAPUserImport.LDAPUserImportConfigClass.OIDCIssuer": "https://{{ .Values.global.hosts.keycloak }}.{{ .Values.global.domain }}/realms/{{ .Values.platform.realm }}" diff --git a/helmfile/environments/default/charts.yaml b/helmfile/environments/default/charts.yaml index 425a4cd7..7315c3d4 100644 --- a/helmfile/environments/default/charts.yaml +++ b/helmfile/environments/default/charts.yaml @@ -60,6 +60,18 @@ charts: name: "cryptpad" version: "0.0.19" verify: true + dkimpy: + # providerCategory: "Platform" + # providerResponsible: "openDesk" + # upstreamRegistry: "https://registry.opencode.de" + # upstreamRepository: "bmi/opendesk/components/platform-development/charts/opendesk-dkimpy-milter/opendesk-dkimpy-milter" + # upstreamMirrorTagFilterRegEx: '^(\d+)\.(\d+)\.(\d+)$' + # upstreamMirrorStartFrom: ["1", "0", "0"] + registry: "registry.opencode.de" + repository: "bmi/opendesk/components/platform-development/charts/opendesk-dkimpy-milter" + name: "opendesk-dkimpy-milter" + version: "1.0.0" + verify: true dovecot: # providerCategory: "Platform" # providerResponsible: "Open-Xchange" @@ -78,7 +90,7 @@ charts: registry: "registry.opencode.de" repository: "bmi/opendesk/components/platform-development/charts/opendesk-element" name: "opendesk-element" - version: "3.3.0" + version: "3.3.2" verify: true elementWellKnown: # providerCategory: "Platform" @@ -88,7 +100,7 @@ charts: registry: "registry.opencode.de" repository: "bmi/opendesk/components/platform-development/charts/opendesk-element" name: "opendesk-well-known" - version: "3.3.0" + version: "3.3.2" verify: true home: # providerCategory: "Platform" @@ -180,7 +192,7 @@ charts: registry: "registry.opencode.de" repository: "bmi/opendesk/components/platform-development/charts/opendesk-element" name: "opendesk-matrix-user-verification-service" - version: "3.3.0" + version: "3.3.2" verify: true memcached: # providerCategory: "Community" @@ -338,7 +350,7 @@ charts: registry: "registry.opencode.de" repository: "bmi/opendesk/components/platform-development/charts/opendesk-postfix" name: "postfix" - version: "2.2.0" + version: "2.3.0" verify: true postgresql: # providerCategory: "Platform" @@ -368,7 +380,7 @@ charts: registry: "registry.opencode.de" repository: "bmi/opendesk/components/platform-development/charts/opendesk-element" name: "opendesk-synapse" - version: "3.3.0" + version: "3.3.2" verify: true synapseCreateAccount: # providerCategory: "Platform" @@ -378,7 +390,7 @@ charts: registry: "registry.opencode.de" repository: "bmi/opendesk/components/platform-development/charts/opendesk-element" name: "opendesk-synapse-create-account" - version: "3.3.0" + version: "3.3.2" verify: true synapseWeb: # providerCategory: "Platform" @@ -388,7 +400,7 @@ charts: registry: "registry.opencode.de" repository: "bmi/opendesk/components/platform-development/charts/opendesk-element" name: "opendesk-synapse-web" - version: "3.3.0" + version: "3.3.2" verify: true xwiki: # providerCategory: "Supplier" diff --git a/helmfile/environments/default/images.yaml b/helmfile/environments/default/images.yaml index bc5ed919..215538e4 100644 --- a/helmfile/environments/default/images.yaml +++ b/helmfile/environments/default/images.yaml @@ -30,6 +30,14 @@ images: registry: "registry.opencode.de" repository: "bmi/opendesk/components/supplier/xwiki/images-mirror/cryptpad" tag: "opendesk-20231222@sha256:f4d20d5c38c87b11ed1a1b46ef6a3633d32c6758ebdff8556458f040318fa5e2" + dkimpy: + # providerCategory: "Platform" + # providerResponsible: "openDesk" + # upstreamRegistry: "https://registry.opencode.de" + # upstreamRepository: "bmi/opendesk/components/platform-development/images/dkimpy-milter" + registry: "registry.opencode.de" + repository: "bmi/opendesk/components/platform-development/images/dkimpy-milter" + tag: "1.1.0@sha256:f140c7fc3fd9636addc612edd6e10f6aefa69e34ff637c95ce9036a32e44555f" dovecot: # providerCategory: "Supplier" # providerResponsible: "Open-Xchange" @@ -763,7 +771,7 @@ images: # upstreamRepository: "bmi/opendesk/components/platform-development/images/postfix" registry: "registry.opencode.de" repository: "bmi/opendesk/components/platform-development/images/postfix" - tag: "1.0.0@sha256:61e4661a7323101dfb51c85c5a48c345c75436f3f533176f049d2660d711a8a5" + tag: "2.0.0@sha256:5b2432dc09318db172a593bca860887ee9d713b9987db64f8b265f3e08a1d374" postgresql: # providerCategory: "Community" # providerResponsible: "openDesk" diff --git a/helmfile/environments/default/opendesk_main.gotmpl b/helmfile/environments/default/opendesk_main.gotmpl index 841fb9ed..3d8b0006 100644 --- a/helmfile/environments/default/opendesk_main.gotmpl +++ b/helmfile/environments/default/opendesk_main.gotmpl @@ -19,6 +19,9 @@ collabora: cryptpad: enabled: true namespace: ~ +dkimpy: + enabled: false + namespace: ~ dovecot: enabled: true namespace: ~ diff --git a/helmfile/environments/default/replicas.yaml b/helmfile/environments/default/replicas.yaml index 5b29fd23..c3c05b4c 100644 --- a/helmfile/environments/default/replicas.yaml +++ b/helmfile/environments/default/replicas.yaml @@ -36,6 +36,8 @@ replicas: dovecot: 1 # -- scalable: false postfix: 1 + # -- scalable: true + dkimpy: 1 # -- component: Chat (Element, Synapse) # -- scalable: true diff --git a/helmfile/environments/default/resources.yaml b/helmfile/environments/default/resources.yaml index 628f04db..349af5cd 100644 --- a/helmfile/environments/default/resources.yaml +++ b/helmfile/environments/default/resources.yaml @@ -25,6 +25,13 @@ resources: requests: cpu: 0.1 memory: "512Mi" + dkimpy: + limits: + cpu: 99 + memory: "256Mi" + requests: + cpu: 0.1 + memory: "128Mi" dovecot: limits: cpu: 99 diff --git a/helmfile/environments/default/selinux.yaml b/helmfile/environments/default/selinux.yaml index 6e95a4b0..fbe3c190 100644 --- a/helmfile/environments/default/selinux.yaml +++ b/helmfile/environments/default/selinux.yaml @@ -11,6 +11,7 @@ seLinuxOptions: clamd: ~ collabora: ~ cryptpad: ~ + dkimpy: ~ dovecot: ~ element: ~ freshclam: ~ diff --git a/helmfile/environments/default/smtp.gotmpl b/helmfile/environments/default/smtp.gotmpl index 1a24a2aa..6b679eeb 100644 --- a/helmfile/environments/default/smtp.gotmpl +++ b/helmfile/environments/default/smtp.gotmpl @@ -9,4 +9,17 @@ smtp: username: "" password: {{ env "SMTP_PASSWORD" | quote }} localpartNoReply: "no-reply" + + # For the following settings to have effect `dkimpy.enabled` must be `true`. + dkim: + key: + # DKIM private key as plaintext value. + value: "" + + # DKIM private key from existing secret. As a higher precedence than the plain `value`. + secret: + name: "" + key: "" + selector: "rsa" + useED25519: false ...