Difference between revisions of "Postfix"

From ArchWiki
Jump to: navigation, search
m (Step 2: setup table structure: single to double quotes to prevent interpretation as markup (caused by PRE > bc conversion))
(TLS: this only applies to the "receiving" section)
 
(251 intermediate revisions by 69 users not shown)
Line 1: Line 1:
[[Category:Mail Server]]
+
[[Category:Mail server]]
{{Article summary start}}
+
[[ja:Postfix]]
{{Article summary text|This article discusses the installation and configuration of Postfix}}
+
[[zh-hans:Postfix]]
{{Article summary heading|Related}}
+
{{Related articles start}}
{{Article summary wiki|PostFix Howto With SASL}}
+
{{Related|Postfix with SASL}}
{{Article summary wiki|Simple Virtual User Mail System}}
+
{{Related|Virtual user mail system}}
{{Article summary wiki|Courier MTA}}
+
{{Related|OpenDMARC}}
{{Article summary wiki|SOHO Postfix}}
+
{{Related|OpenDKIM}}
{{Article summary end}}
+
{{Related articles end}}
 +
[[Wikipedia:Postfix (software)|Postfix]] is a [[mail transfer agent]] that according to [http://www.postfix.org/ 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.
  
From [http://www.postfix.org/ Postfix's site]:
+
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.  
:"''Postfix 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.''"
 
  
The goal of this article is to setup Postfix for virtual mailbox delivery only. There will be no delivery to user accounts on the system ({{ic|/etc/passwd}}). Further, access will only be available via a web mail frontend (Squirrelmail), no direct POP3 or IMAP access will be granted. It should be fairly easy to allow those additional features given the information below, but it is not within the scope of this document.
+
== Installation ==
  
== Required packages ==
+
[[Install]] the {{Pkg|postfix}} package.
  
{{Accuracy|The squirrelmail package is currently dropped from the offical repositories and moved to the [[AUR]]. {{Pkg|roundcubemail}} is an officially supported possible alternative to Squirrelmail}}
+
== Configuration ==
  
* {{Pkg|postfix}}
+
See [http://www.postfix.org/BASIC_CONFIGURATION_README.html Postfix Basic Configuration]. Configuration files are in {{ic|/etc/postfix}} by default. The two most important files are:
* {{AUR|courier-imap}}
 
* {{Pkg|squirrelmail}}
 
* {{Pkg|mariadb}}
 
* {{Pkg|apache}}
 
* {{Pkg|openssl}}
 
  
== Postfix configuration ==
+
* {{ic|master.cf}}, defines what Postfix services are enabled an what how clients connect to them, see {{man|5|master}}
 +
* {{ic|main.cf}}, the main configuration file, see {{man|5|postconf}}
  
=== Step 1: check /etc/passwd, /etc/group ===
+
Configuration changes need a {{ic|postfix.service}} [[reload]] in order to take effect.
  
After Postfix installation, make sure that the following shows up in {{ic|/etc/passwd}}:
+
=== Aliases ===
postfix:x:73:73::/var/spool/postfix:/bin/false
 
  
Make sure that the following shows up in {{ic|/etc/group}}:
+
See {{man|5|aliases|url=https://jlk.fjfi.cvut.cz/arch/manpages/man/postfix/aliases.5.en}}.
postdrop:x:75:
 
postfix:x:73:
 
  
{{Note|Postfix can be made to run in a chroot. This document does not currently cover this and might be added later.}}
+
You can specify aliases (also known as forwarders) in {{ic|/etc/postfix/aliases}}.
  
=== Step 2: setup MX record ===
+
You need to map all mail addressed to ''root'' to another account since it is not a good idea to read mail as root.
  
An MX record should point to the mail host. Usually this is done from configuration interface of your domain provider.
+
Uncomment the following line, and change {{ic|you}} to a real account.
 +
root: you
  
A mail exchanger record (MX record) is a type of resource record in the Domain Name System that specifies a mail server responsible for accepting email messages on behalf of a recipient's domain.
+
Once you have finished editing {{ic|/etc/postfix/aliases}} you must run the postalias command:
 +
postalias /etc/postfix/aliases
 +
For later changes you can use:
 +
newaliases
  
When an e-mail message is sent through the Internet, the sending mail transfer agent queries the Domain Name System for MX records of each recipient's domain name. This query returns a list of host names of mail exchange servers accepting incoming mail for that domain and their preferences. The sending agent then attempts to establish an SMTP connection to one of these servers, starting with the one with the smallest preference number, delivering the message to the first server with which a connection can be made.  
+
{{Tip|Alternatively you can create the file {{ic|~/.forward}}, e.g. {{ic|/root/.forward}} for root. Specify the user to whom root mail should be forwarded, e.g. ''user@localhost''.
  
{{Note|Some mail servers will not deliver mail to you if your MX record points to a CNAME. For best results, always point an MX record to an A record definition. For more information, see e.g. [https://secure.wikimedia.org/wikipedia/en/wiki/List_of_DNS_record_types Wikipedia's List of DNS Record Types].}}
+
{{hc|/root/.forward|
 +
user@localhost
 +
}}
  
=== Step 3: /etc/postfix/master.cf ===
+
}}
 
 
This is the Pipeline configuration file, in which you can put your new pipes e.g. to check for Spam!
 
 
 
=== Step 4: /etc/postfix/main.cf ===
 
 
 
==== For virtual mail ====
 
 
 
===== Step 4.1 myhostname =====
 
 
 
set myhostname if your mail server has multiple domains, and you do not want the primary domain to be the mail host. The default is to use the result of a gethostname() call if nothing is specified.
 
For our purposes we will just set it as follows:
 
 
 
myhostname = mail.nospam.net
 
 
 
This is assuming that a DNS A record, and an MX record both point to mail.nospam.net
 
 
 
===== Step 4.2 mydomain =====
 
 
 
this is usually the value of myhostname, minus the first part. If your domain is wonky, then just set it manually:
 
 
 
mydomain = nospam.net
 
 
 
===== Step 4.3 myorigin =====
 
 
 
this is where the email will be seen as being sent from. I usually set this to the value of mydomain. For simple servers, this works fine. This is for mail originating from a local account. Since we are not doing local delivery (except sending), then this is not really as important as it normally would be.
 
 
 
myorigin = $mydomain
 
 
 
===== Step 4.4 mydestination =====
 
 
 
This is the lookup for local users. Since we are not going to deliver internet mail for any local users, set this to localhost only.
 
 
 
mydestination = localhost
 
  
===== Step 4.5 mynetworks and mynetwork_style =====
+
=== Local mail ===
  
Both of these control relaying, and whom is allowed to. We do not want any relaying.
+
To only deliver mail to local system users (that are in {{ic|/etc/passwd}}) update {{ic|/etc/postfix/main.cf}} to reflect the following configuration. Uncomment, change, or add the following lines:
For our sakes, we will simply set mynetwork_style to host, as we are trying to make a standalone postfix host, that people with use webmail on. No relaying, no other MTA's. Just webmail.
 
  
 +
myhostname = localhost
 +
mydomain = localdomain
 +
mydestination = $myhostname, localhost.$mydomain, localhost
 +
inet_interfaces = $myhostname, localhost
 
  mynetworks_style = host
 
  mynetworks_style = host
 +
default_transport = error: outside mail is not deliverable
  
===== Step 4.6 relaydomains =====
+
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]].
  
This controls the destinations that Postfix will relay TO. The default value is $mydestination. This should be fine for now.
+
=== Virtual mail ===
 +
Virtual mail is mail that does not map to a user account ({{ic|/etc/passwd}}).
  
relay_domains = $mydestination
+
See [[Virtual user mail system with Postfix, Dovecot and Roundcube]] for a comprehensive guide how to set it up.
  
===== Step 4.7 home_mailbox =====
+
=== Check configuration ===
  
This setting controls how mail is stored for the users.
+
Run the {{ic|postfix check}} command. It should output anything that you might have done wrong in a config file.  
Set this to "Maildir/", as courier IMAP requires Maildir style mail storage. This is a good thing. Maildir format mailboxes remove the possible race conditions that can occur with old style mbox formats. No more need to deal with file locking. The '/' at the end is REQUIRED.
 
  
home_mailbox = Maildir/
+
To see all of your configs, type {{ic|postconf}}. To see how you differ from the defaults, try {{ic|postconf -n}}.
  
===== Step 4.8 virtual_mail =====
+
== Start Postfix ==
  
Virtual mail is mail that does not map to a user account ({{ic|/etc/passwd}}). This is where all the email for the system will be kept. We are not doing local delivery, remember, so if you want a user that has the same name as a local user, just make a virtual account with the same name.
+
{{Note|You must run {{ic|newaliases}} at least once for Postfix to run, even if you did not set up any [[#Aliases]].}}
First thing we need to do is add the following:
 
  
virtual_mailbox_domains = virtualdomain.tld
+
[[Start/enable]] the {{ic|postfix.service}}.
virtual_alias_maps = hash:/etc/postfix/virtual_alias, mysql:/etc/postfix/mysql_virtual_forwards.cf
 
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains.cf
 
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailboxes.cf
 
virtual_mailbox_base = /home/vmailer
 
virtual_uid_maps = static:5003
 
virtual_gid_maps = static:5003
 
virtual_minimum_uid = 5003
 
virtual_mailbox_limit = 51200000
 
  
virtual_mailbox_domains is a list of the domains that you want to receive mail for. This CANNOT be the same thing that is listed in mydestination. That is why we left mydestination to be localhost only.
+
== TLS ==
virtual_mailbox_maps will contain the info about the virtual users and their mailbox locations. We are using a hash file to store the more permanent maps, and these will override the forwards in the MySQL database.
 
  
virtual_mailbox_base is the base dir where the virtual mailboxes will be stored.
+
For more information, see [http://www.postfix.org/TLS_README.html Postfix TLS Support].
The gid and uid maps are the real system user account that the virtual mail will be owned by. This is for storage purposes. Since we will be using a web interface, and do not want people accessing this by any other means, we will be creating this account later with no login access.
 
Virtual_mailbox_limit controls the size of the mailbox. I do not know how well this works yet. I have set the size above to about 50MB.
 
  
===== Step 4.9 Default message and mailbox size limits =====
+
=== Secure SMTP (sending) ===
  
Postfix imposes both message and mailbox size limits by default. The message_size_limit controls the maximum size in bytes of a message, including envelope information. (default 10240000) The mailbox_size_limit controls the maximum size of any local individual mailbox or maildir file. This limits the size of '''any''' file that is written to upon local delivery, '''including files written by external commands''' (i.e. procmail) that are executed by the local delivery agent. (default is 51200000, set to 0 for no limit) If bounced message notifications are generated, check the size of the local mailbox under {{ic|/var/spool/mail}} and use postconf to check these size limits:
+
By default, Postfix/sendmail will not send email encrypted to other SMTP servers. To use TLS when available, add the following line to {{ic|main.cf}}:
 +
{{hc|/etc/postfix/main.cf|2=
 +
smtp_tls_security_level = may
 +
}}
  
  supersff:~> postconf -d mailbox_size_limit
+
To ''enforce'' TLS (and fail when the remote server does not support it), change {{ic|may}} to {{ic|encrypt}}. Note, however, that this violates [[RFC:2487]] if the SMTP server is publicly referenced.
mailbox_size_limit = 51200000
 
supersff:~> postconf -d message_size_limit
 
message_size_limit = 10240000
 
  
==== Local mail ====
+
=== Secure SMTP (receiving) ===
  
The only things you need to change in {{ic|/etc/postfix/main.cf}} are as follows. Uncomment them and modify them to the specifics listed below. Everything else can be left as installed.
+
{{Warning|If you deploy [[Wikipedia:TLS|TLS]], be sure to follow [https://weakdh.org/sysadmin.html weakdh.org's guide] to prevent FREAK/Logjam. Since mid-2015, the default settings have been safe against [[Wikipedia:POODLE|POODLE]]. For more information see [[Server-side TLS]].}}
  
inet_interfaces = loopback-only
+
By default, Postfix will not accept secure mail.
mynetworks_style = host
 
append_dot_mydomain = no
 
default_transport = error: Local delivery only!
 
  
If you want to control where the mail gets delivered and which mailbox format is to be used, you can do this by setting:
+
You need to [[obtain a certificate]]. Point Postfix to your TLS certificates by adding the following lines to {{ic|main.cf}}:
home_mailbox = /some/path
 
or:
 
mail_spool_directory some/path
 
''mail_spool_directory'' is an absolute path where all mail goes, while ''home_mailbox'' specifies a mailbox relative to the user's home directory. If the path ends with a slash ('/'), messages are stored in Maildir format (directory tree, one message per file); if it doesn't, the mbox format is used (all mail in one file).  
 
  
Examples:
+
{{hc|/etc/postfix/main.cf|2=
mail_spool_directory = /var/mail  (1)
+
smtpd_tls_security_level = may
home_mailbox = Maildir/           (2)
+
smtpd_tls_cert_file = '''/path/to/cert.pem'''
1) All mail will be stored in {{ic|/var/mail}}, mbox format.
+
smtpd_tls_key_file = '''/path/to/key.pem'''
 +
}}
  
2) Mail will be saved in {{ic|~/Maildir}}, Maildir format.
+
There are two ways to accept secure mail. STARTTLS over SMTP (port 587) and SMTPS (port 465). The latter was previously deprecated but was reinstated by [[RFC:8314]].
  
=== Step 4: /etc/postfix/aliases ===
+
To enable STARTTLS over SMTP (port 587), uncomment the following lines in {{ic|master.cf}}:
  
We need to map some aliases to real accounts. The default setup by arch looks pretty good here.
+
{{hc|/etc/postfix/master.cf|2=
 +
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 {{ic|smtpd_*_restrictions}} options remain commented because {{ic|$mua_*_restrictions}} are not defined in main.cf by default. If you do decide to set any of {{ic|$mua_*_restrictions}}, uncomment those lines too.
  
Uncomment the following line, and change it to a real account. I put the user account on the box that I use. Best not to just send mail to root, because you do not want to be logging in as root or checking email as root. Not good. Sudo is your friend, and so is forwarding root mail. Since this is for local delivery only (syslogs and stuff), it is still within the realm of mydestination.
 
  
root: USER
+
To enable SMTPS (port 465), uncomment the following lines in {{ic|master.cf}}:
  
Once you have finished editing {{ic|/etc/postfix/aliases}} you must run the postalias command:
+
{{hc|/etc/postfix/master.cf|
 +
'''smtps'''<nowiki>    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
 +
</nowiki>}}
  
postalias /etc/postfix/aliases
+
And in the first line, replace {{ic|'''smtps'''}} with {{ic|submissions}}. (this is the official service name according to [https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt IANA]; Postfix still references the old name)
  
=== Step 5: /etc/postfix/virtual_alias ===
+
The rationale surrounding the {{ic|$smtpd_*_restrictions}} lines is the same as above.
  
Create {{ic|/etc/postfix/virtual_alias}} with the following contents:
+
{{Note|If you get an error message like {{ic|postfix/master[5309]: fatal: 0.0.0.0:smtps: Servname not supported for ai_socktype}}, make sure that you have the following line in {{ic|postfix/master.cf}}:
 +
submissions inet n      -      n      -      -      smtpd
 +
Also make sure that {{ic|/etc/services}} is up to date and includes the following line:
 +
submissions 465/tcp
 +
}}
  
{{bc|
+
== Tips and tricks ==
MAILER-DAEMON:  postmaster
 
postmaster:    root
 
  
# General redirections for pseudo accounts
+
=== Blacklist incoming emails ===
bin:            root
 
daemon:        root
 
named:          root
 
nobody:        root
 
uucp:          root
 
www:            root
 
ftp-bugs:      root
 
postfix:        root
 
  
# Put your local aliases here.
+
Manually blacklisting incoming emails by sender address can easily be done with Postfix.  
  
# Well-known aliases
+
Create and open {{ic|/etc/postfix/blacklist_incoming}} file and append sender email address:
manager:       root
+
dumper:        root
+
user@example.com REJECT
operator:      root
 
abuse:          postmaster
 
  
# trap decode to catch security attacks
+
Then use the {{ic|postmap}} command to create a database:
decode:         root
 
  
# Person who should get root's mail. Don't receive mail as root!
+
# postmap hash:blacklist_incoming
root:           cactus@virtualdomain.tld
 
}}
 
  
Then run the postalias command on it:
+
Add the following code before the first permit rule in {{ic|main.cf}}:
  postalias /etc/postfix/virtual_alias
+
   
 +
smtpd_recipient_restrictions = check_sender_access hash:/etc/postfix/blacklist_incoming
  
Alternatively you can create the file .forward in /root.  specify the user to whom root mail should be forwarded, e.g. ''user@localhost''.
+
Finally [[restart]] {{ic|postfix.service}}.
  
{{hc|/root/.forward|
+
===Hide the sender's IP and user agent in the Received header===
user@localhost
+
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: [http://askubuntu.com/questions/78163/when-sending-email-with-postfix-how-can-i-hide-the-senders-ip-and-username-in AskUbuntu])
 +
What we want to do is remove the Received header from outgoing emails. This can be done by the following steps:
  
=== Step 6. mysql_virtual_domains.cf ===
+
Add the following line to {{ic|main.cf}}:
  
Create the {{ic|/etc/postfix/mysql_virtual_domains.cf}} file with the following (or similar) contents:
+
smtp_header_checks = regexp:/etc/postfix/smtp_header_checks
  
user = postfixuser
+
Create {{ic|/etc/postfix/smtp_header_checks}} with this content:
password = XXXXXXXXXX
 
hosts = localhost
 
dbname = postfix
 
table = domains
 
select_field = 'virtual'
 
where_field = domain
 
  
=== Step 7: mysql_virtual_mailboxes.cf ===
+
/^Received: .*/    IGNORE
 +
/^User-Agent: .*/  IGNORE
  
Create the /etc/postfix/mysql_virtual_mailboxes.cf file with the following (or similar) contents:
+
Finally, [[restart]] {{ic|postfix.service}}.
  
user = postfixuser
+
=== Postfix in a chroot jail ===
password = XXXXXXXXXX
+
Postfix is not put in a chroot jail by default. The Postfix documentation [http://www.postfix.org/BASIC_CONFIGURATION_README.html#chroot_setup] 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.
hosts = localhost
 
dbname = postfix
 
table = users
 
select_field = concat(domain,'/',email,'/')
 
where_field = email
 
  
Instead of having a directory structure something like ''/home/vmail/example.com/user@example.com'' you can have cleaner subdirectories (without the additional domain name) by replacing ''select_field'' and ''where_field'' with:
+
First, go into the {{ic|master.cf}} file in the directory {{ic|/etc/postfix}} and change all the chroot entries to 'yes' (y) except for the services {{ic|qmgr}}, {{ic|proxymap}}, {{ic|proxywrite}}, {{ic|local}}, and {{ic|virtual}}
  
query = SELECT CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/') FROM users WHERE email='%s'
+
Second, create two functions that will help us later with copying files over into the chroot jail (see last step)
 +
CP="cp -p"
  
=== Step 8: mysql_virtual_forwards.cf ===
+
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
 +
}
  
Create the {{ic|/etc/postfix/mysql_virtual_forwards.cf}} file with the following (or similar) contents:
+
Next, make the new directories for the jail:
 +
set -e
 +
umask 022
  
  user = postfixuser
+
  POSTFIX_DIR=${POSTFIX_DIR-/var/spool/postfix}
password = XXXXXXXXXX
+
  cd ${POSTFIX_DIR}
hosts = localhost
 
dbname = postfix
 
  table = forwardings
 
select_field = destination
 
where_field = source
 
  
=== Step 9: Postfix check ===
+
mkdir -p etc lib usr/lib/zoneinfo
 +
test -d /lib64 && mkdir -p lib64
  
Run the {{ic|postfix check}} command. It should output anything that you might have done wrong in a config file.
+
Find the localtime file
 +
lt=/etc/localtime
 +
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
  
To see all of your configs, type {{ic|postconf}}. To see how you differ from the defaults, try {{ic|postconf -n}}.
+
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
  
=== Step 10: enable and start the service ===
+
Copy required libraries into the chroot using the previously created function {{ic|cond_copy}}
 +
cond_copy '/usr/lib/libnss_*.so*' lib
 +
cond_copy '/usr/lib/libresolv.so*' lib
 +
cond_copy '/usr/lib/libdb.so*' lib
  
Enabling the [[systemd]] service '''postfix''' will automatically start Postfix at boot, but needs to be started manually for the first time.
+
And don't forget to reload Postfix.
  
=== Step 11: newuser ===
 
  
We need to create the user for storing the virtual mail. Create a vmailuser as follows:
+
=== DANE (DNSSEC) ===
 +
==== Resource Record ====
  
# groupadd -g 5003 vmail
+
{{warning|This is not a trivial section. Be aware that you make sure you know what you are doing. You better read [https://dane.sys4.de/common_mistakes Common Mistakes] before.}}
# useradd -g vmail -u 5003 -d /home/vmailer -s /bin/false vmailer
 
# mkdir /home/vmailer
 
# chown vmailer.vmail /home/vmailer
 
# chmod -R 750 /home/vmailer
 
# passwd vmailer
 
  
5003 UID/GID are the ones specified in the Postfix main.cf file.
+
[[DANE]] supports several types of records, however not all of them are suitable in Postfix.
  
== MySQL configuration ==
+
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 [[DANE#Resource Record|Resource Records]].
  
=== Step 1: create a MySQL database ===
+
==== Configuration ====
  
Create MySQL database called 'postfix', or something similar.
+
{{Expansion|What does ''tempfail'' mean?}}
  
CREATE DATABASE postfix;
+
Opportunistic DANE is configured this way:
  USE postfix;
+
{{hc|/etc/postfix/main.cf|<nowiki>
 +
smtpd_use_tls = yes
 +
smtp_dns_support_level = dnssec
 +
smtp_tls_security_level = dane
 +
</nowiki>}}
 +
{{hc|/etc/postfix/master.cf|<nowiki>
 +
dane      unix -      -      n      -      -      smtp
 +
  -o smtp_dns_support_level=dnssec
 +
  -o smtp_tls_security_level=dane
 +
</nowiki>}}
  
=== Step 2: setup table structure ===
+
To use per-domain policies, e.g. opportunistic DANE for example.org and mandatory DANE for example.com,
 +
use something like this:
 +
{{hc|/etc/postfix/main.cf|<nowiki>
 +
indexed = ${default_database_type}:${config_directory}/
  
Import the following table structure.
+
# Per-destination TLS policy
{{bc|
+
#
CREATE TABLE `domains` (
+
smtp_tls_policy_maps = ${indexed}tls_policy
  `domain` varchar(50) NOT NULL default "",
 
  PRIMARY KEY  (`domain`),
 
  UNIQUE KEY `domain` (`domain`)
 
);
 
  
 +
# default_transport = smtp, but some destinations are special:
 +
#
 +
transport_maps = ${indexed}transport
 +
</nowiki>}}
  
CREATE TABLE `forwardings` (
+
{{hc|transport|
  `source` varchar(80) NOT NULL default "",
+
example.com dane
  `destination` text NOT NULL,
+
example.org dane
  PRIMARY KEY  (`source`)
+
}}
);
 
  
CREATE TABLE `users` (
+
{{hc|tls_policy|
  `email` varchar(80) NOT NULL default "",
+
example.com dane-only
  `password` varchar(20) NOT NULL default "",
 
  `quota` varchar(20) NOT NULL default '20971520',
 
  `domain` varchar(255) NOT NULL default "",
 
  UNIQUE KEY `email` (`email`)
 
);
 
 
}}
 
}}
  
=== Step 3: create a MySQL user ===
+
{{Note|For global mandatory DANE, change {{ic|smtp_tls_security_level}} to {{ic|dane-only}}. Be aware that this makes Postfix tempfail (respond with a {{ic|4.X.X}} error code) on all deliveries that do not use DANE at all!}}
  
Add a user for Postfix to use. Something like "postfixuser".
+
Full documentation is found [http://www.postfix.org/TLS_README.html#client_tls_dane here].
Give permissions for Postfix user to the table. This user should be listed in the {{ic|/etc/postfix/mysql_virtual_domains.cf}} file.
 
  
The [http://dev.mysql.com/doc/refman/5.5/en/server-administration.html official reference manual] has a detailed guide on user management and server administration in general.
+
== Extras ==
  
The following is just an example for creation of 'postfixuser' with password 'XXXXXXXXXX'.
+
* {{App|[[PostfixAdmin]]|A web-based administrative interface for Postfix.|http://postfixadmin.sourceforge.net/|{{Pkg|postfixadmin}}}}
Note that the GRANT statements need to be executed after creating the tables in the next step.
 
  
CREATE USER 'postfixuser' IDENTIFIED BY 'XXXXXXXXXX';
+
=== Postgrey ===
GRANT SELECT, INSERT, UPDATE, DELETE ON domains TO postfixuser;
 
GRANT SELECT, INSERT, UPDATE, DELETE ON forwardings TO postfixuser;
 
GRANT SELECT, INSERT, UPDATE, DELETE ON users TO postfixuser;
 
  
=== Step 4: add a domain ===
+
{{Style|See [[Help:Style]]}}
  
INSERT INTO `domains` VALUES ('virtualdomain.tld');
+
[http://postgrey.schweikert.ch/ Postgrey] can be used to enable [[Wikipedia:Greylisting|greylisting]] for a Postfix mail server.
  
=== Step 5: add a user ===
+
==== Installation ====
  
INSERT INTO `users` VALUES ('cactus@virtualdomain.tld', 'secret',
+
[[Install]] the {{Pkg|postgrey}} package. To get it running quickly edit the Postfix configuration file and add these lines:
'20971520', 'virtualdomain.tld');
+
{{hc|/etc/postfix/main.cf|<nowiki>
 
+
smtpd_recipient_restrictions =
The above creates the user and sets a password as secret.  
+
  check_policy_service inet:127.0.0.1:10030
 +
</nowiki>}}
  
This will allow you to use encrypted passwords
+
Then [[start/enable]] the {{ic|postgrey}} service. Afterwards, reload the {{ic|postfix}} service. Now greylisting should be enabled.
  
INSERT INTO `users` VALUES ('cactus@virtualdomain.tld', ENCRYPT('secret'),
+
==== Configuration ====
'20971520', 'virtualdomain.tld');
 
  
== Test Postfix ==
+
Configuration is done via editing the {{ic|postgrey.service}} file. First copy it over to edit it.
  
Start Postfix service. Now lets see if Postfix is going to deliver mail for our test user.
+
# cp /usr/lib/systemd/system/postgrey.service /etc/systemd/system/
{{bc|
 
telnet servername 25
 
ehlo testmail.org
 
mail from:<test@testmail.org>
 
rcpt to:<cactus@virtualdomain.tld>
 
data
 
This is a test email.
 
  
.
+
==== Whitelisting ====
quit
+
To add automatic whitelisting (successful deliveries are whitelisted and don't have to wait any more), you could add the {{ic|<nowiki>--auto-whitelist-clients=N</nowiki>}} option and replace {{ic|N}} by a suitably small number (or leave it at its default of 5).
}}
 
  
=== Error response ===
+
...actually, the preferred method should be the override:
  
  451 4.3.0 <lisi@test.com>:Temporary lookup failure
+
  cat /etc/systemd/system/postgrey.service.d/override.conf
Maybe you have entered the wrong user/password for MySQL or the MySQL socket is not in the right place.
 
  
=== See that you have received a email ===
+
[Service]
 +
ExecStart=
 +
ExecStart=/usr/bin/postgrey --inet=127.0.0.1:10030 \
 +
        --pidfile=/run/postgrey/postgrey.pid \
 +
        --group=postgrey --user=postgrey \
 +
        --daemonize \
 +
        --greylist-text="Greylisted for %%s seconds" \
 +
        --auto-whitelist-clients
  
Now type {{ic|$ find /home/vmailer}}.
+
To add your own list of whitelisted clients in addition to the default ones, create the file {{ic|/etc/postfix/whitelist_clients.local}} and enter one host or domain per line, then restart {{ic|postgrey.service}} so the changes take effect.
  
You should see something like the following:
+
==== Troubleshooting ====
{{bc|
 
/home/vmailer/virtualdomain.tld/cactus@virtualdomain.tld
 
/home/vmailer/virtualdomain.tld/cactus@virtualdomain.tld/tmp
 
/home/vmailer/virtualdomain.tld/cactus@virtualdomain.tld/cur
 
/home/vmailer/virtualdomain.tld/cactus@virtualdomain.tld/new
 
/home/vmailer/virtualdomain.tld/cactus@virtualdomain.tld/new/1102974226.2704_0.bonk.testmail.org
 
}}
 
The key is the last entry. This is an actual email, if you see that, it is working.
 
  
== Configure Courier IMAP ==
+
If you specify {{ic|1=--unix=/path/to/socket}} and the socket file is not created ensure you have removed the default {{ic|1=--inet=127.0.0.1:10030}} from the service file.
  
=== Step 1: /etc/courier-imap/imapd ===
+
For a full documentation of possible options see {{ic|perldoc postgrey}}.
  
ADDRESS=127.0.0.1
+
=== SpamAssassin ===
  
We set the listen address to LOCAL ONLY. No outside connections.
+
This section describes how to integrate [[SpamAssassin]].
  
=== Step 2: /etc/authlib/authdaemonrc ===
+
==== SpamAssassin stand-alone generic setup ====
  
Remove all the modules from the authmodulelist line except for authmysql like so:
+
{{Note|If you want to combine SpamAssassin and Dovecot Mail Filtering, ignore the next two lines and continue further down instead.}}
  
  authmodulelist="authmysql"
+
Edit {{ic|/etc/postfix/master.cf}} and add the content filter under smtp.
 +
{{bc|1=
 +
smtp      inet n      -      n      -      -      smtpd
 +
  -o content_filter=spamassassin
 +
}}
  
=== Step 3: /etc/authlib/authmysqlrc ===
+
Also add the following service entry for SpamAssassin
 
+
{{bc|1=
Replace the ''entire'' file with the following:
+
spamassassin unix -     n      n      -      -      pipe
{{bc|
+
  flags=R user=spamd argv=/usr/bin/vendor_perl/spamc -e /usr/bin/sendmail -oi -f ${sender} ${recipient}
MYSQL_SERVER            localhost
 
MYSQL_USERNAME          postfixuser
 
MYSQL_PASSWORD          secret
 
MYSQL_SOCKET            /run/mysqld/mysqld.sock
 
MYSQL_DATABASE          postfix
 
# MYSQL_NAME_FIELD      name
 
MYSQL_USER_TABLE        users
 
MYSQL_CLEAR_PWFIELD     password
 
MYSQL_UID_FIELD        '5003'
 
##note, this is the uid that we set in /etc/postfix/main.cf
 
MYSQL_GID_FIELD        '5003'
 
##note, this is the gid that we set in /etc/postfix/main.cf
 
MYSQL_LOGIN_FIELD      email
 
MYSQL_HOME_FIELD        "/home/vmailer"
 
MYSQL_MAILDIR_FIELD    concat(domain,'/',email,'/')
 
MYSQL_QUOTA_FIELD      quota
 
 
}}
 
}}
Where secret is the MySQL password for the user postfixuser.
 
If you are using encrypted passwords by using MySQL's encrypt function. Use "MYSQL_CRYPT_PWFIELD columnname" instead of "MYSQL_CLEAR_PWFIELD columnname".
 
 
For an alternative directory structure, you could also use this setting for MAILDIR_FIELD:
 
  
MYSQL_MAILDIR_FIELD    CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/')
+
Now you can [[start]] and [[enable]] {{ic|spamassassin.service}}.
  
In this case, ''courier'' will use a directory like {{ic|/home/vmail/exampledomain.com/exampleuser}}.
+
==== SpamAssassin combined with Dovecot LDA / Sieve (Mailfiltering) ====
 +
Set up LDA and the Sieve-Plugin as described in [[Dovecot#Sieve]]. But ignore the last line {{ic|mailbox_command... }}.
  
=== Step 4: autorun imapd on system start ===
+
Instead add a pipe in {{ic|/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}
  
If you already using [[systemd]], enable '''authdaemond''' and '''courier-imapd.services'''.
+
And activate it in {{ic|/etc/postfix/main.cf}}:
If authdaemond fails to start, make sure the folder {{ic|/run/authdaemon}} exists.
+
  virtual_transport = dovecot
  
=== Step 5: Fam and rpcbind ===
+
==== SpamAssassin combined with Dovecot LMTP / Sieve ====
 +
Set up the LMTP and Sieve as described in [[Dovecot#Sieve]].
  
{{Accuracy|FAM should not be required anymore.|section=FAM is obsolete}}
+
Edit {{ic|/etc/dovecot/conf.d/90-plugins.conf}} and add:
Courier-imap for arch comes compiled with FAM. This means portmap is also required. What used to be portmap is nowadays called rpcbind.
 
  
Install {{Pkg|rpcbind}} and edit {{ic|/etc/fam/fam.conf}}
+
  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
  
local_only = true
+
Create the directory and put spamassassin in as a binary that can be ran by dovecot:
idle_timeout = 0
 
  
Make sure the two above values are set. Then start and enable the daemon '''rpcbind'''.
+
  # mkdir /etc/dovecot/sieve-filter
 +
  # ln -s /usr/bin/vendor_perl/spamc /etc/dovecot/sieve-filter/spamc
  
=== Step 6: start courier imap ===
+
Create a new file, {{ic|/etc/dovecot/sieve.before.d/spamassassin.sieve}} which contains:
  
Start the ''imapd'' daemon.
+
  require [ "vnd.dovecot.filter" ];
 +
  filter "spamc" [ "-d", "127.0.0.1", "--no-safe-fallback" ];
  
=== Step 7: Test courier ===
+
Compile the sieve rules {{ic|spamassassin.svbin}}:
  
Lets see if courier is working:
+
  # cd /etc/dovecot/sieve.before.d
{{bc|<nowiki>
+
  # sievec spamassassin.sieve
telnet localhost imap
 
Trying 127.0.0.1...
 
Connected to localhost.localdomain.
 
Escape character is '^]'.
 
* OK [[CAPABILITY IMAP4rev1 ... ]] Courier-IMAP ready.
 
  
A LOGIN "cactus@virtualdomain.tld" "password"
+
Finally, [[restart]] {{ic|dovecot.service}}.
A OK LOGIN Ok.
 
  
B SELECT "Inbox"
+
===Rule-based mail processing===
* FLAGS (\Draft \Answered ... \Recent)
+
With policy services one can easily finetune Postfix' behaviour of mail delivery.
* OK [[PERMANENTFLAGS (\Draft \Answered ... \Seen)]] Limited
+
{{Pkg|postfwd}} and <span class="plainlinks archwiki-template-pkg">[https://aur.archlinux.org/pkgbase/policyd policyd]</span><sup><small>AUR</small></sup> provide services to do so.
* 8 EXISTS
+
This allows you to e.g. implement time-aware grey- and blacklisting of senders and receivers as well as [[SPF]] policy checking.
* 5 RECENT
 
* OK [[UIDVALIDITY 1026858715]] Ok
 
B OK [[READ-WRITE]] Ok
 
  
Z LOGOUT
+
Policy services are standalone services and connected to Postfix like this:
* BYE Courier-IMAP server shutting down
+
{{hc|/etc/postfix/main.cf|<nowiki>
Z OK LOGOUT completed
+
smtpd_recipient_restrictions =
Connection closed by foreign host.
+
  ...
 +
  check_policy_service unix:/run/policyd.sock
 +
  check_policy_service inet:127.0.0.1:10040
 
</nowiki>}}
 
</nowiki>}}
 +
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.
  
== Configure Squirrelmail==
+
=== Sender Policy Framework ===
  
=== Step 1: Create secure http site (https) ===
+
To use the [[Sender Policy Framework]] with Postfix, [[install]] {{AUR|python-postfix-policyd-spf}}.
  
We are going to create a secure http site. This is so that people can login with plain text passwords, and not have to worry about the passwords getting sniffed (or worry less).
+
Edit {{ic|/etc/python-policyd-spf/policyd-spf.conf}} to your needs. An extensively commented version can be found at {{ic|/etc/python-policyd-spf/policyd-spf.conf.commented}}.
 +
Pay some extra attention to the HELO check policy, as standard settings strictly reject HELO failures.
  
==== Step 1.1: Edit /etc/httpd/conf/extra/httpd-ssl.conf ====
+
In the main.cf add a timeout for the policyd:
  
Add appropriate information. Here is an example section:
+
{{hc|/etc/postfix/main.cf|2=
{{bc|
+
policy-spf_time_limit = 3600s
<VirtualHost _default_:443>
 
#  General setup for the virtual host
 
DocumentRoot "/home/httpd/site.virtual/virtualdomain.tld/html"
 
ServerName virtualdomain.tld:443
 
ServerAdmin noemailonthisbox@localhost
 
<Directory "/home/httpd/site.virtual/virtualdomain.tld/html">
 
    Options -Indexes +FollowSymLinks
 
    AllowOverride Options Indexes AuthConfig
 
    Order allow,deny
 
    Allow from all
 
</Directory>
 
 
}}
 
}}
  
==== Step 1.15 Include httpd-ssl.conf in httpd.conf ====
+
Then add a transport
  
Simply uncomment this line in your httpd.conf:
+
{{hc|/etc/postfix/master.cf|2=
 +
policy-spf  unix  -      n      n      -      0      spawn
 +
    user=nobody argv=/usr/bin/policyd-spf
 +
}}
  
#Include conf/extra/httpd-ssl.conf
+
Lastly you need to add the policyd to the {{ic|smtpd_recipient_restrictions}}. To minimize load put it to the end of the restrictions but above any {{ic|reject_rbl_client}} DNSBL line:
  
==== Step 1.2: Create the directory structure ====
+
{{hc|/etc/postfix/main.cf|2=
 +
smtpd_recipient_restrictions=
 +
    ...
 +
    permit_sasl_authenticated
 +
    permit_mynetworks
 +
    reject_unauth_destination
 +
    check_policy_service unix:private/policy-spf
 +
}}
  
Now, create the directory you specified in the ssl.conf file.
+
You can test your Setup with the following:
  
$ mkdir -p /home/httpd/site.virtual/virtualdomain.tld/html
+
{{hc|/etc/python-policyd-spf/policyd-spf.conf|2=
 +
defaultSeedOnly = 0
 +
}}
  
==== Step 1.3: Generate a certificate ====
+
=== Sender Rewriting Scheme ===
  
Follow the instructions here: [[LAMP#SSL]]
+
To use the [[Sender Rewriting Scheme]] with Postfix, [[install]] {{AUR|postsrsd}} and adjust the settings:
  
==== Step 1.4: restart Apache and test ====
+
{{hc|/etc/postsrsd/postsrsd|2=
 +
SRS_DOMAIN=yourdomain.tld
 +
SRS_EXCLUDE_DOMAINS=yourotherdomain.tld,yet.anotherdomain.tld
 +
SRS_SEPARATOR==
 +
SRS_SECRET=/etc/postsrsd/postsrsd.secret
 +
SRS_FORWARD_PORT=10001
 +
SRS_REVERSE_PORT=10002
 +
RUN_AS=postsrsd
 +
CHROOT=/usr/lib/postsrsd
 +
}}
  
Make sure that https is now working, and that you can get to the secure site.
+
Enable and start the daemon, making sure it runs after reboot as well.
 +
Then configure Postfix accordingly by tweaking the following lines:
  
=== Step 2: put Squirrelmail in the directory you created===
+
{{hc|/etc/postfix/main.cf|2=
 +
sender_canonical_maps = tcp:localhost:10001
 +
sender_canonical_classes = envelope_sender
 +
recipient_canonical_maps = tcp:localhost:10002
 +
recipient_canonical_classes= envelope_recipient,header_recipient
 +
}}
  
Either extract squirrelmail, or move it from where the arch package puts it, into the directory you created for the secure http site.
+
Restart Postfix and start forwarding mail.
  
=== Step 3: run Squirrelmail config utility ===
+
== Troubleshooting ==
  
cd ''squirrelmaildir''/config
+
=== Warning: "database /etc/postfix/*.db is older than source file .." ===
perl conf.pl
 
  
Make sure you select 'D', then type in courier and hit enter. Make sure your other options are correct as well.
+
If you get one or both warnings with {{ic|journalctl}}
Note: If you use php with safe mode on, make sure that the data dir is owned by the same owner as all the files in the squirrelmail directory. With safe mode off, simply follow the squirrelmail setup directions.
 
  
=== Step 4: test the Squirrelmail setup ===
+
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
Point your browser to squirrelmail/src/configtest.php. Should you get an error on directory location, make sure php.ini has been set to allow access to them (open_basedir directive).
 
 
 
=== Step 5: test Squirrelmail ===
 
 
 
Log in with the test account. You will need to login with the form of:
 
username: cactus@virtualdomain.tld
 
password: secret
 
 
 
Try sending email to non-existent local accounts. You should get an immediate bounce back.
 
Try sending email to external good email accounts, as well as non-existent ones.
 
Just general testing stuff.
 
If everything works fine, then you can add other accounts to the MySQL database, and away you go!
 
 
 
==== Troubleshooting ====
 
 
 
If you received an error similar to:
 
{{bc|1=Warning: file_exists() [function.file-exists]: open_basedir restriction in effect. File(/var/lib/squirrelmail/data) is not within the allowed path(s): \
 
(/srv/http/:/home/:/tmp/:/usr/share/pear/) in /home/httpd/site.virtual/virtualdomain.tld/html/squirrelmail/src/configtest.php on line 303
 
}}
 
Then edit {{ic|/etc/httpd/httpd.conf}}, and in the section:
 
  <Directory "/home/httpd/site.virtual/virtualdomain.tld/html">
 
add:
 
php_admin_value open_basedir /home/httpd/site.virtual/virtualdomain.tld/html:/var/lib/squirrelmail/
 
  
If you get an error similar to:
+
then you can fix it by using these commands depending on the messages you get
Unknown user or password incorrect.
 
You may have to create your user directories within vmailer like so:
 
  
  $ mkdir -p /home/vmailer/''mydomain.com''/username''
+
  postmap /etc/postfix/transport
  $ mkdir /home/vmailer/''mydomain.com''/username''/cur
+
  postmap /etc/postfix/virtual
$ mkdir /home/vmailer/''mydomain.com''/username''/new
 
$ mkdir /home/vmailer/''mydomain.com''/username''/tmp
 
$ chmod -R 750 /home/vmailer
 
$ chown -R vmailer.vmail /home/vmailer
 
  
where ''mydomain.com''/''username'' is the ''domain''/''username'' given within MySQL.
+
and restart {{ic|postfix.service}}
  
== See also==
+
== See also ==
  
*[http://linox.be/index.php/2005/07/13/44/ Out of Office] for Squirrelmail
+
* [http://www.postfix.org/documentation.html Official documentation]
*[https://help.ubuntu.com/community/Postfix Postfix Ubuntu documentation]
+
* [https://help.ubuntu.com/community/Postfix Postfix Ubuntu documentation]
*[http://www.gelens.org/archlinux-mailserver/ A simple mailserver on Arch Linux]
+
* [http://linox.be/index.php/2005/07/13/44/ Out of Office] for Squirrelmail {{Dead link|2017|08|23}}
*[http://sherlock.heroku.com/blog/2012/02/03/setting-up-postfix-to-use-gmail-as-an-smtp-relay-host-in-archlinux/ Use Gmail as an SMTP relay]
 

Latest revision as of 16:49, 5 December 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.

Installation

Install the postfix package.

Configuration

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.

Aliases

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:

newaliases
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.
/root/.forward
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.

TLS

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:

/etc/postfix/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)

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.

By default, Postfix will not accept secure mail.

You need to obtain a certificate. Point Postfix to your TLS certificates by adding the following lines to main.cf:

/etc/postfix/main.cf
smtpd_tls_security_level = may
smtpd_tls_cert_file = /path/to/cert.pem
smtpd_tls_key_file = /path/to/key.pem

There are two ways to accept secure mail. STARTTLS over SMTP (port 587) and SMTPS (port 465). The latter was previously deprecated but was reinstated by RFC:8314.

To enable STARTTLS over SMTP (port 587), uncomment the following lines in master.cf:

/etc/postfix/master.cf
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.


To enable SMTPS (port 465), uncomment the following lines in master.cf:

/etc/postfix/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

And in the first line, replace smtps with submissions. (this is the official service name according to IANA; Postfix still references the old name)

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

Note: If you get an error message like postfix/master[5309]: fatal: 0.0.0.0:smtps: Servname not supported for ai_socktype, make sure that you have the following line in postfix/master.cf:
submissions inet n       -       n       -       -       smtpd

Also make sure that /etc/services is up to date and includes the following line:

submissions 465/tcp

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
POSTFIX_DIR=${POSTFIX_DIR-/var/spool/postfix}
cd ${POSTFIX_DIR}
mkdir -p etc lib usr/lib/zoneinfo
test -d /lib64 && mkdir -p lib64

Find the localtime file

lt=/etc/localtime
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.


DANE (DNSSEC)

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.

Configuration

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:

/etc/postfix/main.cf
smtpd_use_tls = yes
smtp_dns_support_level = dnssec
smtp_tls_security_level = dane
/etc/postfix/master.cf
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:

/etc/postfix/main.cf
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
transport
example.com dane
example.org dane
tls_policy
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.

Extras

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

Postgrey

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.

Installation

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

/etc/postfix/main.cf
smtpd_recipient_restrictions =
  check_policy_service inet:127.0.0.1:10030

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

Configuration

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/

Whitelisting

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
[Service]
ExecStart=
ExecStart=/usr/bin/postgrey --inet=127.0.0.1:10030 \
       --pidfile=/run/postgrey/postgrey.pid \
       --group=postgrey --user=postgrey \
       --daemonize \
       --greylist-text="Greylisted for %%s seconds" \
       --auto-whitelist-clients

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.

Troubleshooting

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

For a full documentation of possible options see perldoc postgrey.

SpamAssassin

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", "127.0.0.1", "--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:

/etc/postfix/main.cf
smtpd_recipient_restrictions =
  ...
  check_policy_service unix:/run/policyd.sock
  check_policy_service inet:127.0.0.1:10040

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:

/etc/postfix/main.cf
policy-spf_time_limit = 3600s

Then add a transport

/etc/postfix/master.cf
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:

/etc/postfix/main.cf
smtpd_recipient_restrictions=
     ...
     permit_sasl_authenticated
     permit_mynetworks
     reject_unauth_destination
     check_policy_service unix:private/policy-spf

You can test your Setup with the following:

/etc/python-policyd-spf/policyd-spf.conf
defaultSeedOnly = 0

Sender Rewriting Scheme

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

/etc/postsrsd/postsrsd
SRS_DOMAIN=yourdomain.tld
SRS_EXCLUDE_DOMAINS=yourotherdomain.tld,yet.anotherdomain.tld
SRS_SEPARATOR==
SRS_SECRET=/etc/postsrsd/postsrsd.secret
SRS_FORWARD_PORT=10001
SRS_REVERSE_PORT=10002
RUN_AS=postsrsd
CHROOT=/usr/lib/postsrsd

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

/etc/postfix/main.cf
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.

Troubleshooting

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