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