diff --git a/postfix/docker-entrypoint.sh b/postfix/docker-entrypoint.sh index e0b1b17..9996800 100755 --- a/postfix/docker-entrypoint.sh +++ b/postfix/docker-entrypoint.sh @@ -26,7 +26,13 @@ has_wildcard_san() { openssl x509 -in "$cert" -noout -text 2>/dev/null | grep -E -q 'DNS:[[:space:]]*\*\.'"$domain"'(,|$)' >/dev/null } -# generate main.cf from template +# generate main.cf from templates +[ -f "$TEMPLATE_DIR/main.cf.tpl" ] && rm "$TEMPLATE_DIR/main.cf.tpl" +find "$TEMPLATE_DIR" -type f -name '*-icf-*.tpl' | sed 's:.*/::' | sort -t- -k1,1n | while read -r f; do + cat "$TEMPLATE_DIR/$f" + printf '\n' +done > "$TEMPLATE_DIR/main.cf.tpl" + sed \ -e "s/app.domain.tld/${SUBDOMAIN}.${DOMAIN}/g" \ -e "s/domain.tld/${DOMAIN}/g" \ diff --git a/postfix/templates/.gitignore b/postfix/templates/.gitignore new file mode 100644 index 0000000..39598a0 --- /dev/null +++ b/postfix/templates/.gitignore @@ -0,0 +1 @@ +main.cf.tpl diff --git a/postfix/templates/10-icf-main.tpl b/postfix/templates/10-icf-main.tpl new file mode 100644 index 0000000..7deda7e --- /dev/null +++ b/postfix/templates/10-icf-main.tpl @@ -0,0 +1,18 @@ +# POSTFIX config file, adapted for SimpleLogin +# ============================================ + +biff = no +compatibility_level = 3.11 +disable_vrfy_command = yes + +# Increase max. mail size limit from default 10M to 25M +message_size_limit=26214400 + +myhostname = app.domain.tld +mydomain = domain.tld +myorigin = domain.tld + +mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 10.0.0.0/24 + +relay_domains = pgsql:/etc/postfix/conf.d/pgsql-relay-domains.cf +transport_maps = pgsql:/etc/postfix/conf.d/pgsql-transport-maps.cf diff --git a/postfix/templates/20-icf-ssl.tpl b/postfix/templates/20-icf-ssl.tpl new file mode 100644 index 0000000..820d257 --- /dev/null +++ b/postfix/templates/20-icf-ssl.tpl @@ -0,0 +1,36 @@ + +# ---- Certificate configuration ---- +smtpd_tls_cert_file = /certs/app.domain.tld.fullchain.pem +smtpd_tls_key_file = /certs/app.domain.tld.key + +# use secure ECDHE or RFC 7919 FFDHE groups +smtpd_tls_eecdh_grade = strong + +# ---- Logging ---- +# Log TLS negotiations; +# set to 2 for more detailed debugging if needed. +smtpd_tls_loglevel = 1 + +# Explicitly exclude known-weak ciphers (mostly redundant with modern OpenSSL). +smtp_tls_mandatory_exclude_ciphers = aNULL, eNULL, EXPORT, DES, RC4, MD5, PSK, SRP +smtpd_tls_mandatory_exclude_ciphers = aNULL, eNULL, EXPORT, DES, RC4, MD5, PSK, SRP + +# ---- Allowed protocol versions ---- +# Only allow TLSv1.2 and TLSv1.3 (older versions are insecure or deprecated). +smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 +smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 + +# Adds TLS information to Received: headers (optional but useful for diagnostics) +smtpd_tls_received_header = yes + +smtpd_tls_security_level = may # "may" = Opportunistic TLS: offer TLS but do not require it. + +# TLS session caching (LMDB is fast and modern) +smtp_tls_session_cache_database = lmdb:${data_directory}/smtp_scache +smtpd_tls_session_cache_database = lmdb:${data_directory}/smtpd_scache + +# ---- Additional TLS hardening ---- +# Prefer server cipher order and disable TLS compression/renegotiation +# to prevent CRIME and renegotiation attacks. +tls_preempt_cipherlist = yes +tls_ssl_options = NO_COMPRESSION, NO_RENEGOTIATION diff --git a/postfix/templates/50-icf-logging.tpl b/postfix/templates/50-icf-logging.tpl new file mode 100644 index 0000000..e070c9b --- /dev/null +++ b/postfix/templates/50-icf-logging.tpl @@ -0,0 +1,4 @@ + +# Log output to stdout +# Requires that Postfix is started with "postfix start-fg". +maillog_file=/dev/stdout diff --git a/postfix/templates/60-icf-ehlo-restrictions.tpl b/postfix/templates/60-icf-ehlo-restrictions.tpl new file mode 100644 index 0000000..0c7b480 --- /dev/null +++ b/postfix/templates/60-icf-ehlo-restrictions.tpl @@ -0,0 +1,9 @@ + +# HELO restrictions +smtpd_delay_reject = yes +smtpd_helo_required = yes +smtpd_helo_restrictions = + permit_mynetworks, + reject_non_fqdn_helo_hostname, + reject_invalid_helo_hostname, + permit diff --git a/postfix/templates/60-icf-recipient-restrictions.tpl b/postfix/templates/60-icf-recipient-restrictions.tpl new file mode 100644 index 0000000..c5434b5 --- /dev/null +++ b/postfix/templates/60-icf-recipient-restrictions.tpl @@ -0,0 +1,15 @@ + +# Recipient restrictions: +smtpd_recipient_restrictions = + reject_unauth_pipelining, + reject_non_fqdn_recipient, + reject_unknown_recipient_domain, + permit_mynetworks, + reject_unauth_destination, + reject_rbl_client zen.spamhaus.org=127.0.0.[2..11] + reject_rhsbl_sender dbl.spamhaus.org=127.0.1.[2..99] + reject_rhsbl_helo dbl.spamhaus.org=127.0.1.[2..99] + reject_rhsbl_reverse_client dbl.spamhaus.org=127.0.1.[2..99] + warn_if_reject reject_rbl_client zen.spamhaus.org=127.255.255.[1..255] + reject_rbl_client bl.spamcop.net, + permit diff --git a/postfix/templates/60-icf-sender-restrictions.tpl b/postfix/templates/60-icf-sender-restrictions.tpl new file mode 100644 index 0000000..e609f2c --- /dev/null +++ b/postfix/templates/60-icf-sender-restrictions.tpl @@ -0,0 +1,7 @@ + +# Sender restrictions: +smtpd_sender_restrictions = + permit_mynetworks, + reject_non_fqdn_sender, + reject_unknown_sender_domain, + permit diff --git a/postfix/templates/99-icf-alias.tpl b/postfix/templates/99-icf-alias.tpl new file mode 100644 index 0000000..28433cb --- /dev/null +++ b/postfix/templates/99-icf-alias.tpl @@ -0,0 +1,6 @@ + +alias_maps = lmdb:/etc/postfix/conf.d/aliases + +virtual_alias_maps = + lmdb:/etc/postfix/conf.d/virtual, + regexp:/etc/postfix/conf.d/virtual-regexp diff --git a/postfix/templates/main.cf.tpl b/postfix/templates/main.cf.tpl deleted file mode 100644 index cf80e3c..0000000 --- a/postfix/templates/main.cf.tpl +++ /dev/null @@ -1,110 +0,0 @@ -# POSTFIX config file, adapted for SimpleLogin -smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu) -biff = no - -# appending .domain is the MUA's job. -append_dot_mydomain = no - -# Uncomment the next line to generate "delayed mail" warnings -#delay_warning_time = 4h - -readme_directory = no - -# Increase max. mail size limit from default 10M to 25M -message_size_limit=26214400 - -# ---- Modern compatibility level ---- -# Enables modern, secure Postfix defaults for TLS, ciphers, logging, and behavior. -compatibility_level = 3.6 - -# ---- Certificate configuration ---- -smtpd_tls_cert_file = /certs/app.domain.tld.fullchain.pem -smtpd_tls_key_file = /certs/app.domain.tld.key - -# ---- Enable TLS for inbound and outbound SMTP ---- -# "may" = Opportunistic TLS: offer TLS but do not require it. -smtpd_tls_security_level = may -smtp_tls_security_level = may - -# TLS session caching (LMDB is fast and modern) -smtpd_tls_session_cache_database = lmdb:${data_directory}/smtpd_scache -smtp_tls_session_cache_database = lmdb:${data_directory}/smtp_scache - -# ---- Allowed protocol versions ---- -# Only allow TLSv1.2 and TLSv1.3 (older versions are insecure or deprecated). -smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 -smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 - -# ---- Cipher suites ---- -# "medium" is sufficient and balanced; OpenSSL >= 1.1.1 already enforces secure defaults. -# "high" is unnecessarily restrictive and may reduce compatibility without adding security. -smtpd_tls_mandatory_ciphers = medium -smtp_tls_mandatory_ciphers = medium - -# Explicitly exclude known-weak ciphers (mostly redundant with modern OpenSSL). -smtpd_tls_mandatory_exclude_ciphers = aNULL, eNULL, EXPORT, DES, RC4, MD5, PSK, SRP -smtp_tls_mandatory_exclude_ciphers = aNULL, eNULL, EXPORT, DES, RC4, MD5, PSK, SRP - -# ---- Perfect Forward Secrecy / Key exchange ---- -# No manual DH parameter files are needed; OpenSSL automatically uses secure -# ECDHE or RFC 7919 FFDHE groups. -smtpd_tls_eecdh_grade = strong - -# ---- Additional TLS hardening ---- -# Prefer server cipher order and disable TLS compression/renegotiation -# to prevent CRIME and renegotiation attacks. -tls_preempt_cipherlist = yes -tls_ssl_options = NO_COMPRESSION, NO_RENEGOTIATION - -# ---- Logging ---- -# Log TLS negotiations; set to 2 for more detailed debugging if needed. -smtpd_tls_loglevel = 1 - -# Adds TLS information to Received: headers (optional but useful for diagnostics) -smtpd_tls_received_header = yes - -alias_maps = lmdb:/etc/postfix/conf.d/aliases -mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 10.0.0.0/24 - -# set domain here -myhostname = app.domain.tld -mydomain = domain.tld -myorigin = domain.tld - -relay_domains = pgsql:/etc/postfix/conf.d/pgsql-relay-domains.cf -transport_maps = pgsql:/etc/postfix/conf.d/pgsql-transport-maps.cf - -disable_vrfy_command = yes - -# HELO restrictions -smtpd_delay_reject = yes -smtpd_helo_required = yes -smtpd_helo_restrictions = - permit_mynetworks, - reject_non_fqdn_helo_hostname, - reject_invalid_helo_hostname, - permit - -# Sender restrictions: -smtpd_sender_restrictions = - permit_mynetworks, - reject_non_fqdn_sender, - reject_unknown_sender_domain, - permit - -# Recipient restrictions: -smtpd_recipient_restrictions = - reject_unauth_pipelining, - reject_non_fqdn_recipient, - reject_unknown_recipient_domain, - permit_mynetworks, - reject_unauth_destination, - reject_rbl_client zen.spamhaus.org, - reject_rbl_client bl.spamcop.net, - permit - -# Log output -maillog_file=/dev/stdout - -virtual_alias_domains = -virtual_alias_maps = lmdb:/etc/postfix/conf.d/virtual, regexp:/etc/postfix/conf.d/virtual-regexp