From bd8f915bee139edfc8723d7f532fa83da37843b6 Mon Sep 17 00:00:00 2001
From: Sheogorath <sheogorath@shivering-isles.com>
Date: Sun, 26 Nov 2023 23:58:57 +0100
Subject: [PATCH] feat(mok): Use helm for postfix configuration

---
 charts/mok/Chart.yaml                         |   2 +-
 charts/mok/README.md                          |   2 +-
 charts/mok/templates/postfix-config.yaml      | 365 ++++++++++++++
 charts/mok/templates/postfix.yaml             |  75 ++-
 .../tests/__snapshot__/postfix_test.yaml.snap | 474 +++++++++++++++++-
 charts/mok/tests/helmlabels_test.yaml         |   1 +
 charts/mok/tests/postfix_test.yaml            |   8 +-
 7 files changed, 915 insertions(+), 12 deletions(-)
 create mode 100644 charts/mok/templates/postfix-config.yaml

diff --git a/charts/mok/Chart.yaml b/charts/mok/Chart.yaml
index a50ec04ed..24505d9af 100644
--- a/charts/mok/Chart.yaml
+++ b/charts/mok/Chart.yaml
@@ -3,7 +3,7 @@ name: mok
 description: |
   Mail on Kubernetes (MoK) is a project to deploy a functional mailserver that runs without a database server on Kubernetes, taking advantage of configmaps and secret.
 type: application
-version: 0.9.7
+version: 0.10.0
 sources:
   - https://de.postfix.org/ftpmirror/index.html
   - https://github.com/dovecot/core
diff --git a/charts/mok/README.md b/charts/mok/README.md
index 35d03532f..333448018 100644
--- a/charts/mok/README.md
+++ b/charts/mok/README.md
@@ -1,6 +1,6 @@
 # mok
 
-![Version: 0.9.7](https://img.shields.io/badge/Version-0.9.7-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)
+![Version: 0.10.0](https://img.shields.io/badge/Version-0.10.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)
 
 Mail on Kubernetes (MoK) is a project to deploy a functional mailserver that runs without a database server on Kubernetes, taking advantage of configmaps and secret.
 
diff --git a/charts/mok/templates/postfix-config.yaml b/charts/mok/templates/postfix-config.yaml
new file mode 100644
index 000000000..fcfcece13
--- /dev/null
+++ b/charts/mok/templates/postfix-config.yaml
@@ -0,0 +1,365 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: {{ include "mok.fullname" . }}-postfix
+  labels:
+    {{- include "mok.labels" . | nindent 4 }}
+    app.kubernetes.io/component: postfix
+data:
+  master.conf: |
+    # ==========================================================================
+    # service type  private unpriv  chroot  wakeup  maxproc command + args
+    #               (yes)   (yes)   (yes)   (never) (100)
+    # ==========================================================================
+    10025      inet  n       -       -       -       1       postscreen
+        -o postscreen_upstream_proxy_protocol=haproxy
+        -o syslog_name=postfix/10025
+    smtpd     pass  -       -       -       -       -       smtpd
+        -o smtpd_tls_received_header=yes
+        -o content_filter=
+    dnsblog   unix  -       -       -       -       0       dnsblog
+    tlsproxy  unix  -       -       -       -       0       tlsproxy
+    postlog   unix-dgram n  -       n       -       1       postlogd
+    #smtps     inet  n       -       -       -       -       smtpd
+    #  -o syslog_name=postfix/smtps
+    #  -o smtpd_tls_wrappermode=yes
+    #  -o smtpd_sasl_auth_enable=yes
+    #  -o smtpd_reject_unlisted_recipient=no
+    #  -o smtpd_client_restrictions=$mua_client_restrictions
+    #  -o smtpd_helo_restrictions=$mua_helo_restrictions
+    #  -o smtpd_sender_restrictions=$mua_sender_restrictions
+    #  -o smtpd_recipient_restrictions=
+    #  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
+    #  -o milter_macro_daemon_name=ORIGINATING
+    #628       inet  n       -       -       -       -       qmqpd
+    smtp       inet  n       -       y       -       -       smtpd
+        -o smtpd_tls_received_header=yes
+        -o content_filter=
+    pickup     unix  n       -       y       60      1       pickup
+        -o receive_override_options=no_header_body_checks
+    cleanup    unix  n       -       y       -       0       cleanup
+    qmgr      unix  n       -       n       300     1       qmgr
+    #qmgr     unix  n       -       n       300     1       oqmgr
+    tlsmgr     unix  -       -       y       1000?   1       tlsmgr
+    rewrite    unix  -       -       y       -       -       trivial-rewrite
+    bounce     unix  -       -       y       -       0       bounce
+    defer      unix  -       -       y       -       0       bounce
+    trace      unix  -       -       y       -       0       bounce
+    verify     unix  -       -       y       -       1       verify
+    flush      unix  n       -       y       1000?   0       flush
+    proxymap  unix  -       -       n       -       -       proxymap
+    proxywrite unix -       -       n       -       1       proxymap
+    smtp       unix  -       -       y       -       -       smtp
+    #       -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
+    relay      unix  -       -       y       -       -       smtp
+    showq      unix  n       -       y       -       -       showq
+    error      unix  -       -       y       -       -       error
+    retry      unix  -       -       y       -       -       error
+    discard    unix  -       -       y       -       -       discard
+    local     unix  -       n       n       -       -       local
+    virtual   unix  -       n       n       -       -       virtual
+    lmtp       unix  -       -       y       -       -       lmtp
+    anvil      unix  -       -       y       -       1       anvil
+    #
+    # ====================================================================
+    # Interfaces to non-Postfix software. Be sure to examine the manual
+    # pages of the non-Postfix software to find out what options it wants.
+    #
+    # Many of the following services use the Postfix pipe(8) delivery
+    # agent.  See the pipe(8) man page for information about ${recipient}
+    # and other message envelope options.
+    # ====================================================================
+    #
+    # maildrop. See the Postfix MAILDROP_README file for details.
+    # Also specify in main.cf: maildrop_destination_recipient_limit=1
+    #
+    scache     unix  -       -       y       -       1       scache
+    maildrop  unix  -       n       n       -       -       pipe
+      flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
+    #
+    # ====================================================================
+    #
+    # Recent Cyrus versions can use the existing "lmtp" master.cf entry.
+    #
+    # Specify in cyrus.conf:
+    #   lmtp    cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4
+    #
+    # Specify in main.cf one or more of the following:
+    #  mailbox_transport = lmtp:inet:localhost
+    #  virtual_transport = lmtp:inet:localhost
+    #
+    # ====================================================================
+    #
+    # Cyrus 2.1.5 (Amos Gouaux)
+    # Also specify in main.cf: cyrus_destination_recipient_limit=1
+    #
+    #cyrus     unix  -       n       n       -       -       pipe
+    #  user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user}
+    #
+    # ====================================================================
+    # Old example of delivery via Cyrus.
+    #
+    #old-cyrus unix  -       n       n       -       -       pipe
+    #  flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user}
+    #
+    # ====================================================================
+    #
+    # See the Postfix UUCP_README file for configuration details.
+    #
+    uucp      unix  -       n       n       -       -       pipe
+      flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
+    #
+    # Other external delivery methods.
+    #
+    ifmail    unix  -       n       n       -       -       pipe
+      flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
+    bsmtp     unix  -       n       n       -       -       pipe
+      flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
+    scalemail-backend unix	-	n	n	-	2	pipe
+      flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
+    mailman   unix  -       n       n       -       -       pipe
+      flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
+      ${nexthop} ${user}
+
+    submission inet  n       -       y       -       -       smtpd
+        -o syslog_name=postfix/submission
+        -o smtpd_tls_security_level=encrypt
+        -o tls_preempt_cipherlist=yes
+        -o smtpd_sasl_auth_enable=yes
+        -o smtpd_tls_auth_only=yes
+        -o smtpd_reject_unlisted_recipient=no
+        -o smtpd_recipient_restrictions=
+        -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
+        -o smtpd_sender_login_maps=lmdb:/srv/tmp/sender-login-maps
+        -o sender_dependent_relayhost_maps=lmdb:/srv/tmp/relayhosts
+        -o cleanup_service_name=headers-cleanup
+
+    submissions inet  n       -       y       -       -       smtpd
+        -o syslog_name=postfix/submissions
+        -o smtpd_tls_wrappermode=yes
+        -o smtpd_tls_security_level=encrypt
+        -o tls_preempt_cipherlist=yes
+        -o smtpd_sasl_auth_enable=yes
+        -o smtpd_tls_auth_only=yes
+        -o smtpd_reject_unlisted_recipient=no
+        -o smtpd_recipient_restrictions=
+        -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
+        -o smtpd_sender_login_maps=lmdb:/srv/tmp/sender-login-maps
+        -o sender_dependent_relayhost_maps=lmdb:/srv/tmp/relayhosts
+        -o cleanup_service_name=headers-cleanup
+
+    dovecot   unix  -       n       n       -       -       pipe flags=DRhu
+      user=vmail:vmail argv=/usr/lib/dovecot/deliver -d ${recipient}
+
+    #smtp-amavis unix -       -       y       -       2       smtp
+    #    -o smtp_data_done_timeout=1800
+    #    -o smtp_send_xforward_command=yes
+    #    -o disable_mime_output_conversion=yes
+    #    -o smtp_generic_maps=
+
+    #127.0.0.1:10025 inet n   -       y       -       -       smtpd
+    #    -o content_filter=
+    #    -o smtpd_proxy_filter=
+    #    -o smtpd_authorized_xforward_hosts=127.0.0.0/8
+    #    -o smtpd_client_restrictions=
+    #    -o smtpd_helo_restrictions=
+    #    -o smtpd_sender_restrictions=
+    #    -o smtpd_recipient_restrictions=permit_mynetworks,reject
+    #    -o smtpd_data_restrictions=
+    #    -o mynetworks=127.0.0.0/8
+    #    -o receive_override_options=no_unknown_recipient_checks
+    ##        -o header_checks=pcre:/etc/postfix/submission_header_checks.pcre
+
+
+    #127.0.0.1:10027 inet n   -       y       -       -       smtpd
+    #    -o content_filter=smtp-amavis:[127.0.0.1]:10028
+    #    -o smtpd_proxy_filter=
+    #    -o smtpd_authorized_xforward_hosts=127.0.0.0/8
+    #    -o smtpd_client_restrictions=
+    #    -o smtpd_helo_restrictions=
+    #    -o smtpd_sender_restrictions=
+    #    -o smtpd_recipient_restrictions=permit_mynetworks,reject
+    #    -o smtpd_data_restrictions=
+    #    -o mynetworks=127.0.0.0/8
+    #    -o receive_override_options=no_unknown_recipient_checks
+    #    -o cleanup_service_name=subcleanup
+
+    subcleanup unix  n       -       y       -       0       cleanup
+    #    -o header_checks=pcre:/srv/config/submission_header_checks.pcre
+
+    headers-cleanup unix n - - - 0 cleanup
+    -o syslog_name=postfix/headers-cleanup
+    -o header_checks=regexp:/etc/postfix/header_checks
+  main.conf: |
+    ############### Please enable soft_bounce during maintenance: #################
+
+    # Fatal 5xx Errors will be downgraded to temporary 4xx Errors.
+    #soft_bounce = yes
+
+    ###############################################################################
+
+    smtpd_banner = $myhostname ESMTP $mail_name
+    biff = no
+
+    append_dot_mydomain = no
+
+    readme_directory = no
+
+    mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
+    mydestination =
+    mailbox_size_limit = 51200000
+    message_size_limit = 51200000
+    recipient_delimiter = +
+    inet_interfaces = all
+    myorigin = /etc/mailname
+    inet_protocols = all
+    maillog_file = /dev/stdout
+
+    ########
+    ##
+    ## TLS Configuration
+    ##
+
+    smtpd_tls_cert_file=/srv/tls/tls.crt
+    smtpd_tls_key_file=/srv/tls/tls.key
+    smtpd_tls_loglevel = 1
+
+    smtp_tls_cert_file=/srv/tls/tls.crt
+    smtp_tls_key_file=/srv/tls/tls.key
+    smtp_tls_loglevel = 1
+
+    smtpd_tls_security_level = may
+    smtp_tls_security_level = may
+
+    # generated 2023-02-26, Mozilla Guideline v5.6, Postfix 3.4.8, OpenSSL 1.1.1k, intermediate configuration
+    # https://ssl-config.mozilla.org/#server=postfix&version=3.4.8&config=intermediate&openssl=1.1.1k&guideline=5.6
+    smtpd_tls_auth_only = yes
+    smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
+    smtp_tls_mandatory_protocols = !SSLv2, !SSLv3
+    lmtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
+    smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
+    smtp_tls_protocols = !SSLv2, !SSLv3
+    lmtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
+    smtpd_tls_mandatory_ciphers = medium
+
+    tls_medium_cipherlist = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
+    tls_preempt_cipherlist = no
+    tls_ssl_options = NO_COMPRESSION
+
+    smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
+    smtpd_tls_dh1024_param_file = /etc/postfix/postfix_dhparams.pem
+
+    smtp_tls_policy_maps = lmdb:/srv/tmp/tls-policies
+
+    ########
+    ##
+    ## SASL Configuration Configuration
+    ##
+
+    smtpd_sasl_type = dovecot
+    
+    smtpd_sasl_path = inet:{{ include "mok.fullname" . }}-dovecot-internal.{{ .Release.Namespace }}.svc.cluster.local:12345
+    smtpd_sasl_auth_enable = yes
+    broken_sasl_auth_clients = yes
+    smtpd_sasl_security_options = noanonymous, noplaintext
+    smtpd_sasl_tls_security_options = noanonymous
+    smtpd_tls_auth_only = yes
+
+    lmtp_host_lookup = dns, native
+    virtual_transport = lmtp:inet:{{ include "mok.fullname" . }}-dovecot-internal.{{ .Release.Namespace }}.svc.cluster.local:24"
+
+    ########
+    ##
+    ## Postscreen Configuration
+    ##
+
+    postscreen_upstream_proxy_protocol = haproxy
+    postscreen_upstream_proxy_timeout = 5s
+    postscreen_access_list = permit_mynetworks
+    postscreen_blacklist_action = drop
+    postscreen_greet_action = ignore
+    # Disable zombie detection
+    postscreen_greet_banner =
+    postscreen_dnsbl_action = enforce
+    postscreen_dnsbl_threshold = 3
+    postscreen_dnsbl_allowlist_threshold = -1
+    postscreen_dnsbl_sites =
+            zen.spamhaus.org=127.0.1.[2..254]*3,
+            ix.dnsbl.manitu.net*3,
+            bl.spamcop.net,
+            b.barracudacentral.org,
+            safe.dnsbl.sorbs.net,
+            swl.spamhaus.org*-10,
+
+    ########
+    ##
+    ## SMTPD Restrictions Configuration
+    ##
+
+    smtpd_recipient_restrictions =
+    #        check_recipient_access btree:/srv/config/access_recipient,
+    #        check_recipient_access pgsql:/srv/tmp/recipient-access.cf
+    #        check_client_access cidr:/srv/config/access_client,
+    #        check_helo_access btree:/srv/config/access_helo,
+    #        check_sender_access btree:/srv/config/access_sender,
+            reject_non_fqdn_sender,
+            reject_non_fqdn_recipient,
+            reject_unknown_sender_domain,
+            reject_unknown_recipient_domain,
+            reject_invalid_hostname,
+            warn_if_reject reject_unauth_pipelining,
+            permit_mynetworks,
+            reject_unauth_destination,
+            reject_known_sender_login_mismatch,
+            reject_unverified_recipient,
+            permit
+
+    smtpd_sender_restrictions =
+            permit_mynetworks,
+            reject_non_fqdn_sender,
+            reject_authenticated_sender_login_mismatch,
+            permit_sasl_authenticated
+
+    #smtpd_restriction_classes = local_only
+    #local_only =
+    #        check_recipient_access btree:/srv/config/local_domains,
+    #        check_sender_access regexp:/srv/config/local_only_reject.regexp
+
+    ########
+    ##
+    ## Virtual Maps Configuration
+    ##
+
+    virtual_uid_maps = static:5000
+    virtual_gid_maps = static:5000
+
+    virtual_alias_maps = lmdb:/srv/tmp/aliases
+    virtual_mailbox_maps = lmdb:/srv/tmp/mailboxes
+    virtual_mailbox_domains = lmdb:/srv/tmp/domains
+    local_recipient_maps = $virtual_mailbox_maps
+
+    ## Relay config
+
+    sender_dependent_relayhost_maps = lmdb:/srv/tmp/relayhosts
+
+    ## SMTP sasl
+
+    smtp_sasl_auth_enable = yes
+    smtp_sasl_security_options = noanonymous
+    smtp_sasl_tls_security_options = noanonymous
+    smtp_sasl_password_maps = lmdb:/srv/tmp/sasl_passwd
+    smtp_tls_note_starttls_offer = yes
+
+    ########
+    ##
+    ## Miscellaneous
+    ##
+
+    default_database_type = btree
+
+    #mime_header_checks = pcre:/srv/config/mime_header_checks.pcre
+
+    maximal_queue_lifetime = 1d
+    bounce_queue_lifetime = 1d
+    unverified_recipient_reject_code = 577
+    compatibility_level = 2
diff --git a/charts/mok/templates/postfix.yaml b/charts/mok/templates/postfix.yaml
index 7fc95dae7..0515fe16a 100644
--- a/charts/mok/templates/postfix.yaml
+++ b/charts/mok/templates/postfix.yaml
@@ -54,7 +54,8 @@ spec:
   template:
     metadata:
       annotations:
-        checksum/config: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
+        checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
+        checksum/config: {{ include (print $.Template.BasePath "/postfix-config.yaml") . | sha256sum }}
         {{- with .Values.postfix.podAnnotations }}
         {{- toYaml . | nindent 8 }}
         {{- end }}
@@ -69,6 +70,61 @@ spec:
       serviceAccountName: {{ include "mok.serviceAccountName" . }}
       securityContext:
         {{- toYaml .Values.postfix.podSecurityContext | nindent 8 }}
+      initContainer:
+        - name: postmap
+          image: {{ .Values.postfix.image.repository }}:{{.Values.postfix.image.tag | default "latest" }}
+          imagePullPolicy: {{ .Values.postfix.image.pullPolicy }}
+          command:
+            - sh
+            - -c
+            - cp /srv/virtual/* /srv/tmp && find /srv/tmp -type f -exec postmap lmdb://{} \;
+          resources:
+            requests:
+              cpu: 100m
+              memory: 64Mi
+            limits:
+              cpu: 100m
+              memory: 64Mi
+          securityContext:
+            {{- toYaml .Values.postfix.securityContext | nindent 12 }}
+          volumeMounts:
+            - name: spool
+              mountPath: /var/spool/postfix/
+            - name: cache
+              mountPath: "/srv/tmp"
+            - name: maps
+              mountPath: "/srv/virtual"
+              readOnly: true
+            - name: tls
+              mountPath: "/srv/tls"
+              readOnly: true
+        - name: fill-chroot
+          image: {{ .Values.postfix.image.repository }}:{{.Values.postfix.image.tag | default "latest" }}
+          imagePullPolicy: {{ .Values.postfix.image.pullPolicy }}
+          command:
+            - sh
+            - -c
+            - mkdir -p /var/spool/postfix/etc/ && cp /etc/resolv.conf /var/spool/postfix/etc/
+          resources:
+            requests:
+              cpu: 100m
+              memory: 64Mi
+            limits:
+              cpu: 100m
+              memory: 64Mi
+          securityContext:
+            {{- toYaml .Values.postfix.securityContext | nindent 12 }}
+          volumeMounts:
+            - name: spool
+              mountPath: /var/spool/postfix/
+            - name: cache
+              mountPath: "/srv/tmp"
+            - name: maps
+              mountPath: "/srv/virtual"
+              readOnly: true
+            - name: tls
+              mountPath: "/srv/tls"
+              readOnly: true
       containers:
         - name: postfix
           env:
@@ -80,6 +136,12 @@ spec:
             {{- end }}
           image: {{ .Values.postfix.image.repository }}:{{.Values.postfix.image.tag | default "latest" }}
           imagePullPolicy: {{ .Values.postfix.image.pullPolicy }}
+          workingDir: /etc/postfix
+          command:
+            - postfix
+            - -c
+            - /etc/postfix
+            - start-fg
           lifecycle:
             preStop:
               exec:
@@ -136,6 +198,12 @@ spec:
           securityContext:
             {{- toYaml .Values.postfix.securityContext | nindent 12 }}
           volumeMounts:
+            - name: config
+              mountPath: /etc/postfix/master.conf
+              subPath: master.conf
+            - name: config
+              mountPath: /etc/postfix/main.conf
+              subPath: main.conf
             - name: spool
               mountPath: /var/spool/postfix/
             - name: cache
@@ -162,6 +230,9 @@ spec:
         - name: maps
           secret:
             secretName: {{ include "mok.fullname" . }}-postfix-maps
+        - name: config
+          configMap:
+            name: {{ include "mok.fullname" . }}-postfix
         - name: tls
           secret:
             secretName: {{ required "TLS secret for postfix is required" .Values.postfix.tls.secretName }}
@@ -182,4 +253,4 @@ spec:
     matchLabels:
       {{- include "mok.selectorLabels" . | nindent 6 }}
       app.kubernetes.io/component: postfix
-{{- end}}
+{{- end }}
diff --git a/charts/mok/tests/__snapshot__/postfix_test.yaml.snap b/charts/mok/tests/__snapshot__/postfix_test.yaml.snap
index c9f527256..fe23e3067 100644
--- a/charts/mok/tests/__snapshot__/postfix_test.yaml.snap
+++ b/charts/mok/tests/__snapshot__/postfix_test.yaml.snap
@@ -1,5 +1,374 @@
 should match snapshot:
   1: |
+    apiVersion: v1
+    data:
+      main.conf: |
+        ############### Please enable soft_bounce during maintenance: #################
+
+        # Fatal 5xx Errors will be downgraded to temporary 4xx Errors.
+        #soft_bounce = yes
+
+        ###############################################################################
+
+        smtpd_banner = $myhostname ESMTP $mail_name
+        biff = no
+
+        append_dot_mydomain = no
+
+        readme_directory = no
+
+        mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
+        mydestination =
+        mailbox_size_limit = 51200000
+        message_size_limit = 51200000
+        recipient_delimiter = +
+        inet_interfaces = all
+        myorigin = /etc/mailname
+        inet_protocols = all
+        maillog_file = /dev/stdout
+
+        ########
+        ##
+        ## TLS Configuration
+        ##
+
+        smtpd_tls_cert_file=/srv/tls/tls.crt
+        smtpd_tls_key_file=/srv/tls/tls.key
+        smtpd_tls_loglevel = 1
+
+        smtp_tls_cert_file=/srv/tls/tls.crt
+        smtp_tls_key_file=/srv/tls/tls.key
+        smtp_tls_loglevel = 1
+
+        smtpd_tls_security_level = may
+        smtp_tls_security_level = may
+
+        # generated 2023-02-26, Mozilla Guideline v5.6, Postfix 3.4.8, OpenSSL 1.1.1k, intermediate configuration
+        # https://ssl-config.mozilla.org/#server=postfix&version=3.4.8&config=intermediate&openssl=1.1.1k&guideline=5.6
+        smtpd_tls_auth_only = yes
+        smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
+        smtp_tls_mandatory_protocols = !SSLv2, !SSLv3
+        lmtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
+        smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
+        smtp_tls_protocols = !SSLv2, !SSLv3
+        lmtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
+        smtpd_tls_mandatory_ciphers = medium
+
+        tls_medium_cipherlist = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
+        tls_preempt_cipherlist = no
+        tls_ssl_options = NO_COMPRESSION
+
+        smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
+        smtpd_tls_dh1024_param_file = /etc/postfix/postfix_dhparams.pem
+
+        smtp_tls_policy_maps = lmdb:/srv/tmp/tls-policies
+
+        ########
+        ##
+        ## SASL Configuration Configuration
+        ##
+
+        smtpd_sasl_type = dovecot
+
+        smtpd_sasl_path = inet:RELEASE-NAME-mok-dovecot-internal.NAMESPACE.svc.cluster.local:12345
+        smtpd_sasl_auth_enable = yes
+        broken_sasl_auth_clients = yes
+        smtpd_sasl_security_options = noanonymous, noplaintext
+        smtpd_sasl_tls_security_options = noanonymous
+        smtpd_tls_auth_only = yes
+
+        lmtp_host_lookup = dns, native
+        virtual_transport = lmtp:inet:RELEASE-NAME-mok-dovecot-internal.NAMESPACE.svc.cluster.local:24"
+
+        ########
+        ##
+        ## Postscreen Configuration
+        ##
+
+        postscreen_upstream_proxy_protocol = haproxy
+        postscreen_upstream_proxy_timeout = 5s
+        postscreen_access_list = permit_mynetworks
+        postscreen_blacklist_action = drop
+        postscreen_greet_action = ignore
+        # Disable zombie detection
+        postscreen_greet_banner =
+        postscreen_dnsbl_action = enforce
+        postscreen_dnsbl_threshold = 3
+        postscreen_dnsbl_allowlist_threshold = -1
+        postscreen_dnsbl_sites =
+                zen.spamhaus.org=127.0.1.[2..254]*3,
+                ix.dnsbl.manitu.net*3,
+                bl.spamcop.net,
+                b.barracudacentral.org,
+                safe.dnsbl.sorbs.net,
+                swl.spamhaus.org*-10,
+
+        ########
+        ##
+        ## SMTPD Restrictions Configuration
+        ##
+
+        smtpd_recipient_restrictions =
+        #        check_recipient_access btree:/srv/config/access_recipient,
+        #        check_recipient_access pgsql:/srv/tmp/recipient-access.cf
+        #        check_client_access cidr:/srv/config/access_client,
+        #        check_helo_access btree:/srv/config/access_helo,
+        #        check_sender_access btree:/srv/config/access_sender,
+                reject_non_fqdn_sender,
+                reject_non_fqdn_recipient,
+                reject_unknown_sender_domain,
+                reject_unknown_recipient_domain,
+                reject_invalid_hostname,
+                warn_if_reject reject_unauth_pipelining,
+                permit_mynetworks,
+                reject_unauth_destination,
+                reject_known_sender_login_mismatch,
+                reject_unverified_recipient,
+                permit
+
+        smtpd_sender_restrictions =
+                permit_mynetworks,
+                reject_non_fqdn_sender,
+                reject_authenticated_sender_login_mismatch,
+                permit_sasl_authenticated
+
+        #smtpd_restriction_classes = local_only
+        #local_only =
+        #        check_recipient_access btree:/srv/config/local_domains,
+        #        check_sender_access regexp:/srv/config/local_only_reject.regexp
+
+        ########
+        ##
+        ## Virtual Maps Configuration
+        ##
+
+        virtual_uid_maps = static:5000
+        virtual_gid_maps = static:5000
+
+        virtual_alias_maps = lmdb:/srv/tmp/aliases
+        virtual_mailbox_maps = lmdb:/srv/tmp/mailboxes
+        virtual_mailbox_domains = lmdb:/srv/tmp/domains
+        local_recipient_maps = $virtual_mailbox_maps
+
+        ## Relay config
+
+        sender_dependent_relayhost_maps = lmdb:/srv/tmp/relayhosts
+
+        ## SMTP sasl
+
+        smtp_sasl_auth_enable = yes
+        smtp_sasl_security_options = noanonymous
+        smtp_sasl_tls_security_options = noanonymous
+        smtp_sasl_password_maps = lmdb:/srv/tmp/sasl_passwd
+        smtp_tls_note_starttls_offer = yes
+
+        ########
+        ##
+        ## Miscellaneous
+        ##
+
+        default_database_type = btree
+
+        #mime_header_checks = pcre:/srv/config/mime_header_checks.pcre
+
+        maximal_queue_lifetime = 1d
+        bounce_queue_lifetime = 1d
+        unverified_recipient_reject_code = 577
+        compatibility_level = 2
+      master.conf: |
+        # ==========================================================================
+        # service type  private unpriv  chroot  wakeup  maxproc command + args
+        #               (yes)   (yes)   (yes)   (never) (100)
+        # ==========================================================================
+        10025      inet  n       -       -       -       1       postscreen
+            -o postscreen_upstream_proxy_protocol=haproxy
+            -o syslog_name=postfix/10025
+        smtpd     pass  -       -       -       -       -       smtpd
+            -o smtpd_tls_received_header=yes
+            -o content_filter=
+        dnsblog   unix  -       -       -       -       0       dnsblog
+        tlsproxy  unix  -       -       -       -       0       tlsproxy
+        postlog   unix-dgram n  -       n       -       1       postlogd
+        #smtps     inet  n       -       -       -       -       smtpd
+        #  -o syslog_name=postfix/smtps
+        #  -o smtpd_tls_wrappermode=yes
+        #  -o smtpd_sasl_auth_enable=yes
+        #  -o smtpd_reject_unlisted_recipient=no
+        #  -o smtpd_client_restrictions=$mua_client_restrictions
+        #  -o smtpd_helo_restrictions=$mua_helo_restrictions
+        #  -o smtpd_sender_restrictions=$mua_sender_restrictions
+        #  -o smtpd_recipient_restrictions=
+        #  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
+        #  -o milter_macro_daemon_name=ORIGINATING
+        #628       inet  n       -       -       -       -       qmqpd
+        smtp       inet  n       -       y       -       -       smtpd
+            -o smtpd_tls_received_header=yes
+            -o content_filter=
+        pickup     unix  n       -       y       60      1       pickup
+            -o receive_override_options=no_header_body_checks
+        cleanup    unix  n       -       y       -       0       cleanup
+        qmgr      unix  n       -       n       300     1       qmgr
+        #qmgr     unix  n       -       n       300     1       oqmgr
+        tlsmgr     unix  -       -       y       1000?   1       tlsmgr
+        rewrite    unix  -       -       y       -       -       trivial-rewrite
+        bounce     unix  -       -       y       -       0       bounce
+        defer      unix  -       -       y       -       0       bounce
+        trace      unix  -       -       y       -       0       bounce
+        verify     unix  -       -       y       -       1       verify
+        flush      unix  n       -       y       1000?   0       flush
+        proxymap  unix  -       -       n       -       -       proxymap
+        proxywrite unix -       -       n       -       1       proxymap
+        smtp       unix  -       -       y       -       -       smtp
+        #       -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
+        relay      unix  -       -       y       -       -       smtp
+        showq      unix  n       -       y       -       -       showq
+        error      unix  -       -       y       -       -       error
+        retry      unix  -       -       y       -       -       error
+        discard    unix  -       -       y       -       -       discard
+        local     unix  -       n       n       -       -       local
+        virtual   unix  -       n       n       -       -       virtual
+        lmtp       unix  -       -       y       -       -       lmtp
+        anvil      unix  -       -       y       -       1       anvil
+        #
+        # ====================================================================
+        # Interfaces to non-Postfix software. Be sure to examine the manual
+        # pages of the non-Postfix software to find out what options it wants.
+        #
+        # Many of the following services use the Postfix pipe(8) delivery
+        # agent.  See the pipe(8) man page for information about ${recipient}
+        # and other message envelope options.
+        # ====================================================================
+        #
+        # maildrop. See the Postfix MAILDROP_README file for details.
+        # Also specify in main.cf: maildrop_destination_recipient_limit=1
+        #
+        scache     unix  -       -       y       -       1       scache
+        maildrop  unix  -       n       n       -       -       pipe
+          flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
+        #
+        # ====================================================================
+        #
+        # Recent Cyrus versions can use the existing "lmtp" master.cf entry.
+        #
+        # Specify in cyrus.conf:
+        #   lmtp    cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4
+        #
+        # Specify in main.cf one or more of the following:
+        #  mailbox_transport = lmtp:inet:localhost
+        #  virtual_transport = lmtp:inet:localhost
+        #
+        # ====================================================================
+        #
+        # Cyrus 2.1.5 (Amos Gouaux)
+        # Also specify in main.cf: cyrus_destination_recipient_limit=1
+        #
+        #cyrus     unix  -       n       n       -       -       pipe
+        #  user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user}
+        #
+        # ====================================================================
+        # Old example of delivery via Cyrus.
+        #
+        #old-cyrus unix  -       n       n       -       -       pipe
+        #  flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user}
+        #
+        # ====================================================================
+        #
+        # See the Postfix UUCP_README file for configuration details.
+        #
+        uucp      unix  -       n       n       -       -       pipe
+          flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
+        #
+        # Other external delivery methods.
+        #
+        ifmail    unix  -       n       n       -       -       pipe
+          flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
+        bsmtp     unix  -       n       n       -       -       pipe
+          flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
+        scalemail-backend unix	-	n	n	-	2	pipe
+          flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
+        mailman   unix  -       n       n       -       -       pipe
+          flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
+          ${nexthop} ${user}
+
+        submission inet  n       -       y       -       -       smtpd
+            -o syslog_name=postfix/submission
+            -o smtpd_tls_security_level=encrypt
+            -o tls_preempt_cipherlist=yes
+            -o smtpd_sasl_auth_enable=yes
+            -o smtpd_tls_auth_only=yes
+            -o smtpd_reject_unlisted_recipient=no
+            -o smtpd_recipient_restrictions=
+            -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
+            -o smtpd_sender_login_maps=lmdb:/srv/tmp/sender-login-maps
+            -o sender_dependent_relayhost_maps=lmdb:/srv/tmp/relayhosts
+            -o cleanup_service_name=headers-cleanup
+
+        submissions inet  n       -       y       -       -       smtpd
+            -o syslog_name=postfix/submissions
+            -o smtpd_tls_wrappermode=yes
+            -o smtpd_tls_security_level=encrypt
+            -o tls_preempt_cipherlist=yes
+            -o smtpd_sasl_auth_enable=yes
+            -o smtpd_tls_auth_only=yes
+            -o smtpd_reject_unlisted_recipient=no
+            -o smtpd_recipient_restrictions=
+            -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
+            -o smtpd_sender_login_maps=lmdb:/srv/tmp/sender-login-maps
+            -o sender_dependent_relayhost_maps=lmdb:/srv/tmp/relayhosts
+            -o cleanup_service_name=headers-cleanup
+
+        dovecot   unix  -       n       n       -       -       pipe flags=DRhu
+          user=vmail:vmail argv=/usr/lib/dovecot/deliver -d ${recipient}
+
+        #smtp-amavis unix -       -       y       -       2       smtp
+        #    -o smtp_data_done_timeout=1800
+        #    -o smtp_send_xforward_command=yes
+        #    -o disable_mime_output_conversion=yes
+        #    -o smtp_generic_maps=
+
+        #127.0.0.1:10025 inet n   -       y       -       -       smtpd
+        #    -o content_filter=
+        #    -o smtpd_proxy_filter=
+        #    -o smtpd_authorized_xforward_hosts=127.0.0.0/8
+        #    -o smtpd_client_restrictions=
+        #    -o smtpd_helo_restrictions=
+        #    -o smtpd_sender_restrictions=
+        #    -o smtpd_recipient_restrictions=permit_mynetworks,reject
+        #    -o smtpd_data_restrictions=
+        #    -o mynetworks=127.0.0.0/8
+        #    -o receive_override_options=no_unknown_recipient_checks
+        ##        -o header_checks=pcre:/etc/postfix/submission_header_checks.pcre
+
+
+        #127.0.0.1:10027 inet n   -       y       -       -       smtpd
+        #    -o content_filter=smtp-amavis:[127.0.0.1]:10028
+        #    -o smtpd_proxy_filter=
+        #    -o smtpd_authorized_xforward_hosts=127.0.0.0/8
+        #    -o smtpd_client_restrictions=
+        #    -o smtpd_helo_restrictions=
+        #    -o smtpd_sender_restrictions=
+        #    -o smtpd_recipient_restrictions=permit_mynetworks,reject
+        #    -o smtpd_data_restrictions=
+        #    -o mynetworks=127.0.0.0/8
+        #    -o receive_override_options=no_unknown_recipient_checks
+        #    -o cleanup_service_name=subcleanup
+
+        subcleanup unix  n       -       y       -       0       cleanup
+        #    -o header_checks=pcre:/srv/config/submission_header_checks.pcre
+
+        headers-cleanup unix n - - - 0 cleanup
+        -o syslog_name=postfix/headers-cleanup
+        -o header_checks=regexp:/etc/postfix/header_checks
+    kind: ConfigMap
+    metadata:
+      labels:
+        app.kubernetes.io/component: postfix
+        app.kubernetes.io/instance: RELEASE-NAME
+        app.kubernetes.io/managed-by: Helm
+        app.kubernetes.io/name: mok
+        helm.sh/chart: mok-1.2.3
+      name: RELEASE-NAME-mok-postfix
+  2: |
     apiVersion: v1
     kind: Service
     metadata:
@@ -27,7 +396,7 @@ should match snapshot:
         app.kubernetes.io/instance: RELEASE-NAME
         app.kubernetes.io/name: mok
       type: LoadBalancer
-  2: |
+  3: |
     apiVersion: apps/v1
     kind: StatefulSet
     metadata:
@@ -49,14 +418,20 @@ should match snapshot:
       template:
         metadata:
           annotations:
-            checksum/config: 66ea930a9b7e50528ddc0aa54786d07f78c7f56d1daea45b21d9eb94f8e5c4f2
+            checksum/config: 4370771faafcf471bc3cd42d9b0d20cc5f973ed85506113938bd22efa0f49ce0
+            checksum/secret: 66ea930a9b7e50528ddc0aa54786d07f78c7f56d1daea45b21d9eb94f8e5c4f2
           labels:
             app.kubernetes.io/component: postfix
             app.kubernetes.io/instance: RELEASE-NAME
             app.kubernetes.io/name: mok
         spec:
           containers:
-            - env:
+            - command:
+                - postfix
+                - -c
+                - /etc/postfix
+                - start-fg
+              env:
                 - name: DOVECOT_SERVICE_NAME
                   value: RELEASE-NAME-mok-dovecot-internal.NAMESPACE.svc.cluster.local
               image: quay.io/shivering-isles/postfix:4.5.6
@@ -123,6 +498,92 @@ should match snapshot:
                 failureThreshold: 12
                 initialDelaySeconds: 2
                 periodSeconds: 5
+              volumeMounts:
+                - mountPath: /etc/postfix/master.conf
+                  name: config
+                  subPath: master.conf
+                - mountPath: /etc/postfix/main.conf
+                  name: config
+                  subPath: main.conf
+                - mountPath: /var/spool/postfix/
+                  name: spool
+                - mountPath: /srv/tmp
+                  name: cache
+                - mountPath: /srv/virtual
+                  name: maps
+                  readOnly: true
+                - mountPath: /srv/tls
+                  name: tls
+                  readOnly: true
+              workingDir: /etc/postfix
+          initContainer:
+            - command:
+                - sh
+                - -c
+                - cp /srv/virtual/* /srv/tmp && find /srv/tmp -type f -exec postmap lmdb://{} \;
+              image: quay.io/shivering-isles/postfix:4.5.6
+              imagePullPolicy: IfNotPresent
+              name: postmap
+              resources:
+                limits:
+                  cpu: 100m
+                  memory: 64Mi
+                requests:
+                  cpu: 100m
+                  memory: 64Mi
+              securityContext:
+                allowPrivilegeEscalation: false
+                capabilities:
+                  add:
+                    - SYS_CHROOT
+                    - CHOWN
+                    - CAP_NET_BIND_SERVICE
+                    - SETUID
+                    - SETGID
+                    - FOWNER
+                    - DAC_OVERRIDE
+                  drop:
+                    - ALL
+                runAsNonRoot: false
+              volumeMounts:
+                - mountPath: /var/spool/postfix/
+                  name: spool
+                - mountPath: /srv/tmp
+                  name: cache
+                - mountPath: /srv/virtual
+                  name: maps
+                  readOnly: true
+                - mountPath: /srv/tls
+                  name: tls
+                  readOnly: true
+            - command:
+                - sh
+                - -c
+                - mkdir -p /var/spool/postfix/etc/ && cp /etc/resolv.conf /var/spool/postfix/etc/
+              image: quay.io/shivering-isles/postfix:4.5.6
+              imagePullPolicy: IfNotPresent
+              name: fill-chroot
+              resources:
+                limits:
+                  cpu: 100m
+                  memory: 64Mi
+                requests:
+                  cpu: 100m
+                  memory: 64Mi
+              securityContext:
+                allowPrivilegeEscalation: false
+                capabilities:
+                  add:
+                    - SYS_CHROOT
+                    - CHOWN
+                    - CAP_NET_BIND_SERVICE
+                    - SETUID
+                    - SETGID
+                    - FOWNER
+                    - DAC_OVERRIDE
+                  drop:
+                    - ALL
+                runAsNonRoot: false
               volumeMounts:
                 - mountPath: /var/spool/postfix/
                   name: spool
@@ -140,6 +601,9 @@ should match snapshot:
             - name: maps
               secret:
                 secretName: RELEASE-NAME-mok-postfix-maps
+            - configMap:
+                name: RELEASE-NAME-mok-postfix
+              name: config
             - name: tls
               secret:
                 secretName: example-tls
@@ -154,7 +618,7 @@ should match snapshot:
             resources:
               requests:
                 storage: 1Gi
-  3: |
+  4: |
     apiVersion: v1
     kind: Secret
     metadata:
@@ -168,7 +632,7 @@ should match snapshot:
     stringData:
       passwd: ""
     type: Opaque
-  4: |
+  5: |
     apiVersion: v1
     kind: Secret
     metadata:
diff --git a/charts/mok/tests/helmlabels_test.yaml b/charts/mok/tests/helmlabels_test.yaml
index e6374a6b8..cecf412a3 100644
--- a/charts/mok/tests/helmlabels_test.yaml
+++ b/charts/mok/tests/helmlabels_test.yaml
@@ -3,6 +3,7 @@ templates:
   - dovecot.yaml
   - networkpolicy.yaml
   - persistentvolumeclaim.yaml
+  - postfix-config.yaml
   - postfix.yaml
   - secret.yaml
   - serviceaccount.yaml
diff --git a/charts/mok/tests/postfix_test.yaml b/charts/mok/tests/postfix_test.yaml
index 51a23aa5f..88af4a1e1 100644
--- a/charts/mok/tests/postfix_test.yaml
+++ b/charts/mok/tests/postfix_test.yaml
@@ -1,5 +1,6 @@
 suite: Postfix
 templates:
+  - postfix-config.yaml
   - postfix.yaml
   - secret.yaml
 tests:
@@ -82,7 +83,7 @@ tests:
         secretName: example-tls
     asserts:
       - equal:
-          path: spec.template.metadata.annotations["checksum/config"]
+          path: spec.template.metadata.annotations["checksum/secret"]
           value: 66ea930a9b7e50528ddc0aa54786d07f78c7f56d1daea45b21d9eb94f8e5c4f2
         documentIndex: 1
         template: postfix.yaml
@@ -99,7 +100,7 @@ tests:
               passwordHash: NotReallyAHash
     asserts:
       - equal:
-          path: spec.template.metadata.annotations["checksum/config"]
+          path: spec.template.metadata.annotations["checksum/secret"]
           value: 9215abccdd6c1f21fd329db0133f6f8e892c50aab3dcde3259ea797e8ad2a959
         documentIndex: 1
         template: postfix.yaml
@@ -126,9 +127,10 @@ tests:
         documentIndex: 2
         template: postfix.yaml
       - containsDocument:
-          kind: PodDisruptionBudget
           apiVersion: policy/v1
+          kind: PodDisruptionBudget
           name: test-suite-mok-postfix
+          any: true
         template: postfix.yaml
   - it: scales with replicaCount
     set:
-- 
GitLab