# Postfix

Related articles

- PostFix Howto With SASL
- Virtual user mail system
- Courier MTA

From Postfix's site:

  "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 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 and openssl packages from the official repositories.

### DNS records

An MX record should point to the mail host. Usually this is done from configuration interface of your domain provider.

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.

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.

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. Wikipedia's List of DNS Record Types.

## Configuration

### master.cf

`/etc/postfix/master.cf` is the master configuration file where you can specify what kinds of protocols you will serve. It is also the place where you can put your new pipes e.g. to check for Spam!

It is recommended to enable secure SMTP as described in #Secure SMTP.

### main.cf

`/etc/postfix/main.cf` is the main configuration file where everything is configured. The settings below are recommended for virtual local-only delivery.

- `myhostname` should be set if your mail server has multiple domains, and you do not want the primary domain to be the mail host. You should have both a DNS A record and an MX record point to this hostname.

      myhostname = mail.nospam.net

- `mydomain` is usually the value of `myhostname`, minus the first part. If your domain is wonky, then just set it manually.

      mydomain = nospam.net

- `myorigin` 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

- `mydestination` 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

- `mynetworks` and `mynetwork_style` control relaying, and whom is allowed to. We do not want any relaying.

  For our sakes, we will simply set `mynetwork_style` to host, as we are trying to make a standalone Postfix host, that people will use webmail on. No relaying, no other MTA's. Just webmail.

      mynetworks_style = host

- `relaydomains` controls the destinations that Postfix will relay TO. The default value is $mydestination. This should be fine for now.

      relay_domains = $mydestination

- `home_mailbox` or `mail_spool_directory` control how mail is delivered/stored for the users.

  If set, `mail_spool_directory` specifies an absolute path where mail gets delivered. Alternatively, if set, `home_mailbox` specifies a mailbox relative to the user's home directory where mail gets delivered.

  Courier-IMAP requires "Maildir" format, so you must set it like the following:

      home_mailbox = Maildir/

#### Default message and mailbox size limits

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 `/var/spool/mail` and use postconf to check these size limits:

    # postconf -d mailbox_size_limit
    mailbox_size_limit = 51200000
    # postconf -d message_size_limit
    message_size_limit = 10240000

### aliases

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

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`), you only need to change the following lines in `/etc/postfix/main.cf`. Uncomment them and modify them to the specifics listed below. Everything else can be left as installed.

    inet_interfaces = loopback-only
    mynetworks_style = host
    append_dot_mydomain = no
    default_transport = error: Local delivery only!

## Virtual mail

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

See Virtual user mail system for a comprehensive guide how to set it up.

## Postfix check

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 and test Postfix

Start/enable `postfix.service` using systemd.

Now lets see if Postfix is going to deliver mail for our test user.

    telnet servername 25
    ehlo testmail.org
    mail from:<test@testmail.org>
    rcpt to:<cactus@virtualdomain.tld>
    data
    This is a test email.

    .
    quit

### Error response

    451 4.3.0 <lisi@test.com>:Temporary lookup failure

Maybe you have entered the wrong user/password for MySQL or the MySQL socket is not in the right place.

    550 5.1.1 <email@spam.me>: Recipient address rejected: User unknown in virtual mailbox table.

Double check content of mysql_virtual_mailboxes.cf and check the main.cf for mydestination

### See that you have received a email

Now type `$ find /home/vmailer`.

You should see something like the following:

    /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.

## Extra

### PostfixAdmin

To use PostfixAdmin, you need a working Apache/MySQL/PHP setup as described in LAMP.

You can install postfixadmin from the official repositories.

Edit the PostfixAdmin configuration file:

    /etc/webapps/postfixadmin/config.inc.php

    $CONF['configured'] = true;
    // correspond to dovecot maildir path /home/vmail/%d/%u
    $CONF['domain_path'] = 'YES';
    $CONF['domain_in_mailbox'] = 'YES';
    $CONF['database_type'] = 'mysql';
    $CONF['database_host'] = 'localhost';
    $CONF['database_user'] = 'postfix_user';
    $CONF['database_password'] = 'hunter2';
    $CONF['database_name'] = 'postfix_db';

Create the Apache configuration file:

    /etc/httpd/conf/extra/httpd-postfixadmin.conf

    Alias /postfixadmin "/usr/share/webapps/postfixAdmin"
    <Directory "/usr/share/webapps/postfixAdmin">
        DirectoryIndex index.html index.php
        AllowOverride All
        Options FollowSymlinks
        Require all granted
    </Directory>

And include it in `/etc/httpd/conf/httpd.conf`:

    # PostfixAdmin configuration
    Include conf/extra/httpd-postfixadmin.conf

### Secure SMTP

To enable STARTTLS over SMTP (port 587, the proper way of securing SMTP), uncomment these lines in `/etc/postfix/master.cf`:

    smtp      inet  n       -       n       -       -       smtpd
    submission inet n       -       n       -       -       smtpd
      -o smtpd_tls_security_level=encrypt
      -o smtpd_sasl_auth_enable=yes

If you also need to support the deprecated SMTPS (port 465), see #SMTPS over port 465

#### SMTPS over port 465

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

To enable it uncomment the following lines in `/etc/postfix/master.cf`:

    smtps     inet  n       -       n       -       -       smtpd
      -o smtpd_tls_wrappermode=yes
      -o smtpd_sasl_auth_enable=yes

And verify that these lines are in `/etc/services`:

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

Otherwise Postfix will not start and you will get the following error:

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

### SpamAssassin

Go over `/etc/mail/spamassassin/local.cf` and configure it to your needs.

Create an user and group for SpamAssassin.

    # groupadd -g 5001 spamd
    # useradd -u 5001 -g spamd -s /sbin/nologin -d /var/lib/spamassassin -m spamd
    # chown spamd:spamd /var/lib/spamassassin

Make sure `/etc/conf.d/spamd` looks like the following:

    SAHOME="/var/lib/spamassassin/"
    SPAMD_OPTS="--create-prefs --max-children 5 --username spamd --helper-home-dir ${SAHOME} -s ${SAHOME}spamd.log --pidfile /var/run/spamd.pid"

To leave the service ready to run, let's update the SpamAssassin matching patterns.

    # /usr/bin/vendor_perl/sa-update

Note: If you want to combine Spamassassin and Dovecot Mail Filtering you have to 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
           user=spamd argv=/usr/bin/vendor_perl/spamc -f -e /usr/sbin/sendmail -oi -f ${sender} ${recipient}

Now you can start `spamassassin.service` using systemd.

##### 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 -f -u spamd -e /usr/lib/dovecot/dovecot-lda -f ${sender} -d ${recipient}

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

     virtual_transport = dovecot

### Hide the sender's IP and username 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 applying header_checks exclusively to the submission port. What we need to do is pass the cleanup_service_name option to the submission service so that we can set up a new cleanup service, “subcleanup.” The relevant section of /etc/postfix/master.cf might look like this:

    submission inet n       -       -       -       -       smtpd
     -o smtpd_tls_security_level=encrypt
     -o smtpd_sasl_auth_enable=yes
     -o smtpd_client_restrictions=permit_sasl_authenticated,reject
     -o milter_macro_daemon_name=ORIGINATING
     -o cleanup_service_name=subcleanup

Now we can pass the header_checks option to the new cleanup service. That part of /etc/postfix/master.cf might look like this:

    cleanup   unix  n       -       -       -       0       cleanup
    subcleanup unix n       -       -       -       0       cleanup
     -o header_checks=regexp:/etc/postfix/submission_header_checks

Finally, we need to create the file /etc/postfix/submission_header_checks, which will contain the regex that filters offending Received header lines:

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

## See also

- Out of Office for Squirrelmail
- Postfix Ubuntu documentation
- A simple mailserver on Arch Linux
- Use Gmail as an SMTP relay

Category:

- Mail Server