SMTP Sender-Dependent SASL Authentication in Postfix
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: wes@example.com via necrux.com
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
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.