From ab4d3c9cf944fc0d0b45dac9b9c07017da0b6233 Mon Sep 17 00:00:00 2001
From: Sheogorath <sheogorath@shivering-isles.com>
Date: Wed, 25 May 2022 01:52:29 +0200
Subject: [PATCH] feat(postfix): Add container image for postfix

---
 images/postfix/.release                |   1 +
 images/postfix/Containerfile           |  25 ++++
 images/postfix/Makefile                |   2 +
 images/postfix/README.md               |  19 +++
 images/postfix/config/.gitignore       |   1 +
 images/postfix/config/header_checks    |   7 +
 images/postfix/config/main.cf          | 170 ++++++++++++++++++++++++
 images/postfix/config/master.cf        | 176 +++++++++++++++++++++++++
 images/postfix/docker/rsyslog.conf     |  13 ++
 images/postfix/docker/start.sh         |  56 ++++++++
 images/postfix/docker/supervisord.conf |  24 ++++
 11 files changed, 494 insertions(+)
 create mode 100644 images/postfix/.release
 create mode 100644 images/postfix/Containerfile
 create mode 100644 images/postfix/Makefile
 create mode 100644 images/postfix/README.md
 create mode 100644 images/postfix/config/.gitignore
 create mode 100644 images/postfix/config/header_checks
 create mode 100644 images/postfix/config/main.cf
 create mode 100644 images/postfix/config/master.cf
 create mode 100644 images/postfix/docker/rsyslog.conf
 create mode 100644 images/postfix/docker/start.sh
 create mode 100644 images/postfix/docker/supervisord.conf

diff --git a/images/postfix/.release b/images/postfix/.release
new file mode 100644
index 000000000..85f180f38
--- /dev/null
+++ b/images/postfix/.release
@@ -0,0 +1 @@
+release=0.1.0
diff --git a/images/postfix/Containerfile b/images/postfix/Containerfile
new file mode 100644
index 000000000..d77d4b43c
--- /dev/null
+++ b/images/postfix/Containerfile
@@ -0,0 +1,25 @@
+FROM docker.io/library/alpine:3.16.0
+
+# Install pre-requirements
+RUN apk update
+RUN apk add --no-cache ca-certificates rsyslog supervisor
+RUN update-ca-certificates
+
+
+RUN apk add --no-cache postfix
+
+RUN mkdir /var/spool/postfix/etc && echo "smtp		25/tcp		mail		# Simple Mail Transfer" > /var/spool/postfix/etc/services
+
+COPY config/main.cf /etc/postfix/
+COPY config/master.cf /etc/postfix/
+COPY docker/supervisord.conf /etc/
+COPY docker/rsyslog.conf /etc/
+COPY docker/start.sh /usr/local/libexec/start.sh
+RUN chmod +x /usr/local/libexec/start.sh
+
+#   25: SMTP (Server2Server)
+#  465: SUBMISSIONS (SSL)
+#  587: SMTP (StartTLS)
+EXPOSE 25 465 587
+
+ENTRYPOINT [ "sh" , "/usr/local/libexec/start.sh" ]
diff --git a/images/postfix/Makefile b/images/postfix/Makefile
new file mode 100644
index 000000000..d433bc8ba
--- /dev/null
+++ b/images/postfix/Makefile
@@ -0,0 +1,2 @@
+include ../.utils/container-build.mk
+include ../../utils/help.mk
diff --git a/images/postfix/README.md b/images/postfix/README.md
new file mode 100644
index 000000000..0c9660584
--- /dev/null
+++ b/images/postfix/README.md
@@ -0,0 +1,19 @@
+Postfix
+===
+
+Postfix container image intended for use in Kubernetes with plain text user backend.
+
+The goal of this postfix image is to be preconfigured to utilse Kubernetes configmaps and secrets to become useful. It doesn't come with external database backend.
+
+Expectations
+---
+
+|Path | Usage |
+|-----|-------|
+|`/srv/virtual`|All files for virtual hosting (domains, aliases, mailboxes)|
+|`/srv/tls/`|TLS key and certificate used for TLS enabled services|
+
+References
+---
+
+This image is heavily inspired by https://github.com/mum-project/docker-images/tree/master/postfix
diff --git a/images/postfix/config/.gitignore b/images/postfix/config/.gitignore
new file mode 100644
index 000000000..3997beadf
--- /dev/null
+++ b/images/postfix/config/.gitignore
@@ -0,0 +1 @@
+*.db
\ No newline at end of file
diff --git a/images/postfix/config/header_checks b/images/postfix/config/header_checks
new file mode 100644
index 000000000..520aef1bd
--- /dev/null
+++ b/images/postfix/config/header_checks
@@ -0,0 +1,7 @@
+/^Message-ID:/i IGNORE
+/^Mime-Version: 1.0.*/ REPLACE Mime-Version: 1.0
+/^User-Agent:/ IGNORE
+/^X-Enigmail:/ IGNORE
+/^X-Mailer:/ IGNORE
+/^X-Originating-IP:/ IGNORE
+/^X-PHP-Originating-Script:/ IGNORE
diff --git a/images/postfix/config/main.cf b/images/postfix/config/main.cf
new file mode 100644
index 000000000..07bfbf2d8
--- /dev/null
+++ b/images/postfix/config/main.cf
@@ -0,0 +1,170 @@
+############### 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
+
+########
+##
+## 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
+
+smtpd_tls_auth_only = yes
+tls_ssl_options = NO_COMPRESSION
+
+smtp_tls_mandatory_protocols = !SSLv2, !SSLv3
+smtp_tls_protocols = !SSLv2, !SSLv3
+lmtp_tls_mandatory_protocols = !SSLv2, !SSLv3
+lmtp_tls_protocols = !SSLv2, !SSLv3
+smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
+smtpd_tls_protocols = !SSLv2, !SSLv3
+smtpd_tls_mandatory_ciphers=high
+tls_high_cipherlist=EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA256:EECDH:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA128-SHA:AES128-SHA
+
+tls_preempt_cipherlist = yes
+smtp_dns_support_level = dnssec
+
+smtpd_tls_mandatory_exclude_ciphers = MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL, SEED, IDEA, RC2
+smtpd_tls_exclude_ciphers = MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL, SEED, IDEA, RC2
+smtp_tls_mandatory_exclude_ciphers = MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL, SEED, IDEA, RC2
+smtp_tls_exclude_ciphers = MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL, SEED, IDEA, RC2
+
+smtpd_tls_eecdh_grade=ultra
+smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
+#smtpd_tls_dh1024_param_file = /srv/config/tls/dh4096.pem
+
+#smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
+#smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
+
+#smtp_tls_policy_maps = lmdb:/srv/tmp/tls-policies
+
+########
+##
+## SASL Configuration Configuration
+##
+
+smtpd_sasl_type = dovecot
+smtpd_sasl_path = inet:dovecot-internal: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
+
+virtual_transport = lmtp:inet:dovecot-internal:24
+
+########
+##
+## Postscreen Configuration
+##
+
+postscreen_access_list = permit_mynetworks
+postscreen_blacklist_action = drop
+postscreen_greet_action = enforce
+postscreen_dnsbl_action = enforce
+postscreen_dnsbl_threshold = 3
+postscreen_dnsbl_whitelist_threshold = -1
+postscreen_dnsbl_sites =
+        zen.spamhaus.org*3,
+        ix.dnsbl.manitu.net*3,
+        multi.uribl.com,
+        bl.spamcop.net,
+        b.barracudacentral.org,
+        dnsbl-1.uceprotect.net,
+        safe.dnsbl.sorbs.net,
+        ubl.unsubscore.com,
+        psbl.surriel.com,
+        dnsbl.inps.de,
+        swl.spamhaus.org*-10,
+        list.dnswl.org=127.0.[0..255].1*-2,
+        list.dnswl.org=127.0.[0..255].2*-10,
+        list.dnswl.org=127.0.[0..255].3*-100
+
+########
+##
+## 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_sasl_authenticated,
+        permit_mynetworks,
+		reject_unverified_recipient,
+        reject_unauth_destination,
+        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
+
+########
+##
+## 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/images/postfix/config/master.cf b/images/postfix/config/master.cf
new file mode 100644
index 000000000..d978e1e9c
--- /dev/null
+++ b/images/postfix/config/master.cf
@@ -0,0 +1,176 @@
+# ==========================================================================
+# service type  private unpriv  chroot  wakeup  maxproc command + args
+#               (yes)   (yes)   (yes)   (never) (100)
+# ==========================================================================
+#smtp      inet  n       -       -       -       1       postscreen
+#smtpd     pass  -       -       -       -       -       smtpd
+#dnsblog   unix  -       -       -       -       0       dnsblog
+#tlsproxy  unix  -       -       -       -       0       tlsproxy
+#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_type=dovecot
+    -o smtpd_sasl_path=inet:dovecot-internal:12345
+    -o smtpd_sasl_security_options=noanonymous
+    -o smtpd_sasl_auth_enable=yes
+    -o smtpd_client_restrictions=permit_sasl_authenticated,reject
+    -o smtpd_sender_login_maps=lmdb:/srv/tmp/sender-login-maps
+    -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_type=dovecot
+    -o smtpd_sasl_path=inet:dovecot-internal:12345
+    -o smtpd_sasl_security_options=noanonymous
+    -o smtpd_sasl_auth_enable=yes
+    -o smtpd_client_restrictions=permit_sasl_authenticated,reject
+    -o smtpd_sender_login_maps=lmdb:/srv/tmp/sender-login-maps
+    -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
diff --git a/images/postfix/docker/rsyslog.conf b/images/postfix/docker/rsyslog.conf
new file mode 100644
index 000000000..b11424083
--- /dev/null
+++ b/images/postfix/docker/rsyslog.conf
@@ -0,0 +1,13 @@
+$ModLoad immark.so # provides --MARK-- message capability
+$ModLoad imuxsock.so # provides support for local system logging (e.g. via logger command)
+
+# default permissions for all log files.
+$FileOwner root
+$FileGroup adm
+$FileCreateMode 0640
+$DirCreateMode 0755
+$Umask 0022
+
+#*.info							/dev/stdout
+#mail.*							/dev/stdout
+mail.info /dev/stdout
\ No newline at end of file
diff --git a/images/postfix/docker/start.sh b/images/postfix/docker/start.sh
new file mode 100644
index 000000000..6285b6739
--- /dev/null
+++ b/images/postfix/docker/start.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+
+SHOULD_EXIT_EARLY=false
+
+function var_not_set {
+    echo "Environment variable $1 is not set"
+    SHOULD_EXIT_EARLY=true
+}
+
+########
+##
+## Variables
+##
+
+if [ -z $HOSTNAME ]; then
+    HOSTNAME="$(hostname -f)"
+fi
+
+########
+##
+## Test if we should return early
+##
+
+if [ $SHOULD_EXIT_EARLY = true ]; then
+    exit 1
+fi
+
+
+########
+##
+## Preparation
+##
+
+########
+##
+## Postfix Configuration
+##
+
+postconf -e "myhostname = $HOSTNAME"
+cp /srv/virtual/* /srv/tmp
+find /srv/tmp -type f -exec postmap lmdb://{} \;
+
+########
+##
+## Kube DNS Support
+##
+
+cp /etc/resolv.conf /var/spool/postfix/etc/
+
+########
+##
+## Start
+##
+
+# exec postfix start
+exec supervisord -c /etc/supervisord.conf
diff --git a/images/postfix/docker/supervisord.conf b/images/postfix/docker/supervisord.conf
new file mode 100644
index 000000000..bbc1cc653
--- /dev/null
+++ b/images/postfix/docker/supervisord.conf
@@ -0,0 +1,24 @@
+[supervisord]
+user            = root
+nodaemon        = true
+logfile         = /dev/null
+logfile_maxbytes= 0
+
+[program:rsyslog]
+command         = rsyslogd -n
+autostart       = true
+autorestart     = true
+startsecs       = 2
+stopwaitsecs    = 2
+stdout_logfile  = /dev/stdout
+stderr_logfile  = /dev/stderr
+stdout_logfile_maxbytes = 0
+stderr_logfile_maxbytes = 0
+
+[program:postfix]
+process_name    = master
+autostart       = true
+autorestart     = false
+directory       = /etc/postfix
+command         = /usr/sbin/postfix -c /etc/postfix start
+startsecs       = 0
\ No newline at end of file
-- 
GitLab