apt install postfix postfix-ldap certbot
Wählen Sie hier Internet Site
System mail name: domain.tld - das ist im Normalfall der Wert für myorigin
Das setzt /etc/mailname auf diesen Wert und macht sonst gar nix an der Postfix-Grundkonfiguration. myorigin ist der Wert der für alle Mails ohne Domain angehängt wird. https://wiki.debian.org/EtcMailName viel mehr macht der mailname auch nicht.
Zwingend 🗝️ LetsEncrypt-Zertifikat.
main.cf
myhostname = mx.domain.tld
# domain.tld
myorigin = /etc/mailname
mydestination = localhost
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
mail_spool_directory = /var/vmail
home_mailbox = Maildir/
compatibility_level = 3.9
### SSL
smtpd_tls_cert_file=/etc/letsencrypt/live/mail.domain.tld/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/mail.domain.tld/privkey.pem
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes
smtpd_tls_loglevel = 1
smtpd_tls_mandatory_protocols = >=TLSv1.3
tls_preempt_cipherlist = yes
tls_disable_workarounds = 0xFFFFFFFFFFFFFFFF
smtpd_tls_mandatory_ciphers = high
smtp_tls_security_level = encrypt
smtp_tls_CApath = /etc/ssl/certs
smtp_tls_loglevel = $smtpd_tls_loglevel
smtp_tls_mandatory_protocols = $smtpd_tls_mandatory_protocols
smtp_tls_mandatory_ciphers = $smtpd_tls_mandatory_ciphers
smtp_tls_exclude_ciphers = $smtpd_tls_exclude_ciphers
### /SSL
### Alias
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
### Virtual Mailbox
virtual_mailbox_domains = domain.tld mail.domain.tld
### Transport
virtual_transport = lmtp:inet:[127.0.0.1]:24
### SMTPD
smtpd_sasl_type = dovecot
smtpd_sasl_path = inet:127.0.0.1:26
smtpd_sasl_auth_enable = yes
##### SMTPD Security
smtpd_sender_login_maps = ldap:/etc/postfix/ldap_lookups/smtpd_sender_login_maps
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
### Default Transport
relayhost = mx.domain.tld
#default_transport = smtp # Das ist so Standard
### SMTP
smtp_sasl_auth_enable = yes
smtp_sasl_tls_security_level = noanonymous
smtp_sasl_password_maps = hash:/etc/postfix/relay_password
https://www.spamhaus.com/data-access/free-data-query-service/ registrieren
https://docs.spamhaus.com/datasets/docs/source/40-real-world-usage/MTAs/020-Postfix.html lesen :)
$ apt install postfix-policyd-spf-python
https://manpages.debian.org/testing/postfix-policyd-spf-python/policyd-spf.conf.5.en.html
policyd-spf.conf
# For a fully commented sample config file see policyd-spf.conf.commented
# https://manpages.debian.org/testing/postfix-policyd-spf-python/policyd-spf.conf.5.en.html#LOGGING
debugLevel = 2
# nur loggen aber alle mails pass
TestOnly = 1
HELO_reject = Fail
Mail_From_reject = Fail
PermError_reject = False
TempError_Defer = False
skip_addresses = 127.0.0.0/8,::ffff:127.0.0.0/104,::1
# Requirement for DMARC Reports
Header_Type = AR
Authserv_Id = mx.domain.tld
wenn alles geht Testonly = 0
master.cf
policy-spf unix - n n - - spawn
user=nobody argv=/usr/bin/policyd-spf
main.cf
policy-spf_time_limit = 3600s
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
check_policy_service unix:private/policy-spf,
reject_rbl_client query_key.zen.dq.spamhaus.net=127.0.0.[2..11]
reject_rhsbl_sender query_key.dbl.dq.spamhaus.net=127.0.1.[2..99]
reject_rhsbl_helo query_key.dbl.dq.spamhaus.net=127.0.1.[2..99]
reject_rhsbl_reverse_client query_key.dbl.dq.spamhaus.net=127.0.1.[2..99]
reject_rhsbl_sender query_key.zrd.dq.spamhaus.net=127.0.2.[2..24]
reject_rhsbl_helo query_key.zrd.dq.spamhaus.net=127.0.2.[2..24]
reject_rhsbl_reverse_client query_key.zrd.dq.spamhaus.net=127.0.2.[2..24]
# reject_rhsbl_helo dbl.spamhaus.org,
# reject_rhsbl_reverse_client dbl.spamhaus.org,
# reject_rhsbl_sender dbl.spamhaus.org,
# permit_dnswl_client list.dnswl.org=127.0.[0..255].[1..3],
# permit_dnswl_client swl.spamhaus.org,
# reject_rbl_client zen.spamhaus.org
rbl_reply_maps = hash:/etc/postfix/dnsbl-reply-map
dnsbl-reply-map
query_key.zen.dq.spamhaus.net=127.0.0.[2..11] 554 $rbl_class $rbl_what blocked using ZEN - see https://www.spamhaus.org/query/ip/$client_address for details
query_key.dbl.dq.spamhaus.net=127.0.1.[2..99] 554 $rbl_class $rbl_what blocked using DBL - see $rbl_txt for details
query_key.zrd.dq.spamhaus.net=127.0.2.[2..24] 554 $rbl_class $rbl_what blocked using ZRD - domain too young
query_key.zen.dq.spamhaus.net 554 $rbl_class $rbl_what blocked using ZEN - see https://www.spamhaus.org/query/ip/$client_address for details
query_key.dbl.dq.spamhaus.net 554 $rbl_class $rbl_what blocked using DBL - see $rbl_txt for details
query_key.zrd.dq.spamhaus.net 554 $rbl_class $rbl_what blocked using ZRD - domain too young
$ postmap dnsbl-reply-map
http://www.opendkim.org/docs.html
(ambigious syntax in signing.table, arch is better)
https://wiki.archlinux.org/title/OpenDKIM
$ apt install opendkim
Build socket
mkdir /var/spool/postfix/opendkim
chown -R opendkim:opendkim /var/spool/postfix/opendkim
chmod -R 750 /var/spool/postfix/opendkim
Add postfix uid to opendkim gid
usermod -aG opendkim postfix
/etc/opendkim.conf
# Defaults to MTA name so myhostname in postfix
#AuthservID mx.domain.tld
Syslog yes
SyslogSuccess yes
LogWhy yes
Canonicalization relaxed/relaxed
Mode sv
# needed if you send from subdomains, i recommend
SubDomains yes
OversignHeaders From
UserID opendkim
UMask 007
#geht auch per inet, muss man aber in /etc/default/opendkim ändern
Socket local:/var/spool/postfix/opendkim/opendkim.sock
PidFile /run/opendkim/opendkim.pid
TrustAnchorFile /usr/share/dns/root.key
# Auto restart on failures, max 10/minute
AutoRestart true
AutoRestartRate 10/1M
# forks, default
Background yes
# default
DNSTimeout 5
SignatureAlgorithm rsa-sha256
# not required if a SigningTable is in use; in that case, the list of signed domains is implied by the lines in that file.
#Domain domain.tld
KeyTable refile:/etc/opendkim/key.table
SigningTable refile:/etc/opendkim/signing.table
# Identifies a set of "external" hosts that may send mail through the server as one of the signing domains without credentials as such
ExternalIgnoreList /etc/opendkim/trusted.hosts
# Identifies a set internal hosts whose mail should be signed rather than verified
InternalHosts /etc/opendkim/trusted.hosts
$ mkdir /etc/opendkim
$ mkdir /etc/opendkim/keys
/etc/opendkim/trusted.hosts
# Notice these are the hosts that connected to postfix via SMTP
127.0.0.1
::1
localhost
# needed?
# not needed. domains that are in signing.table (you send from them are signed)
# 10.lan.your.mailserver
# .domain.tld
.deutschebahn.com
.bahn.de
build keys
/etc/opendkim/# opendkim-genkey -d domain.tld -b 2048 -r -s 20261224
move keys
mv 20261224.private keys/domain.tld.private
mv 20261224.txt keys/domain.tld.txt
/etc/opendkim/signing.table
@domain.tld 20261224._domainkey.domain.tld
/etc/opendkim/key.table
20260908._domainkey.domain.tld domain.tld:20260908:/etc/opendkim/keys/domain.tld.private
chown all
chown -R opendkim:opendkim /etc/opendkim
start
systemctl enable opendkim && systemctl start opendkim
liegen in der .txt bekommste hin
check
opendkim-testkey -d domain.tld -s 20261224 -vvv
http://www.trusteddomain.org/opendmarc/opendmarc.conf.5.html
$ apt install opendmarc
Ja brauch mysql ... db common errort erstmal einfach retry dann selbsterklärend
build socket
mkdir /var/spool/postfix/opendmarc
chown -R opendmarc:opendmarc /var/spool/postfix/opendmarc
chmod -R 750 /var/spool/postfix/opendmarc
usermod -aG opendmarc postfix
/etc/opendmarc.conf
# Defaults to /etc/mailname (?) - needs to match opendkim
AuthservID mx.domain.tld
# this just means we will not milter away already checked by opendkim mails
TrustedAuthservIDs mx.domain.tld
# set to true when all works
RejectFailures false
# technically not needed when IgnoreHosts is correct
# But it seems we never actually send from 127.0.0.1
# So use IgnoreAuthenticatedClients
#
# IgnoreMailFrom domain.tld
IgnoreHosts /etc/opendmarc/ignore.hosts
# Needed, smarter than a list of domains if you tighten sender_maps - works better for relay_users
IgnoreAuthenticatedClients true
# Auto restart on failures, max 10/minute
AutoRestart true
AutoRestartRate 10/1M
Socket local:/var/spool/postfix/opendmarc/opendmarc.sock
# geht auch per inet
# Socket inet:9999@10.lan.x.y
PublicSuffixList /etc/opendmarc/public_suffix_list.dat
# Reports
# needed for aggregate reports to work, see script /etc/cron.hourly/opendmarc-reporting.sh
HistoryFile /var/run/opendmarc/opendmarc.dat
# Forensic Reports, not aggregate. DSGVO beachten.
FailureReports true
FailureReportsSentBy no-reply.dmarc.failurereports@domain.tld
# BCC
# FailureReportsBcc bcc.dmarc.failurereports@domain.tld
# zur Sicherheit gegen report-pingpong
IgnoreMailTo no-reply.dmarc.reports@domain.tld, no-reply.dmarc.failurereports@domain.tld
# Debian defaults
PidFile /run/opendmarc/opendmarc.pid
PublicSuffixList /usr/share/publicsuffix/public_suffix_list.dat
#Socket local:/run/opendmarc/opendmarc.sock
Syslog true
UMask 0002
UserID opendmarc
eigene Server ignorieren:
mkdir /etc/opendmarc
touch /etc/opendmarc/ignore.hosts
/etc/opendmarc/ignore.hosts
# Notice, these are the hosts that connected to postfix via SMTP - not the postfix host
127.0.0.1
::1
localhost
Public Suffixes in Debian evtl veraltet
wget --no-check-certificate -q -N -P /etc/opendmarc https://publicsuffix.org/list/public_suffix_list.dat
Alles chownen
chown -R opendmarc:opendmarc /etc/opendmarc
Starten
systemctl enable opendmarc && systemctl start opendmarc
forensic reports werden sofort versandt.
für aggregate reports:
opendmarc writes a report .dat file we can use to populate the mysql database and send out reports, then purge it again.
Deshalb muss man die dann aber auch wieder neu mit denselben Rechten erstellen.
touch /etc/cron.hourly/opendmarc-reporting.sh
chmod +x /etc/cron.hourly/opendmarc-reporting.sh
apt install zip
/etc/cron.hourly/opendmarc-reporting (no . in filename or it wont run)
#!/bin/bash
# Database Connection
DBHOST='localhost'
DBUSER='opendmarc'
DBPASS='StarkesPasswortVerwenden'
DBNAME='opendmarc'
# History-File
HISTDIR='/var/run/opendmarc'
HISTFILE='opendmarc'
# Report-Settings
REPORT_INTERVAL='86400'
REPORT_SENDER='no-reply.dmarc.reports@domain.tld'
REPORT_ORG='domain.tld'
REPORT_EXPIRE='90'
# Define a clean temp file
TMPFILE="/tmp/${HISTFILE}.$$"
# Delete the temp file automatically when the script exits (even on error)
trap 'rm -f "$TMPFILE"' EXIT
# Check history file exists
touch ${HISTDIR}/${HISTFILE}.dat
chown opendmarc:opendmarc ${HISTDIR}/${HISTFILE}.dat
# Move history file to Temp-Dir for processing
mv ${HISTDIR}/${HISTFILE}.dat "$TMPFILE"
# Import Temp history file data to MySQL DB and send reports
/usr/sbin/opendmarc-import -dbhost=${DBHOST} -dbuser=${DBUSER} -dbpasswd=${DBPASS} -dbname=${DBNAME} < "$TMPFILE"
/usr/sbin/opendmarc-reports -dbhost=${DBHOST} -dbuser=${DBUSER} -dbpasswd=${DBPASS} -dbname=${DBNAME} --interval=$REPORT_INTERVAL --report-email=$REPORT_SENDER --report-org=$REPORT_ORG
/usr/sbin/opendmarc-expire -dbhost=${DBHOST} -dbuser=${DBUSER} -dbpasswd=${DBPASS} -dbname=${DBNAME} --expire=$REPORT_EXPIRE
# (No manual rm line needed, trap handles it cleanly)
wer dafür bccs bekommen will:
/etc/postfix/bcc_map
no-reply.dmarc.reports@domain.tld bcc.dmarc.reports@domain.tld
/etc/postfix/main.cf
sender_bcc_maps = hash:/etc/postfix/bcc_map
/etc/postfix# postmap bcc_map
/etc/postfix/main.cf
## Milters
# The default action when a Milter (mail filter) response is unavailable
milter_default_action = accept
# default
milter_protocol = 6
smtpd_milters =
local:opendkim/opendkim.sock,
# inet:10.lan.x.y:12345 siehe /etc/default/opendkim
local:opendmarc/opendmarc.sock
# inet:10.lan.x.y:12345 siehe /etc/default/opendmarc
# local, rarely used here
non_smtpd_milters =
${smtpd_milters}
apt install rsyslog
defaults are fine, but add
/etc/rsyslog.conf
...
mail.* -/var/log/mail.log
mail.err /var/log/mail.err
...
/etc/opendmarc.conf
RejectFailures true
/etc/postfix-policyd-spf-python/policyd-spf.conf
TestOnly = 0
/etc/postfix/main.cf
header_checks = regexp:/etc/postfix/header_checks
/etc/postfix/header_checks
# Strip internal hop from authenticated clients
/^Received:.*with ESMTPSA/ IGNORE
/^Received:.*with ESMTPA/ IGNORE
# Optional: strip client fingerprinting headers
/^User-Agent:/ IGNORE
/^X-Mailer:/ IGNORE
/^X-Originating-IP:/ IGNORE
# RFC 8601 - strip any incoming forged Authentication-Results headers
# This makes sure we never get spoofed headers
/^Authentication-Results:.*mx\.domain\.tld/ IGNORE
header_checks runs in cleanup
/etc/opendmarc.conf
https://manpages.debian.org/unstable/opendmarc/opendmarc.conf.5.en.html
add these to harden SPF checks
SPFIgnoreResults true
SPFSelfValidate true
postscreen
Workflow ist dass SpamAssassin per milter an postfix angebunden wird und Mails als SPAM markiert. Wir machen hier kein ClamAV/Amavisd weil ich in ~5 Jahren nich eine Viren-Mail erhalten habe...
........... Dovecot
Install:
apt install spamassassin spamc spamass-milter dovecot-sieve dovecot-managesieved
spamc ist der Client der mit spamd (spamassassin daemon) redet
Brauchen hier -u debian-spamd da wir mit vistuellen mailaccounts arbeiten, es gibt also kein ~/.spamassassin
/etc/default/spamd
...
... --allow-tell -u debian-spamd
...
check
/etc/default/spamass-milter
...
# -m Disables modification of the 'Subject:' and 'Content-Type:' headers and message body
# -r If -1, reject scanned email if SpamAssassin tags it as spam
OPTIONS="-u spamass-milter -i 127.0.0.1 -m -r -1"
...
######################################
# If /usr/sbin/postfix is executable, the following are set by
# default. You can override them by uncommenting and changing them
# here.
######################################
# SOCKET="/var/spool/postfix/spamass/spamass.sock"
...
daher:
/etc/postfix/main.cf
...
smtpd_milters =
local:opendkim/opendkim.sock,
local:opendmarc/opendmarc.sock,
local:spamass/spamass.sock
...
sieve sollte in dovecot schon laufen.
https://doc.dovecot.org/2.4.0/core/admin/guides/spam_reporting.html
/etc/dovecot/sieve/spam-to-folder.sieve
require ["fileinto","mailbox"];
if header :contains "X-Spam-Flag" "YES" {
fileinto :create "Junk";
stop;
}
/etc/dovecot/sieve# sievec spam-to-folder.sieve
/etc/dovecot/conf.d/90-sieve.conf
...
sieve_script detected-spam {
type = after
path = /etc/dovecot/sieve/spam-to-folder.sieve
}
...
Für automatisches HAM/SPAM lernen und User-defined filters
/etc/dovecot/conf.d/20-imap.conf
...
protocol imap {
mail_plugins {
sieve = yes
}
...
}
...
/etc/dovecot/conf.d/20-lmtp.conf
...
protocol lmtp {
mail_plugins {
sieve = yes
}
# do not get confused we never use %{user} in pass or userdb
# can be left like this
auth_username_format = %{user | username | lower}
}
...
/etc/dovecot/conf.d/90-sieve.conf
...
sieve_plugins {
sieve_imapsieve = yes
sieve_extprograms = yes
}
sieve_pipe_bin_dir = /etc/dovecot/sieve/scripts
sieve_global_extensions {
vnd.dovecot.pipe = yes
vnd.dovecot.environment = yes
}
mailbox Junk {
# From elsewhere to Junk folder
sieve_script report-spam {
type = before
cause = copy
path = /etc/dovecot/sieve/report-spam.sieve
}
}
# From Junk folder to elsewhere
imapsieve_from Junk {
sieve_script report-ham {
type = before
cause = copy
path = /etc/dovecot/sieve/report-ham.sieve
}
}
...
/etc/dovecot/sieve/scripts/sa-learn-ham.sh
#!/bin/sh
# you can also use tcp/ip here, consult spamc(1)
exec /usr/bin/spamc -u debian-spamd -s 10485760 -L ham
/etc/dovecot/sieve/scripts/sa-learn-spam.sh
#!/bin/sh
# you can also use tcp/ip here, consult spamc(1)
exec /usr/bin/spamc -u debian-spamd -s 10485760 -L spam
Die Sieve Filter übergeben zwar einen username, wir nutzen die aber nicht in den scripts
/etc/dovecot/sieve/report-spam.sieve
require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];
if environment :matches "imap.user" "*" {
set "username" "${1}";
}
# needs to be in sieve_pipe_bin_dir
pipe :copy "sa-learn-spam.sh" [ "${username}" ];
/etc/dovecot/sieve/report-ham.sieve
require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];
if environment :matches "imap.mailbox" "*" {
set "mailbox" "${1}";
}
if string "${mailbox}" "Trash" {
stop;
}
if environment :matches "imap.user" "*" {
set "username" "${1}";
}
# needs to be in sieve_pipe_bin_dir
pipe :copy "sa-learn-ham.sh" [ "${username}" ];
Filter kompilieren und chmod für die Skripte
sievec /etc/dovecot/sieve/report-spam.sieve
sievec /etc/dovecot/sieve/report-ham.sieve
chmod +x /etc/dovecot/sieve/scripts/sa-learn-ham.sh /etc/dovecot/sieve/scripts/sa-learn-spam.sh
https://www.syn-flut.de/spamassassin-erkennungsrate-verbessern
/etc/postfix/main.cf
# See /usr/share/postfix/main.cf.dist for a commented, more complete version
# See http://www.postfix.org/COMPATIBILITY_README.html
compatibility_level = 3.9
## My's
# hostname fqdn, appended to unknown senders from local_header_rewrite_clients (default only inet_interfaces so this host)
myorigin = /etc/mailname
# Sent in EHLO, set this to reverse DNS
myhostname = mx.domain.tld
# Text that follows the 220 code in the SMTP server's greeting banner.
# You MUST specify $myhostname at the start due to an RFC requirement.
smtpd_banner = $myhostname ESMTP $mail_name (Debian)
# Local domain class
mydestination = localhost
## Network
inet_interfaces = all
# IP protocols to use: ipv4, ipv6, or all
# (set this explicitly so `post-install upgrade-configuration' wont complain)
inet_protocols = all
#inet_protocols = ipv4
# fxd ipv6 for nptv6
smtp_bind_address6 = fdxx:xxxx:xxxx:xxxx::fxdlocal
# can send without auth
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
# Default was this
# List of domains (maptype:mapname allowed) that this machine considers
# itself the final destination for.
# mydestination = $myhostname, hostname.domain.tld, localhost.domain.tld, localhost
# /etc/resolv.conf nutzen
# default ist "dns"
# smtp_host_lookup = native
## SSL (Server)
smtpd_tls_key_file = /etc/letsencrypt/live/mx.domain.tld/privkey.pem
smtpd_tls_cert_file = /etc/letsencrypt/live/mx.domain.tld/fullchain.pem
# SMTP Server security level: none|may|encrypt
# may offers STARTTLS. One shall not enforce SSL on public servers
smtpd_tls_security_level = may
# allow auth only over SSL
smtpd_tls_auth_only = yes
# Modern TLS only
smtpd_tls_mandatory_protocols = >=TLSv1.3
# Sichere Cipher erzwingen
smtpd_tls_mandatory_ciphers = high
# Logging
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
## SSL (Client)
# we send to everyone not just a relayhost
smtp_tls_security_level = may
smtp_tls_loglevel = $smtpd_tls_loglevel
smtp_tls_mandatory_protocols = $smtpd_tls_mandatory_protocols
#smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_mandatory_ciphers = $smtpd_tls_mandatory_ciphers
# handy to keep some TLS sessions
# SMTP Client TLS session cache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
# @TBT needed? This will be loaded prior to chroot
# List of CAs for SMTP Client to trust
# Prefer this over _CApath when smtp is running chrooted
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
## Local delivery
# Optional external command to use instead of mailbox delivery. If set,
# you must set up an alias to forward root mail to a real user.
#mailbox_command = /usr/bin/procmail
#mailbox_command = /usr/bin/procmail -a "$EXTENSION"
mailbox_command =
# List of alias maps to use to lookup local addresses.
# Per Debian Policy it should be /etc/aliases.
alias_maps = hash:/etc/aliases
# List of alias maps to make indexes on, when running newaliases.
alias_database = hash:/etc/aliases
# Notify (or not) local biff service when new mail arrives.
# Rarely used these days.
biff = no
## Maps
# Separator between user name and address extension (user+foo@domain
#
recipient_delimiter = +
virtual_mailbox_domains = ldap:/etc/postfix/ldap_lookups/virtual_mailbox_domains
virtual_mailbox_maps = ldap:/etc/postfix/ldap_lookups/virtual_mailbox_maps, ldap:/etc/postfix/ldap_lookups/virtual_mailbox_maps_catchall
## Auth
# Where to look for Cyrus SASL configuration files. Upstream default is unset
# (use compiled-in SASL library default), Debian Policy says it should be
# /etc/postfix/sasl.
# not in use, dovecot.
# cyrus_sasl_config_path = /etc/postfix/sasl
smtpd_sasl_type = dovecot
smtpd_sasl_auth_enable = yes
# Unix-Listener
smtpd_sasl_path = private/auth
# Inet-Listener
# smtpd_sasl_path = inet:[127.0.0.1]:26
## Milters
# The default action when a Milter (mail filter) response is unavailable
milter_default_action = accept
# default
milter_protocol = 6
smtpd_milters =
local:opendkim/opendkim.sock,
local:opendmarc/opendmarc.sock,
local:spamass/spamass.sock
# local, rarely used here
non_smtpd_milters =
${smtpd_milters}
## Receiving Mail
## SPAM
policy-spf_time_limit = 3600s
# during cleanup/access https://www.postfix.org/SMTPD_ACCESS_README.html
# applied in the context of a client connection request.
smtpd_client_restrictions =
# applied in the context of a client MAIL FROM command
# (default: empty)
smtpd_sender_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
# MAIL FROM address specifies a domain that is not in fully-qualified domain form
reject_non_fqdn_sender,
# MAIL FROM domain has 1) no DNS MX and no DNS A record, or 2) a malformed MX record
reject_unknown_sender_domain
# applied in the context of the RCPT TO command, before smtpd_recipient_restrictions.
# (default: permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination)
smtpd_relay_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
# reject not defer
reject_unauth_destination
# applied in the context of a client RCPT TO command
# (default: empty)
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
# broken senders and bad actors
# Postfix is not final destination for the recipient domain, and the RCPT TO domain has 1) no DNS MX and no DNS A record or 2) a malformed MX record
reject_unknown_recipient_domain,
# spamhouse
reject_rhsbl_sender youbet.dbl.dq.spamhaus.net=127.0.1.[2..99],
reject_rhsbl_helo youbet.dbl.dq.spamhaus.net=127.0.1.[2..99],
reject_rhsbl_reverse_client youbet.dbl.dq.spamhaus.net=127.0.1.[2..99],
reject_rhsbl_sender youbet.zrd.dq.spamhaus.net=127.0.2.[2..24],
reject_rhsbl_helo youbet.zrd.dq.spamhaus.net=127.0.2.[2..24],
reject_rhsbl_reverse_client youbet.zrd.dq.spamhaus.net=127.0.2.[2..24],
reject_rbl_client youbet.zen.dq.spamhaus.net=127.0.0.[2..255]
# run this after dnsbl
# https://www.postfix.org/SMTPD_POLICY_README.html
check_policy_service unix:private/policy-spf,
# applied in the context of the SMTP DATA command
smtpd_data_restrictions =
# Block clients that speak too early.
reject_unauth_pipelining
rbl_reply_maps = hash:/etc/postfix/dnsbl-reply-map
## Sending Mail
# not in use
relayhost =
smtpd_sender_login_maps =
# Satellites
hash:/etc/postfix/sender_login_maps
# logged in users
ldap:/etc/postfix/ldap_lookups/smtpd_sender_login_maps
sender_bcc_maps = hash:/etc/postfix/bcc_map
## Relaying
relay_domains = /etc/postfix/relay_domains
## Transport
# for relaying
transport_maps = hash:/etc/postfix/transport_maps
# for virtual mailbox domains
virtual_transport = lmtp:unix:private/dovecot-lmtp
## Mailbox
#home_mailbox not in use
# default
#mail_spool_directory = /var/mail
# The maximal size of any local(8) individual mailbox or maildir file (default: 51200000)
mailbox_size_limit = 0
## Mail Size
# 100MB statt 10
message_size_limit = 102400000
## Strip headers
header_checks = regexp:/etc/postfix/header_checks
## Unused but interesting
# The time after which the sender receives a copy of the message headers of mail that is still queued
# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h
/etc/postfix/master.cf
smtp inet n - y - - smtpd
submission inet n - y - - smtpd
submissions inet n - y - - smtpd
-o smtpd_tls_wrappermode=yes
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 syslog_name=${multi_instance_name?{$multi_instance_name}:{postfix}}/$service_name
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
postlog unix-dgram n - n - 1 postlogd
policy-spf unix - n n - - spawn
user=nobody argv=/usr/bin/policyd-spf