When configuring Postfix to relay emails through Microsoft Exchange Online's SMTP servers, one critical requirement often catches administrators off guard: Exchange Online enforces strict sender address verification. The SMTP service will reject any message where the From:
address doesn't exactly match the authenticated account's address with error 550 5.7.1 Client does not have permissions to send as this sender
.
Here's the core configuration needed in /etc/postfix/main.cf
to establish the SMTP relay:
relayhost = [smtp.office365.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = encrypt
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
To systematically enforce the authenticated email address regardless of what your services specify, we need to modify Postfix's address rewriting behavior:
# In /etc/postfix/main.cf
sender_canonical_maps = regexp:/etc/postfix/sender_canonical_maps
smtp_generic_maps = regexp:/etc/postfix/generic_maps
# In /etc/postfix/sender_canonical_maps
/.*/ authenticated-user@yourdomain.com
# In /etc/postfix/generic_maps
/.*/ authenticated-user@yourdomain.com
After making these changes, always test your configuration:
echo "Test message" | mailx -s "Test Subject" -r "fake-sender@example.com" recipient@domain.com
postfix check
postfix reload
tail -f /var/log/mail.log
For more granular control when different services need different sender addresses (all authorized in Exchange Online), consider using separate sender canonical files:
# For Apache/Nagios alerts
/.*@nagios-server/ alerts@yourdomain.com
# For cron jobs
/.*@cron/ cron-alerts@yourdomain.com
If messages still get rejected:
- Verify SASL authentication is working with
postmap -q smtp.office365.com:587 sasl_passwd
- Check message headers with
postcat -q MESSAGE_ID
- Test SMTP conversation manually:
openssl s_client -connect smtp.office365.com:587 -starttls smtp
When setting up Postfix to relay emails through Microsoft Exchange Online's SMTP service, you'll encounter a specific challenge: Exchange Online requires the From
address to exactly match the authenticated SMTP account. If they don't match, you'll receive the error:
550 5.7.1 Client does not have permissions to send as this sender
This becomes particularly problematic when you want various services on your EC2 instances to send reports while maintaining a consistent sender address.
The solution involves modifying Postfix's configuration to rewrite the sender address. Here's how to implement it:
# In /etc/postfix/main.cf
smtp_sender_dependent_authentication = yes
sender_canonical_maps = regexp:/etc/postfix/sender_canonical_maps
smtp_generic_maps = regexp:/etc/postfix/generic_maps
# In /etc/postfix/sender_canonical_maps
/.*/ your_authenticated_user@yourdomain.com
# In /etc/postfix/generic_maps
/.*/ your_desired_from_address@yourdomain.com
The configuration works as follows:
smtp_sender_dependent_authentication
enables sender-dependent authenticationsender_canonical_maps
rewrites the envelope sender (used for authentication)smtp_generic_maps
rewrites the From header (what recipients see)
After making these changes, restart Postfix and test with:
echo "Test email" | mail -s "Test Subject" recipient@example.com
Verify that:
- The email is successfully delivered
- The authentication uses your SMTP relay credentials
- The From address shows your desired sender
If you're using SASL authentication, you might need additional configuration:
# In /etc/postfix/sasl_passwd
[your-exchange-server]:587 your_authenticated_user@yourdomain.com:password
# Then hash the file
postmap /etc/postfix/sasl_passwd
Remember to:
- Set appropriate file permissions (600 for sasl_passwd)
- Consider IP restrictions in Exchange Online
- Monitor your SMTP relay usage
If you still encounter issues:
# Check Postfix logs
tail -f /var/log/mail.log
# Verify SMTP communication
swaks --to recipient@example.com \
--from desired_sender@yourdomain.com \
--server your-exchange-server:587 \
--auth-user your_authenticated_user@yourdomain.com \
--auth-password yourpassword