diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..fc1668d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM ubuntu:22.04 + +WORKDIR /opt/postfix + +RUN apt update && \ + apt upgrade -y && \ + apt install -y postfix curl + +RUN curl -SsfL -o /usr/bin/gomplate "https://github.com/hairyhenderson/gomplate/releases/download/v3.11.5/gomplate_linux-amd64-slim" && \ + chmod 755 /usr/bin/gomplate + +COPY entrypoint.sh . +COPY config ./config + +EXPOSE 25/tcp 465/tcp 587/tcp +CMD ["/bin/bash", "entrypoint.sh"] \ No newline at end of file diff --git a/README.md b/README.md index 236c0ee..c8554d5 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,67 @@ -# postfix-docker +# Building the image +```sh +docker build --rm -t postfix:latest . +``` -Lightweight Dockerized Postfix setup for easy deployment and mail relay configuration. \ No newline at end of file +# Running the image +```sh +docker run -it --rm --name test -p 25:25 -p 587:587 postfix:latest +``` + +# Environment variables +These values are default and can be overriden by declaring environment variable with naother value. +```sh +# The text that follows the 220 status code in the SMTP greeting banner. +POSTFIX_SMTP_BANNER="$myhostname ESMTP $mail_name ($mail_version)" + +# Enable submission running on port 587. +POSTFIX_SUBMISSION_ENABLED="yes" + +# Enable standard non encrypted SMTP running on port 25. +POSTFIX_SMTP_ENABLED="yes" + +# Enable SSL encrypted SMTPS running on port 465. +POSTFIX_SMTPS_ENABLED="yes" + +# Opportunistic TLS: announce STARTTLS support to remote SMTP clients, but do not require that clients use TLS encryption. +POSTFIX_SMTPD_USE_TLS="no" + +# When TLS encryption is optional in the Postfix SMTP server, do not announce or accept SASL authentication over unencrypted connections. +POSTFIX_SMTPD_TLS_AUTH_ONLY="yes" + +# File with the Postfix SMTP server RSA certificate in PEM format. +POSTFIX_SMTPD_TLS_CERT_FILE="/etc/ssl/certs/ssl-cert-snakeoil.pem" + +# File with the Postfix SMTP server RSA private key in PEM format. +POSTFIX_SMTPD_TLS_KEY_FILE="/etc/ssl/private/ssl-cert-snakeoil.key" + +# The SMTP TLS security level for the Postfix SMTP server. +POSTFIX_SMTPD_TLS_SECURITY_LEVEL="may" + +# Directory with PEM format Certification Authority certificates. +POSTFIX_SMTP_TLS_CAPATH="/etc/ssl/certs" + +# The default SMTP TLS security level for the Postfix SMTP client. +POSTFIX_SMTP_TLS_SECURITY_LEVEL="encrypt" + +# The internet hostname of this mail system. +POSTFIX_MYHOSTNAME="$(hostname --fqdn)" + +# The internet hostname of this mail system. +POSTFIX_MYDOMAIN="$(hostname --fqdn)" + +# The list of "trusted" remote SMTP clients that have more privileges than "strangers". +POSTFIX_MYNETWORKS="127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8" + +# The local network interface addresses that this mail system receives mail on. +POSTFIX_INET_INTERFACES="all" + +# The Internet protocols Postfix will attempt to use when making or accepting connections. +POSTFIX_INET_PROTOCOLS="all" + +# A list of Milter (mail filter) applications for new mail that arrives via the Postfix smtpd server. +POSTFIX_SMTPD_MILTERS="opendkim:port" + +# A list of Milter (mail filter) applications for new mail that does not arrive via the Postfix smtpd server. +POSTFIX_NON_SMTPD_MILTERS="opendkim:port" +``` \ No newline at end of file diff --git a/config/main.cf.tpl b/config/main.cf.tpl new file mode 100644 index 0000000..461a6e1 --- /dev/null +++ b/config/main.cf.tpl @@ -0,0 +1,41 @@ +biff = no +maillog_file = /dev/stdout +debug_peer_level = 1 +compatibility_level=3.6 +append_dot_mydomain = no +readme_directory = no +mailbox_command = procmail -a "$EXTENSION" +mailbox_size_limit = 0 +recipient_delimiter = + + +smtpd_banner = {{ .Env.POSTFIX_SMTPD_BANNER }} + +smtpd_relay_restrictions = permit_mynetworks defer_unauth_destination +smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination + +smtpd_use_tls = {{ .Env.POSTFIX_SMTPD_USE_TLS }} +smtpd_tls_auth_only = {{ .Env.POSTFIX_SMTPD_TLS_AUTH_ONLY }} +smtpd_tls_cert_file={{ .Env.POSTFIX_SMTPD_TLS_CERT_FILE }} +smtpd_tls_key_file={{ .Env.POSTFIX_SMTPD_TLS_KEY_FILE }} + +smtp_tls_CApath={{ .Env.POSTFIX_SMTP_TLS_CAPATH }} +smtp_tls_security_level = {{ .Env.POSTFIX_SMTP_TLS_SECURITY_LEVEL }} +smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache + +myhostname = {{ .Env.POSTFIX_MYHOSTNAME }} +mydomain = {{ .Env.POSTFIX_MYDOMAIN }} +mynetworks = {{ .Env.POSTFIX_MYNETWORKS }} +mydestination = $myhostname, localhost.$mydomain $mydomain + +inet_interfaces = {{ .Env.POSTFIX_INET_INTERFACES }} +inet_protocols = {{ .Env.POSTFIX_INET_PROTOCOLS }} + +milter_protocol = 6 +milter_default_action = accept + +{{- if .Env.POSTFIX_SMTPD_MILTERS }} +smtpd_milters = inet:{{ .Env.POSTFIX_SMTPD_MILTERS }} +{{- end }} +{{- if .Env.POSTFIX_NON_SMTPD_MILTERS }} +non_smtpd_milters = inet:{{ .Env.POSTFIX_NON_SMTPD_MILTERS }} +{{- end }} \ No newline at end of file diff --git a/config/master.cf.tpl b/config/master.cf.tpl new file mode 100644 index 0000000..dbfa74d --- /dev/null +++ b/config/master.cf.tpl @@ -0,0 +1,64 @@ +# ========================================================================== +# service type private unpriv chroot wakeup maxproc command + args +# (yes) (yes) (no) (never) (100) +# ========================================================================== + +# SMTP configuration. +{{ if eq .Env.POSTFIX_SMTP_ENABLED "yes" }} +smtp inet n - y - - smtpd + -o syslog_name=postfix/smtp +{{ end }} + +# Submission configuration. +{{ if eq .Env.POSTFIX_SUBMISSION_ENABLED "yes" }} +submission inet n - y - - smtpd + -o syslog_name=postfix/submission + -o smtpd_tls_security_level=encrypt +{{ end }} + +# SSL encrypted SMTP configuration. +{{ if eq .Env.POSTFIX_SMTPS_ENABLED "yes" }} +smtps inet n - y - - smtpd + -o syslog_name=postfix/smtps + -o smtpd_tls_wrappermode=yes +{{ end }} + +# Other internal services. +pickup unix n - y 60 1 pickup +cleanup unix n - y - 0 cleanup +qmgr unix n - n 300 1 qmgr +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 +relay unix - - y - - smtp + -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 +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 +scache unix - - y - 1 scache +maildrop unix - n n - - pipe + flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient} +uucp unix - n n - - pipe + flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) +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} +postlog unix-dgram n - n - 1 postlogd \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..1893838 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +# Misc default variables. +export POSTFIX_SMTPD_BANNER=${POSTFIX_SMTPD_BANNER:-$myhostname ESMTP $mail_name ($mail_version)} + +# Service default variables. +export POSTFIX_SUBMISSION_ENABLED=${POSTFIX_SUBMISSION_ENABLED:-yes} +export POSTFIX_SMTP_ENABLED=${POSTFIX_SMTP_ENABLED:-yes} +export POSTFIX_SMTPS_ENABLED=${POSTFIX_SMTPS_ENABLED:-yes} + +# TLS default variables. +export POSTFIX_SMTPD_USE_TLS=${POSTFIX_SMTPD_USE_TLS:-no} +export POSTFIX_SMTPD_TLS_AUTH_ONLY=${POSTFIX_SMTPD_TLS_AUTH_ONLY:-yes} +export POSTFIX_SMTPD_TLS_CERT_FILE=${POSTFIX_SMTPD_TLS_CERT_FILE:-/etc/ssl/certs/ssl-cert-snakeoil.pem} +export POSTFIX_SMTPD_TLS_KEY_FILE=${POSTFIX_SMTPD_TLS_KEY_FILE:-/etc/ssl/private/ssl-cert-snakeoil.key} +export POSTFIX_SMTPD_TLS_SECURITY_LEVEL=${POSTFIX_SMTPD_TLS_SECURITY_LEVEL:-may} + +export POSTFIX_SMTP_TLS_CAPATH=${POSTFIX_SMTP_TLS_CAPATH:-/etc/ssl/certs} +export POSTFIX_SMTP_TLS_SECURITY_LEVEL=${POSTFIX_SMTP_TLS_SECURITY_LEVEL:-encrypt} + +# Hostname default variables. +export POSTFIX_MYHOSTNAME=${POSTFIX_MYHOSTNAME:-$(hostname --fqdn)} +export POSTFIX_MYDOMAIN=${POSTFIX_MYDOMAIN:-$(hostname --fqdn)} + +# Allowed networks default variables. +export POSTFIX_MYNETWORKS=${POSTFIX_MYNETWORKS:-127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8} + +# Network configuration default variables. +export POSTFIX_INET_INTERFACES=${POSTFIX_INET_INTERFACES:-all} +export POSTFIX_INET_PROTOCOLS=${POSTFIX_INET_PROTOCOLS:-all} + +# DKIM milters default variables. +export POSTFIX_SMTPD_MILTERS=${POSTFIX_SMTPD_MILTERS:-} +export POSTFIX_NON_SMTPD_MILTERS=${POSTFIX_NON_SMTPD_MILTERS:-} + +# Configuration templates. +gomplate -f config/main.cf.tpl > /etc/postfix/main.cf +gomplate -f config/master.cf.tpl > /etc/postfix/master.cf + +# Move resolv conf to postfix spool in order to make postfix DNS lookups working. +cat /etc/resolv.conf > /var/spool/postfix/etc/resolv.conf + +postfix start-fg \ No newline at end of file