Transport

----------

Postfix Admin Transport Map and Relayhost Map For Email Delivery

Use Postfix Transport Map

The transport map defines mappings from recipient address to transport method. By default, the value of the transport_maps parameter in Postfix is not set, as can be checked with:

postconf transport_maps

Sample output:

transport_maps =

iRedMail and Modoboa uses MySQL/MariaDB database to store transport maps. If you used iRedMail to set up your mail server, then the output should be like:

transport_maps = proxy:mysql:/etc/postfix/sql/transport_maps_user.cf proxy:mysql:/etc/postfix/sql/transport_maps_domain.cf

The transport_maps parameter points to one or more transport lookup tables. You can edit the Postfix main configuration file.

vi /etc/postfix/main.cf

And set a value by adding the following line at the end of the file. The /etc/postfix/transport file will contain the lookup table.

transport_maps = hash:/etc/postfix/transport

If you use iRedMail, you can find the transport_maps parameter and set the value to

transport_maps =     hash:/etc/postfix/transport     proxy:mysql:/etc/postfix/sql/transport_maps_user.cf     proxy:mysql:/etc/postfix/sql/transport_maps_domain.cf

localhost                local:

localhost.worldcm.net    local:

mail.worldcm.net          local:

xyz.com                  smtp:[100.30.157.100]

example.com               smtp:[200.30.127.200]

Lookup table can be a file, or in the form of MySQL/MariaDB database tables. Lookup tables will be searched in the specified order until a match is found.

Save and close the Postfix main configuration file. Next, we need to create the lookup table file.

vi /etc/postfix/transport

In this file, we can define mappings from recipient addresses to transport method. For example, I found that many .pl (Poland) domains are using a particular blacklist that blocks my mail server’s IP address. I can add the following line in this file so that emails sent to .pl domains will be relayed through Mailjet.

.pl                relay:[mail.xyz.com]:587

Some people find that it’s hard to get into the inbox of Microsoft mailboxes (hotmail.com, outlook.com, etc). It’s very likely that you email will be put in spam folder. Well, you can try using Mailjet to deliver emails to Microsoft mailbox users. Mailjet even allows you to see if the recipient opened or clicked links in your email. So I put the following lines in the file.

hotmail.com        relay:[in-v3.mailjet.com]:587 abc.com            relay:[smtp.gmail.com]:587

live.com            smtp:[smtp.abc.cloud]:587

If you want to use relay host to deliver emails to a particular recipient, but send emails directly to all other recipients in the same domain, then you can add a line like below.

someone@gmail.com  relay:[in-v3.mailjet.com]:587

If a certain SMTP server doesn’t use the default SMTP port 25, but uses a different port such as 2525 to receive incoming emails, you can add the following line

example.com        smtp:[mail.example.com]:2525

It’s a good practice to add your own domain name in this file like below.

your-domain.com    local

This tells Postfix that emails sent to your own domain should be delivered locally. This is the default behavior for canonical domains. If your mail server has multiple virtual domains, you should add all of your virtual domains.

your-domain1.com         local your-domain2.com         local

If you just put the following two lines in the file and don’t add other lines, this will make all emails, excluding emails sent to your own domain, delivered via the relay host. The asterisk (*) is a wild-card character that represent any email address.

your-domain.com       local *                     relay:[in-v3.mailjet.com]:587

We can also have the following configuration, which means that emails sent to your own domain are delivered locally. Email sent to Gmail.com are delivered normally by performing MX lookup and all other emails are delivered via the relay host.

your-domain.com       local  gmail.com             smtp *                     relay:[in-v3.mailjet.com]:587

Save and close the file. Then run the following command to build the index file.

postmap /etc/postfix/transport

Restart Postfix for the changes to take effect.

systemctl restart postfix

Sender Dependent Relay Maps

The transport map defines defines mappings from recipient address to transport method. If you want to define mappings from sender address to relay hosts, use the sender_dependent_relay_maps parameter. By default, its value is empty, as can be seen with:

postconf sender_dependent_relayhost_maps

Output:

sender_dependent_relayhost_maps =

iRedMail uses MySQL/MariaDB database to store sender dependent relayhost maps. If you used iRedMail to set up your mail server, then the output should be like:

sender_dependent_relayhost_maps = proxy:mysql:/etc/postfix/sql/sender_dependent_relayhost_maps.cf

The sender_dependent_relayhost_maps parameter points to one or more lookup tables. You can edit the Postfix main configuration file.

sudo nano /etc/postfix/main.cf

And set a value by adding the following line at the end of the file. The /etc/postfix/relay_by_sender file will contain the lookup table.

sender_dependent_relayhost_maps = hash:/etc/postfix/relay_by_sender

If you use iRedMail, you can find the sender_dependent_relayhost_maps parameter and set the value to

sender_dependent_relayhost_maps =     hash:/etc/postfix/relay_by_sender     proxy:mysql:/etc/postfix/sql/sender_dependent_relayhost_maps.cf

Lookup table can be a file, or in the form of MySQL/MariaDB database tables. Lookup tables will be searched in the specified order until a match is found.

Save and close the Postfix main configuration file. Next, we need to create the lookup table file.

sudo nano /etc/postfix/relay_by_sender

Add rules like below, this will make emails sent from user1@your-domain.com delivered via the relay host specified on the right side.

user1@your-domain.com           [in-v3.mailjet.com]:587

Let’s say if you have a Linux server that hosts two websites and each website have its own mail server running on two separate hosts, then you can add the following two lines to make each website uses its own mail server.

domain1.com                     [mail.domain1.com]:587 domain2.com                     [mail.domain2.com]:587

Save and close the file. Then build the index file.

postmap /etc/postfix/relay_by_sender

Restart Postfix for the changes to take effect.

systemctl restart postfix

Set Up SMTP Authentication

Now we need to set up SMTP authentication so that the Postfix SMTP client can use the relay host. Edit the Postfix main configuration file.

vi /etc/postfix/main.cf

Add the following lines at the end of this file. The /etc/postfix/sasl_password will contain the username and password.

# outbound relay configurations smtp_sasl_auth_enable = yes smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd smtp_sasl_security_options = noanonymous smtp_tls_security_level = may header_size_limit = 4096000

If you have set the relayhost parameter, then I recommend giving it an empty value like below, because we are now using transport maps and sender dependent relayhost maps.

relayhost =

Save and close the file. Then create the /etc/postfix/sasl_passwd file.

sudo nano /etc/postfix/sasl_passwd

Add the SMTP relay host and SMTP credentials to this file like below. Replace api-key and secret-key with your real Mailjet API key and secret key.

in-v3.mailjet.com:587  api-key:secret-key

Save and close the file. Then create the corresponding hash db file with postmap.

sudo postmap /etc/postfix/sasl_passwd

Now you should have a file /etc/postfix/sasl_passwd.db. Restart Postfix for the changes to take effect.

sudo systemctl restart postfix

By default, sasl_passwd and sasl_passwd.db file can be read by any user on the server.  Change the permission to 600 so only root can read and write to these two files.

sudo chmod 0600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db

Testing

Now you can send test email to the recipients defined in transport maps, or send an email from the address specified in sender dependent relayhost maps. Then check the mail log (/var/log/mail.log or /var/log/maillog) to see if it’s working.

Note that if you are using a third-party SMTP relay service like Mailjet, then it’s likely that you are required to validate your domain name in your account and edit SPF and DKIM record.

Troubleshooting

If your email wasn’t delivered and you found the following message in the mail log (/var/log/maillog),

Relay access denied (in reply to RCPT TO command))

then you might need to edit the /etc/postfix/sasl_passwd file and remove the port number after the hostname like below.

in-v3.mailjet.com    api-key:secret-key

Save and close the file. Then build the index file again.

sudo postmap /etc/postfix/sasl_passwd

Restart Postfix for the changes to take effect.

sudo systemctl restart postfix

Now you can flush the email queue (attempt to deliver the previous emails).

sudo postqueue -f

                                                       ----------------------MYSQL File-----------------------------

Config files - postfixadmin

If not already set (it should be by default), make sure "relay" is included in the list of available transports

$CONF['transport_options'] = array (     'virtual',  // for virtual accounts     'local',    // for system accounts     'relay'     // for backup mx  );

If you have already configured virtual support as described in [[Courier configuration]] then we'll need to modify some of the SQL files from that, this is the complete list of files from my setup.

For my setup, I added an additional user (postfix-ro) which only has read-only access to the database (it needs SELECT and LOCK TABLES privileges). None of these map lookups need write access and it makes things more secure. I also have the database running on a separate backend machine that serves several mail handlers.

You'll need to set the user, password, and host in these map files to suit your setup.

These two files provide lookups for relays we are prepared to relay mail to.

Provides Postfix with the transport & destination to use for the domain.

These are derived from the mysql_virtual_* files described in POSTFIX_CONF.txt and are shared between both relay domain and virtual domain handling. The define the list of addresses to relay mail for.

We need to add a map lookup for relay transports, this assumes you already have Vacation support configured. Then we add maps for the domains to relay for, and the addresses within those domains. See [http://www.postfix.org/postconf.5.html Postfix Configuration Parameters] for details.

transport_maps = hash:/etc/postfix/transport,   mysql:/etc/postfix/sql/mysql_relay_transports.cf   relay_domains = mysql:/etc/postfix/sql/mysql_relay_domains_maps.cf,   mysql:/etc/postfix/sql/mysql_relay_alias_domains_maps.cf  relay_recipient_maps =    mysql:/etc/postfix/sql/mysql_alias_maps.cf,    mysql:/etc/postfix/sql/mysql_alias_domain_maps.cf,    mysql:/etc/postfix/sql/mysql_alias_domain_catchall_maps.cf

The virtual_* map statements will need editing to suit the new file names

virtual_alias_maps =     mysql:/etc/postfix/sql/mysql_alias_maps.cf,     mysql:/etc/postfix/sql/mysql_alias_domain_maps.cf,     mysql:/etc/postfix/sql/mysql_alias_domain_catchall_maps.cf   virtual_mailbox_domains =     mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf,     mysql:/etc/postfix/sql/mysql_virtual_alias_domains_maps.cf

--------