====== Postfix Mail Server ======
* [[Mail Servers]]
* [[SendGrid]]
* [[SSMTP]]
* [[pflogsumm]]
* [[http://www.mail-tester.com/|Mail Tester]] - great for seeing how to improve outgoing mail setup, check for spam, etc.
* [[https://toolbox.googleapps.com/apps/checkmx/|Check MX]]
* [[https://sendgrid.com/blog/smtp-server-response-codes-explained/|SMTP Response Codes]]
Postfix is the SMTP server of choice, used to send outgoing email messages to the world.
==== Howto ====
To see the mail queue:
mailq
To flush the queue and try to re-send all the messages:
postfix flush
To remove all mail from the queue:
postsuper -d ALL
To remove all mail marked as deferred in the queue:
postsuper -d ALL deferred
Display configuration
postconf -d
=== Local Mail Only ===
You can setup Postfix so that it doesn't send any outgoing email at all, but instead delivers everything locally to one user account.
Add this to Postfix's ''main.cf'':
canonical_maps = regexp:/etc/postfix/canonical-redirect
and for the contents of the new file, choose the user and send all mail there:
/^.*$/ steve
Finally, reload or restart Postfix:
postfix reload
==== Source Build ====
Build with SASL and TLS support for using a third party SMTP relay server:
make makefiles CCARGS="-DUSE_SASL_AUTH -DUSE_CYRUS_SASL -I/usr/include/sasl -DUSE_TLS -I/usr/include/openssl/" AUXLIBS="-lsasl2 -lssl -lcrypto"
Next, run ''make install''. The defaults will place all the binaries in ''/usr'' as normal.
==== Logging ====
Logging can be made more verbose by editing ''/etc/postfix/master.cf'' and adding ''-v'' to the lines containing ''smtpd''.
For example:
smtp inet n - n - - smtpd -v
If creating a new ''/var/log/maillog'' you will need to restart your system logger **in addition** to postfix for it to populate.
==== Security ====
Enable Postfix to use TLS if possible. Clients and servers that connect may use it. In ''main.cf'':
smtp_tls_security_level = may
smtpd_tls_security_level = may
If you have your own certs, enable those as well. In this case, the ''server.pem'' is the combination of the CRT PEM and the CA bundle PEM. Be sure to set the key to read-only for the root user as well.
cat beandog.crt.pem ca_bundle.pem > server.pem
smtpd_tls_cert_file = /etc/postfix/server.pem
smtpd_tls_key_file = /etc/postfix/server.key
Postfix can define which protocols and ciphers to ignore, and set the preferred order as well. Here, ignore TLSv1 and use stronger ciphers.
Also, if you are using OpenSSL 1.1.1 or higher, you can add TLSv1.3 to the list.
smtp_tls_ciphers = high
smtp_tls_mandatory_ciphers = high
smtp_tls_protocols = TLSv1.2, TLSv1.1, !TLSv1
smtp_tls_mandatory_protocols = TLSv1.2, TLSv1.1, !TLSv1
smtpd_tls_ciphers = high
smtpd_tls_mandatory_ciphers = high
smtpd_tls_protocols = TLSv1.2, TLSv1.1, !TLSv1
smtpd_tls_mandatory_protocols = TLSv1.2, TLSv1.1, !TLSv1
Specific ciphers can be disabled as well. For a list of all ciphers that are available, use ''openssl'':
openssl ciphers
To make it easier to read, one per line:
openssl ciphers | tr ':' '\n'
You can find the ciphers or cipher family you'd like to drop by specifying the cipher list. For example::
openssl ciphers MD5:aNULL
And then disable those in ''main.cf'':
smtp_tls_exclude_ciphers = MD5, aNULL
smtp_tls_mandatory_exclude_ciphers = MD5, aNULL
smtpd_tls_exclude_ciphers = MD5, aNULL
smtpd_tls_mandatory_exclude_ciphers = MD5, aNULL
==== Virtual Domains and Aliases ====
Configure Postfix to accept email from additional domains. In ''/etc/postfix/main.cf'':
virtual_alias_domains = hash:/etc/postfix/virtual_domains
virtual_alias_maps = hash:/etc/postfix/virtual_aliases
In ''/etc/postfix/virtual_domains'':
wonkabar.org comment-ignored
In ''/etc/postfix/virtual_aliases'', send all email for ''wonkabar.org'' to user root on local box:
@wonkabar.org root
Create the database hashes once the files are created and reload postfix:
postmap virtual_domains
postmap virtual_aliases
postfix reload
Here's an example the maillog where an email sent to postmaster@wonkabar.org is delivered locally to user root@beandog.org:
Oct 28 20:52:11 lkmx postfix/local[29196]: 8A35EC93E1: to=, orig_to=, relay=local, delay=0.05, delays=0.05/0/0/0, dsn=2.0.0, status=sent (delivered to mailbox)
==== FreeBSD ====
/etc/rc.d/sendmail stop
pkg_upgrade -r postfix
echo sendmail_enable="NO" >> /etc/rc.conf
echo sendmail_submit_enable="NO" >> /etc/rc.conf
echo sendmail_outbound_enable="NO" >> /etc/rc.conf
echo sendmail_msp_queue_enable="NO" >> /etc/rc.conf
echo daily_clean_hoststat_enable="NO" >> /etc/periodic.conf
echo daily_status_mail_rejects_enable="NO" >> /etc/periodic.conf
echo daily_status_include_submit_mailq="NO" >> /etc/periodic.conf
echo daily_submit_queuerun="NO" >> /etc/periodic.conf
echo postfix_enable="YES" >> /etc/rc.conf
/usr/local/etc/rc.d/postfix start
==== Configuration ====
When changing the Postfix configuration, you can either run ''postfix reload'' or restart it through the init system. If the changes are significant, or if ''postfix check'' complains, then restart it with init.
A default Postfix installation has a reasonable configuration.
Some common changes are:
* myhostname
* mydomain
* myorigin
* inet_interfaces
* mydestination
Set ''smtp_tls_security_level'' to ''may'' so that TLS can be used to transfer mail.
# INTERNET HOST AND DOMAIN NAMES
#
# The myhostname parameter specifies the internet hostname of this
# mail system. The default is to use the fully-qualified domain name
# from gethostname(). $myhostname is used as a default value for many
# other configuration parameters.
#
#myhostname = host.domain.tld
#myhostname = virtual.domain.tld
# The mydomain parameter specifies the local internet domain name.
# The default is to use $myhostname minus the first component.
# $mydomain is used as a default value for many other configuration
# parameters.
#
#mydomain = domain.tld
# SENDING MAIL
#
# The myorigin parameter specifies the domain that locally-posted
# mail appears to come from. The default is to append $myhostname,
# which is fine for small sites. If you run a domain with multiple
# machines, you should (1) change this to $mydomain and (2) set up
# a domain-wide alias database that aliases each user to
# user@that.users.mailhost.
#
# For the sake of consistency between sender and recipient addresses,
# myorigin also specifies the default domain name that is appended
# to recipient addresses that have no @domain part.
#
#myorigin = $myhostname
#myorigin = $mydomain
# RECEIVING MAIL
# The inet_interfaces parameter specifies the network interface
# addresses that this mail system receives mail on. By default,
# the software claims all active interfaces on the machine. The
# parameter also controls delivery of mail to user@[ip.address].
#
# See also the proxy_interfaces parameter, for network addresses that
# are forwarded to us via a proxy or network address translator.
#
# Note: you need to stop/start Postfix when this parameter changes.
#
#inet_interfaces = all
#inet_interfaces = $myhostname
#inet_interfaces = $myhostname, localhost
# The mydestination parameter specifies the list of domains that this
# machine considers itself the final destination for.
#
# These domains are routed to the delivery agent specified with the
# local_transport parameter setting. By default, that is the UNIX
# compatible delivery agent that lookups all recipients in /etc/passwd
# and /etc/aliases or their equivalent.
#
# The default is $myhostname + localhost.$mydomain. On a mail domain
# gateway, you should also include $mydomain.
#
# Do not specify the names of virtual domains - those domains are
# specified elsewhere (see VIRTUAL_README).
#
# Do not specify the names of domains that this machine is backup MX
# host for. Specify those names via the relay_domains settings for
# the SMTP server, or use permit_mx_backup if you are lazy (see
# STANDARD_CONFIGURATION_README).
#
# The local machine is always the final destination for mail addressed
# to user@[the.net.work.address] of an interface that the mail system
# receives mail on (see the inet_interfaces parameter).
#
# Specify a list of host or domain names, /file/name or type:table
# patterns, separated by commas and/or whitespace. A /file/name
# pattern is replaced by its contents; a type:table is matched when
# a name matches a lookup key (the right-hand side is ignored).
# Continue long lines by starting the next line with whitespace.
#
# See also below, section "REJECTING MAIL FOR UNKNOWN LOCAL USERS".
#
#mydestination = $myhostname, localhost.$mydomain, localhost
#mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
#mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain,
# mail.$mydomain, www.$mydomain, ftp.$mydomain