Difference between revisions of "Postfix"

From ArchWiki
Jump to: navigation, search
m (增加简体中文)
(Local mail: I rechaned the destination, Because I was wrong)
Line 56: Line 56:
  myhostname = localhost
  myhostname = localhost
  mydomain = localdomain
  mydomain = localdomain
  mydestination = $myhostname, localhost.$mydomain, $mydomain
  mydestination = $myhostname, localhost.$mydomain, localhost
  inet_interfaces = $myhostname, localhost
  inet_interfaces = $myhostname, localhost
  mynetworks_style = host
  mynetworks_style = host

Revision as of 20:11, 30 November 2018

Postfix is a mail transfer agent that according to its website:

attempts to be fast, easy to administer, and secure, while at the same time being sendmail compatible enough to not upset existing users. Thus, the outside has a sendmail-ish flavor, but the inside is completely different.

This article builds upon Mail server. The goal of this article is to setup Postfix and explain what the basic configuration files do. There are instructions for setting up local system user-only delivery and a link to a guide for virtual user delivery.


Install the postfix package.


See Postfix Basic Configuration. Configuration files are in /etc/postfix by default. The two most important files are:

  • master.cf, defines what Postfix services are enabled an what how clients connect to them, see master(5)
  • main.cf, the main configuration file, see postconf(5)

Configuration changes need a postfix.service reload in order to take effect.


See aliases(5).

You can specify aliases (also known as forwarders) in /etc/postfix/aliases.

You need to map all mail addressed to root to another account since it is not a good idea to read mail as root.

Uncomment the following line, and change you to a real account.

root: you

Once you have finished editing /etc/postfix/aliases you must run the postalias command:

postalias /etc/postfix/aliases

For later changes you can use:

Tip: Alternatively you can create the file ~/.forward, e.g. /root/.forward for root. Specify the user to whom root mail should be forwarded, e.g. user@localhost.

Local mail

To only deliver mail to local system users (that are in /etc/passwd) update /etc/postfix/main.cf to reflect the following configuration. Uncomment, change, or add the following lines:

myhostname = localhost
mydomain = localdomain
mydestination = $myhostname, localhost.$mydomain, localhost
inet_interfaces = $myhostname, localhost
mynetworks_style = host
default_transport = error: outside mail is not deliverable

All other settings may remain unchanged. After setting up the above configuration file, you may wish to set up some #Aliases and then #Start Postfix.

Virtual mail

Virtual mail is mail that does not map to a user account (/etc/passwd).

See Virtual user mail system with Postfix, Dovecot and Roundcube for a comprehensive guide how to set it up.

Check configuration

Run the postfix check command. It should output anything that you might have done wrong in a config file.

To see all of your configs, type postconf. To see how you differ from the defaults, try postconf -n.

Start Postfix

Note: You must run newaliases at least once for Postfix to run, even if you did not set up any #Aliases.

Start/enable the postfix.service.


Warning: If you deploy TLS, be sure to follow weakdh.org's guide to prevent FREAK/Logjam. Since mid-2015, the default settings have been safe against POODLE. For more information see Server-side TLS.

You need to obtain a certificate.

For more information, see Postfix TLS Support.

Secure SMTP (sending)

By default, Postfix/sendmail will not send email encrypted to other SMTP servers. To use TLS when available, add the following line to main.cf:

smtp_tls_security_level = may

To enforce TLS (and fail when the remote server does not support it), change may to encrypt. Note, however, that this violates RFC:2487 if the SMTP server is publicly referenced.

Secure SMTP (receiving)

Tango-view-refresh-red.pngThis article or section is out of date.Tango-view-refresh-red.png

Reason: Port 465 has been reinstated for SMTPS by RFC:8314. (Discuss in Talk:Postfix#)

By default, Postfix will not accept secure mail.

To enable STARTTLS over SMTP (port 587, the proper way of securing SMTP), add the following lines to main.cf

smtpd_tls_security_level = may
smtpd_tls_cert_file = /path/to/cert.pem
smtpd_tls_key_file = /path/to/key.pem

In master.cf, find and uncomment the following lines to enable the service on that port with the correct settings:

submission inet n       -       n       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_tls_auth_only=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

The smtpd_*_restrictions options remain commented because $mua_*_restrictions are not defined in main.cf by default. If you do decide to set any of $mua_*_restrictions, uncomment those lines too.

If you need support for the deprecated SMTPS port 465, also follow the next section.

SMTPS (port 465)

The deprecated method of securing SMTP is using the wrapper mode which uses the system service smtps as a non-standard service and runs on port 465.

To enable it, uncomment the following lines in master.cf:

smtps     inet  n       -       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

The rationale surrounding the $smtpd_*_restrictions lines is the same as above.

After this, verify that these lines are in /etc/services:

smtps 465/tcp # Secure SMTP
smtps 465/udp # Secure SMTP

If they are not there, go ahead and add them (replace the other listing for port 465). Otherwise Postfix will not start and you will get the following error:

postfix/master[5309]: fatal: Servname not supported for ai_socktype

Tips and tricks

Blacklist incoming emails

Manually blacklisting incoming emails by sender address can easily be done with Postfix.

Create and open /etc/postfix/blacklist_incoming file and append sender email address:

user@example.com REJECT

Then use the postmap command to create a database:

# postmap hash:blacklist_incoming

Add the following code before the first permit rule in main.cf:

smtpd_recipient_restrictions = check_sender_access hash:/etc/postfix/blacklist_incoming

Finally restart postfix.service.

Hide the sender's IP and user agent in the Received header

This is a privacy concern mostly, if you use Thunderbird and send an email. The received header will contain your LAN and WAN IP and info about the email client you used. (Original source: AskUbuntu) What we want to do is remove the Received header from outgoing emails. This can be done by the following steps:

Add the following line to main.cf:

smtp_header_checks = regexp:/etc/postfix/smtp_header_checks

Create /etc/postfix/smtp_header_checks with this content:

/^Received: .*/     IGNORE
/^User-Agent: .*/   IGNORE

Finally, restart postfix.service.

Postfix in a chroot jail

Postfix is not put in a chroot jail by default. The Postfix documentation [1] provides details about how to accomplish such a jail. The steps are outlined below and are based on the chroot-setup script provided in the Postfix source code.

First, go into the master.cf file in the directory /etc/postfix and change all the chroot entries to 'yes' (y) except for the services qmgr, proxymap, proxywrite, local, and virtual

Second, create two functions that will help us later with copying files over into the chroot jail (see last step)

CP="cp -p"
cond_copy() {
  # find files as per pattern in $1
  # if any, copy to directory $2
  dir=`dirname "$1"`
  pat=`basename "$1"`
  lr=`find "$dir" -maxdepth 1 -name "$pat"`
  if test ! -d "$2" ; then exit 1 ; fi
  if test "x$lr" != "x" ; then $CP $1 "$2" ; fi

Next, make the new directories for the jail:

set -e
umask 022
mkdir -p etc lib usr/lib/zoneinfo
test -d /lib64 && mkdir -p lib64

Find the localtime file

if test ! -f $lt ; then lt=/usr/lib/zoneinfo/localtime ; fi
if test ! -f $lt ; then lt=/usr/share/zoneinfo/localtime ; fi
if test ! -f $lt ; then echo "cannot find localtime" ; exit 1 ; fi
rm -f etc/localtime

Copy localtime and some other system files into the chroot's etc

$CP -f $lt /etc/services /etc/resolv.conf /etc/nsswitch.conf etc
$CP -f /etc/host.conf /etc/hosts /etc/passwd etc
ln -s -f /etc/localtime usr/lib/zoneinfo

Copy required libraries into the chroot using the previously created function cond_copy

cond_copy '/usr/lib/libnss_*.so*' lib
cond_copy '/usr/lib/libresolv.so*' lib
cond_copy '/usr/lib/libdb.so*' lib

And don't forget to reload Postfix.


Resource Record

Warning: This is not a trivial section. Be aware that you make sure you know what you are doing. You better read Common Mistakes before.

DANE supports several types of records, however not all of them are suitable in Postfix.

Certificate usage 0 is unsupported, 1 is mapped to 3 and 2 is optional, thus it is recommendet to publish a "3" record. More on Resource Records.


Tango-view-fullscreen.pngThis article or section needs expansion.Tango-view-fullscreen.png

Reason: What does tempfail mean? (Discuss in Talk:Postfix#)

Opportunistic DANE is configured this way:

smtpd_use_tls = yes
smtp_dns_support_level = dnssec
smtp_tls_security_level = dane
dane       unix  -       -       n       -       -       smtp
  -o smtp_dns_support_level=dnssec
  -o smtp_tls_security_level=dane

To use per-domain policies, e.g. opportunistic DANE for example.org and mandatory DANE for example.com, use something like this:

indexed = ${default_database_type}:${config_directory}/

# Per-destination TLS policy
smtp_tls_policy_maps = ${indexed}tls_policy

# default_transport = smtp, but some destinations are special:
transport_maps = ${indexed}transport
example.com dane
example.org dane
example.com dane-only
Note: For global mandatory DANE, change smtp_tls_security_level to dane-only. Be aware that this makes Postfix tempfail (respond with a 4.X.X error code) on all deliveries that do not use DANE at all!

Full documentation is found here.


  • PostfixAdmin — A web-based administrative interface for Postfix.
http://postfixadmin.sourceforge.net/ || postfixadmin


Tango-edit-clear.pngThis article or section needs language, wiki syntax or style improvements. See Help:Style for reference.Tango-edit-clear.png

Reason: See Help:Style (Discuss in Talk:Postfix#)

Postgrey can be used to enable greylisting for a Postfix mail server.


Install the postgrey package. To get it running quickly edit the Postfix configuration file and add these lines:

smtpd_recipient_restrictions =
  check_policy_service inet:

Then start/enable the postgrey service. Afterwards, reload the postfix service. Now greylisting should be enabled.


Configuration is done via editing the postgrey.service file. First copy it over to edit it.

# cp /usr/lib/systemd/system/postgrey.service /etc/systemd/system/


To add automatic whitelisting (successful deliveries are whitelisted and don't have to wait any more), you could add the --auto-whitelist-clients=N option and replace N by a suitably small number (or leave it at its default of 5).

...actually, the preferred method should be the override:

cat /etc/systemd/system/postgrey.service.d/override.conf
ExecStart=/usr/bin/postgrey --inet= \
       --pidfile=/run/postgrey/postgrey.pid \
       --group=postgrey --user=postgrey \
       --daemonize \
       --greylist-text="Greylisted for %%s seconds" \

To add your own list of whitelisted clients in addition to the default ones, create the file /etc/postfix/whitelist_clients.local and enter one host or domain per line, then restart postgrey.service so the changes take effect.


If you specify --unix=/path/to/socket and the socket file is not created ensure you have removed the default --inet= from the service file.

For a full documentation of possible options see perldoc postgrey.


This section describes how to integrate SpamAssassin.

SpamAssassin stand-alone generic setup

Note: If you want to combine SpamAssassin and Dovecot Mail Filtering, ignore the next two lines and continue further down instead.

Edit /etc/postfix/master.cf and add the content filter under smtp.

smtp      inet  n       -       n       -       -       smtpd
  -o content_filter=spamassassin

Also add the following service entry for SpamAssassin

spamassassin unix -     n       n       -       -       pipe
  flags=R user=spamd argv=/usr/bin/vendor_perl/spamc -e /usr/bin/sendmail -oi -f ${sender} ${recipient}

Now you can start and enable spamassassin.service.

SpamAssassin combined with Dovecot LDA / Sieve (Mailfiltering)

Set up LDA and the Sieve-Plugin as described in Dovecot#Sieve. But ignore the last line mailbox_command... .

Instead add a pipe in /etc/postfix/master.cf:

 dovecot   unix  -       n       n       -       -       pipe
       flags=DRhu user=vmail:vmail argv=/usr/bin/vendor_perl/spamc -u spamd -e /usr/lib/dovecot/dovecot-lda -f ${sender} -d ${recipient}

And activate it in /etc/postfix/main.cf:

 virtual_transport = dovecot

SpamAssassin combined with Dovecot LMTP / Sieve

Set up the LMTP and Sieve as described in Dovecot#Sieve.

Edit /etc/dovecot/conf.d/90-plugins.conf and add:

 sieve_before = /etc/dovecot/sieve.before.d/
 sieve_extensions = +vnd.dovecot.filter
 sieve_plugins = sieve_extprograms
 sieve_filter_bin_dir = /etc/dovecot/sieve-filter
 sieve_filter_exec_timeout = 120s #this is often needed for the long running spamassassin scans, default is otherwise 10s

Create the directory and put spamassassin in as a binary that can be ran by dovecot:

 # mkdir /etc/dovecot/sieve-filter
 # ln -s /usr/bin/vendor_perl/spamc /etc/dovecot/sieve-filter/spamc

Create a new file, /etc/dovecot/sieve.before.d/spamassassin.sieve which contains:

 require [ "vnd.dovecot.filter" ];
 filter "spamc" [ "-d", "", "--no-safe-fallback" ];

Compile the sieve rules spamassassin.svbin:

 # cd /etc/dovecot/sieve.before.d
 # sievec spamassassin.sieve

Finally, restart dovecot.service.

Rule-based mail processing

With policy services one can easily finetune Postfix' behaviour of mail delivery. postfwd and policydAUR provide services to do so. This allows you to e.g. implement time-aware grey- and blacklisting of senders and receivers as well as SPF policy checking.

Policy services are standalone services and connected to Postfix like this:

smtpd_recipient_restrictions =
  check_policy_service unix:/run/policyd.sock
  check_policy_service inet:

Placing policy services at the end of the queue reduces load, as only legitimate mails are processed. Be sure to place it before the first permit statement to catch all incoming messages.

Sender Policy Framework

To use the Sender Policy Framework with Postfix, install python-postfix-policyd-spfAUR.

Edit /etc/python-policyd-spf/policyd-spf.conf to your needs. An extensively commented version can be found at /etc/python-policyd-spf/policyd-spf.conf.commented. Pay some extra attention to the HELO check policy, as standard settings strictly reject HELO failures.

In the main.cf add a timeout for the policyd:

policy-spf_time_limit = 3600s

Then add a transport

policy-spf  unix  -       n       n       -       0       spawn
     user=nobody argv=/usr/bin/policyd-spf

Lastly you need to add the policyd to the smtpd_recipient_restrictions. To minimize load put it to the end of the restrictions but above any reject_rbl_client DNSBL line:

     check_policy_service unix:private/policy-spf

You can test your Setup with the following:

defaultSeedOnly = 0

Sender Rewriting Scheme

To use the Sender Rewriting Scheme with Postfix, install postsrsdAUR and adjust the settings:


Enable and start the daemon, making sure it runs after reboot as well. Then configure Postfix accordingly by tweaking the following lines:

sender_canonical_maps = tcp:localhost:10001
sender_canonical_classes = envelope_sender
recipient_canonical_maps = tcp:localhost:10002
recipient_canonical_classes= envelope_recipient,header_recipient

Restart Postfix and start forwarding mail.


Warning: "database /etc/postfix/*.db is older than source file .."

If you get one or both warnings with journalctl

warning: database /etc/postfix/virtual.db is older than source file /etc/postfix/virtual
warning: database /etc/postfix/transport.db is older than source file /etc/postfix/transport

then you can fix it by using these commands depending on the messages you get

postmap /etc/postfix/transport
postmap /etc/postfix/virtual

and restart postfix.service

See also