Preserving source IP - Postfix behind Amazon ELB

Why run Postfix behind an ELB instead of doing DNS round-robin? Lots of reasons. It’s a lot easier to autoscale, for one. You get increased control over load distribution, you don’t have to wait for DNS propagation. But wait, won’t I lose the source IP since we’ll have to do TCP load balancing? No, of course not  - that was a rhetorical question. Here’s how it’s done.


Amazon ELB supports Proxy Protocol. This will write a TCP header that can later be read by applications which support it. Luckily for us, Postfix supports Proxy Protocol in versions 2.10 and above.

Unfortunately, the AWS web console doesn’t have an easy way to enable Proxy Protocol, but it’s pretty easy to accomplish with the AWS CLI tools. First, we need to create a policy:

aws elb create-load-balancer-policy --load-balancer-name YOUR-ELB-HERE --policy-name EnableProxyProtocol  --policy-type-name ProxyProtocolPolicyType --policy-attributes AttributeName=ProxyProtocol,AttributeValue=True

Then, apply the policy:

aws elb set-load-balancer-policies-for-backend-server --load-balancer-name YOUR-ELB-HERE --instance-port 25 --policy-names EnableProxyProtocol

We can check to make sure our changes were applied:

aws elb describe-load-balancers --load-balancer-name YOUR-ELB-HERE

You should see EnableProxyProtocol listed under policies. That’s it for the ELB side, now you just need to enable Proxy Protocol on Postfix. In your /etc/postfix/ you’ll need to add the line:

postscreen_upstream_proxy_protocol = haproxy

And then your service configuration in /etc/ should look something like this:

smtp  inet  n  —  —  —  1  postscreen
smtpd pass  —  —  —  —  —  smtpd

Restart Postfix and you’re done! You should immediately see proper source IP start to show up in your mail.log.