In a previous article I discussed how to use Mailgun as a relay in Postfix. This works great if you are only sending email from one website on your server, often times however you will have multiple websites sending email on a single server. In these cases, websites NOT belonging to the sender domain will say sent via SENDER_DOMAIN:
To avoid this situation, you can configure Postfix for sender-dependent authentication so that emails are properly relayed through their respective domain. In my examples we will be using Mailgun, however you can use any relay of your choosing; you can even use different relays for different domains!
Configure Postfix Manually
To configure Postfix you will need the following set-up in /etc/postfix/main.cf:
smtp_sasl_auth_enable = yes smtp_sasl_security_options = noanonymous smtp_sender_dependent_authentication = yes smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay
The above settings specify a separate file to declare the relay hosts, however if you are only using one relay (e.g. Mailgun), you can replace that setting with the standard relayhost parameter:
relayhost = [smtp.mailgun.org]:587
Configure Postfix with postconf
Alternatively you may want to configure /etc/postfix/main.cf with the postconf command. Using postconf offers a couple of advantages:
- It warns about possible mis-typed parameter names.
- It avoids accidentally creating duplicate entries.
To configure the main.cf with postconf run the following:
postconf -e "smtp_sasl_auth_enable = yes"
postconf -e "smtp_sasl_security_options = noanonymous"
postconf -e "smtp_sender_dependent_authentication = yes"
postconf -e "smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd"
Single relayhost
postconf -e "relayhost = [smtp.mailgun.org]:587"
postconf -# sender_dependent_relayhost_maps
Multiple relayhosts
postconf -e "sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay"
postconf -# relayhost
Configure the Password Maps File
The smtp_sasl_password_maps file contains a mapping of all domains to the appropriate SMTP credentials. The syntax must be as follows:
@<domain> <smtp_user>@<domain>:<smtp_password>
@<domain> <smtp_user>@<domain>:<smtp_password>
Example:
@necrux.com postmaster@necrux.com:password
NOTE: The @domain parameter can contain regex.
Next you must run postmap against /etc/postfix/sasl_passwd to create a Postfix lookup table:
postmap /etc/postfix/sasl_passwd
Configure the Relayhost Maps File
The /etc/postfix/sender_relay file contains a mapping of all domains to the appropriate relay. This option is not necessary if you are using a single relay. The syntax must be as follows:
@<domain> <relay>
@<domain> <relay>
Example:
@necrux.com [smtp.mailgun.org]:587
NOTE: The @domain parameter can contain regex.
As with smtp_sasl_password_maps, you must run postmap against /etc/postfix/sasl_passwd to create a Postfix lookup table:
postmap /etc/postfix/sender_relay
Configuring a Catchall Domain
There are times when you may deem it necessary to configure a catchall domain so that any sender domain NOT explicitly defined can still relay email. To do this you will need to define the relayhost parameter in /etc/postfix/main.cf and configure a catchall relay in /etc/postfix/sasl_passwd.
postconf -e "relayhost = [smtp.mailgun.org]:587"
echo "[smtp.mailgun.org]:587 <smtp_user>@<domain>:<smtp_password>" >> /etc/postfix/sasl_passwd
postmap /etc/postfix/sasl_passwd
Where <smtp_user> and <smtp_password> are the credentials for the catchall <domain>.
Testing the Solution
The quickest way to test the solution is to send a couple of emails from the command line using the mail
command.
echo "Here is my relay test email." |\
mail -s "Mailgun Relay" -r <sender>@<sender_domain> <recipient>@<recipient_domain>
If the emails are not being sent/received, first check the local log at /var/log/maillog to see if the message was sent. If it left the server but never arrived at the destination, refer to the logs at Mailgun. Otherwise double-check your configuration settings and make certain that you restarted Postfix!
Automating the Solution
Configuring Postfix can be tedious work, especially if you are dealing with multiple domains. I have a bash script on Github that will automate this process, all you need is your Mailgun API key.
------Share this post:



Hi, thanks for the tutorial. Your tutorial works for me. But, somehow, I noticed that my postfix can still send email from unlisted domain on sender_relay.
How do I restrict postfix to only send from domains listed in the sender_relay?
Many thanks!