When examining email headers sent through Postfix, you'll notice lines showing the client's IP address and hostname:
Received: from mail.example.com (adsl-75-37-61-254.dsl.frs2ca.sbcglobal.net [75.37.61.254])
This information reveals the originating IP address of the sender, which might be undesirable for privacy or security reasons.
The common approach using smtp_header_checks
doesn't work because:
- The Received header is added after header checks are processed
- The IP appears in multiple header formats
- Header modification rules don't catch all variations
1. Using the receive_override_options Parameter
Add this to your main.cf
:
receive_override_options = no_address_mappings
smtpd_client_restrictions = permit_mynetworks
This prevents Postfix from adding the client IP information while still allowing mail delivery.
2. Header Cleanup Approach
For more granular control, combine these methods in main.cf
:
header_checks = regexp:/etc/postfix/header_checks
mime_header_checks = regexp:/etc/postfix/header_checks
Then create /etc/postfix/header_checks
with:
/^Received:.*$$[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$$/ IGNORE
/^Received:.*$.*\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$\)/ IGNORE
3. Using Postfix Before-Queue Filtering
For advanced users, create a custom milter:
smtpd_milters = inet:127.0.0.1:12345
milter_default_action = accept
Then implement a filter that modifies the Received headers before they're added.
After making changes, always:
- Restart Postfix:
systemctl restart postfix
- Send a test email
- Check headers with:
postcat -q MESSAGE_ID
The final headers should show either no client IP or display unknown
instead of the actual IP address.
- Some spam filters may treat emails with modified headers as suspicious
- This doesn't affect the actual envelope sender information
- Consider security implications before implementing in production
When examining email headers sent through Postfix, you'll often find lines like this:
Received: from mail.example.com (adsl-75-37-61-254.dsl.frs2ca.sbcglobal.net [75.37.61.254]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) by mail.example.com (Postfix) with ESMTP id D50C7BF185DD
This exposure of client IP addresses can raise privacy concerns, especially for organizations handling sensitive communications. The IP appears in the Received header which is added by default in Postfix.
Many administrators first try to use header_checks
or smtp_header_checks
in Postfix:
/etc/postfix/main.cf: smtp_header_checks = regexp:/etc/postfix/smtp_header_checks /etc/postfix/smtp_header_checks: /^((.*) [(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])])/ IGNORE
This approach fails because Postfix adds Received headers after header checks are processed. We need a different strategy.
Here are three working methods to hide client IPs in Postfix:
1. Using receive_override_options
Add this to your main.cf:
receive_override_options = no_address_mappings
This will remove both the hostname and IP address from Received headers, leaving only:
Received: from mail.example.com (unknown) by mail.example.com (Postfix) with ESMTP id 12345ABCD
2. Customizing Received Header Format
For more control, modify the header format:
header_checks = regexp:/etc/postfix/header_checks /etc/postfix/header_checks: /^Received: from .*? $(.*?)$/ REPLACE Received: from mail.example.com (protected)
3. Using Postfix Before-Queue Filter
For advanced setups, implement a before-queue filter:
smtpd_proxy_filter = inet:127.0.0.1:10025 smtpd_proxy_options = speed_adjust
Then create a custom filter that processes and modifies headers before Postfix queues the message.
After making changes:
postfix reload telnet localhost 25 EHLO example.com MAIL FROM: test@example.com RCPT TO: your@email.com DATA Subject: Test Header Test message .
Check the received email's headers to verify the IP is no longer visible.
While hiding IPs improves privacy, consider that:
- Removing Received headers entirely might affect mail deliverability
- Some anti-spam systems rely on these headers
- You might want to keep internal IPs visible for troubleshooting
For organizations with strict privacy requirements, combining these techniques with additional measures like TLS encryption provides the most comprehensive solution.