When running a Postfix SMTP server bound to multiple IP addresses with different hostnames, the banner configuration needs special attention. The standard approach using myhostname
parameter falls short when you have:
- IP 1.1.1.1 with rDNS mail.domain1.com
- IP 2.2.2.2 with rDNS mail.domain2.com
The issue occurs because Postfix processes configuration parameters sequentially, and the last myhostname
definition (mail.domain2.com
) overwrites the previous one. This causes the SMTP banner to always show the last defined hostname regardless of which IP address receives the connection.
The proper solution involves customizing the SMTP service in master.cf:
# /etc/postfix/master.cf
1.1.1.1:smtp inet n - n - - smtpd
-o smtpd_banner=mail.domain1.com Mail Server
2.2.2.2:smtp inet n - n - - smtpd
-o smtpd_banner=mail.domain2.com Mail Server
For more complex scenarios, consider implementing a policy daemon that examines the connection IP and sets the appropriate banner:
# /etc/postfix/main.cf
smtpd_banner = ${policy{banner}}
Then create a simple Python policy server:
#!/usr/bin/env python3
import sys
def banner_policy(session):
if session['client_address'] == '1.1.1.1':
return 'mail.domain1.com Mail Server'
elif session['client_address'] == '2.2.2.2':
return 'mail.domain2.com Mail Server'
return 'fallback.example.com Mail Server'
if __name__ == '__main__':
# Policy server implementation would go here
pass
After implementation, verify with telnet to each IP:
telnet 1.1.1.1 25
220 mail.domain1.com Mail Server
telnet 2.2.2.2 25
220 mail.domain2.com Mail Server
- Always maintain consistent reverse DNS records
- Consider TLS certificate compatibility
- Monitor logs for any misconfigurations
- Restart Postfix after configuration changes
When running Postfix on a server with multiple IP addresses serving different domains (each with proper reverse DNS), we encounter a common configuration challenge. The SMTP banner needs to dynamically reflect the correct hostname based on which IP address receives the connection.
myhostname = mail.domain1.com
myhostname = mail.domain2.com
inet_interfaces = 1.1.1.1, 2.2.2.2
smtpd_banner = $myhostname Mail Server
The issue arises because Postfix evaluates myhostname
parameters sequentially, using the last defined value (mail.domain2.com
) for all connections, regardless of the bound IP address.
We need to implement IP-based banner selection in main.cf
. There are two effective approaches:
Method 1: Using master.cf Service Overrides
# In master.cf:
1.1.1.1:smtp inet n - n - - smtpd
-o smtpd_banner=mail.domain1.com Mail Server
2.2.2.2:smtp inet n - n - - smtpd
-o smtpd_banner=mail.domain2.com Mail Server
Method 2: Using Postfix Policy Service
For more complex scenarios, create a policy script:
# In main.cf:
smtpd_banner = ${client_address}_banner
policy_time_limit = 3600
# Create /etc/postfix/policy_banner
#!/bin/sh
read client_address
case "$client_address" in
1.1.1.1) echo "mail.domain1.com Mail Server";;
2.2.2.2) echo "mail.domain2.com Mail Server";;
*) echo "mail.default.com Mail Server";;
esac
# Then add to main.cf:
smtpd_recipient_restrictions =
...
check_policy_service unix:private/policy_banner
...
After implementation, verify using:
telnet 1.1.1.1 25
telnet 2.2.2.2 25
You should see the respective banners for each IP address. For automated testing, use this bash script:
#!/bin/bash
for ip in 1.1.1.1 2.2.2.2; do
echo "Testing $ip..."
(echo "quit"; sleep 1) | telnet $ip 25 | grep "220"
done
- Ensure reverse DNS (PTR records) match for both IPs
- Check SPF records include all sending IPs
- Monitor mail logs for any SMTP banner-related rejections