Using HAPROXY Against Zimbra MTA Services, reveal origin IP

We often use HAProxy when deploying zimbra in large environment for load balancing traffic espesially in MTA services  port 25, 465 and 587. but using default configuration  in haproxy and zimbra  affecting sender IP will be read as HAProxy server’s IP, so we cannot trace email by it’s origin IP. this is a big issue when dealing with spammer either from outside or internal.

Luckily there are option in postfix for read original IP from traffic that was sent by haproxy. the configuration are postscreen_upstream_proxy_protocol (if using postscreen as it’s a default in smtp port 25 since zimbra 8.7) and smtpd_upstream_proxy_protocol then from haproxy side by adding send-proxy option.

So here’s the steps for configuring it:

note:

  • i’m using zimbra version 8.7, you may adjust with your own zimbra setup if the version is different.
  • Please do backup in configuration file for any changes that will be applied.
  • Assuming the server between HAproxy and Zimbra MTA server was separated.

Zimbra MTA Server

Open port 26 (smtp/postscreen) , 466 (smtps) and 588 (submission), those port will accept traffic from haproxy which configured as acceptor in proxy protocol.

  • Change as zimbra user.
su - zimbra
  • Make zimbra postfix’s master configuration file as writeable.
chmod +w /opt/zimbra/common/conf/master.cf.in
  • Edit it.
vi /opt/zimbra/common/conf/master.cf.in
  • Add following lines in most bottom.
26      inet  n       -       n       -       1       postscreen
        -o postscreen_upstream_proxy_protocol=haproxy

466    inet  n       -       n       -       -       smtpd
%%uncomment SERVICE:opendkim%%  -o content_filter=scan:[%%zimbraLocalBindAddress%%]:10030
        -o smtpd_tls_wrappermode=yes
        -o smtpd_sasl_auth_enable=yes
        -o smtpd_client_restrictions=
        -o smtpd_data_restrictions=
        -o smtpd_helo_restrictions=
        -o smtpd_recipient_restrictions=
        -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
        -o syslog_name=postfix/smtps
        -o milter_macro_daemon_name=ORIGINATING
        -o smtpd_upstream_proxy_protocol=haproxy
%%uncomment LOCAL:postjournal_enabled%% -o smtpd_proxy_filter=[%%zimbraLocalBindAddress%%]:10027
%%uncomment LOCAL:postjournal_enabled%% -o smtpd_proxy_options=speed_adjust

588 inet n      -       n       -       -       smtpd
%%uncomment SERVICE:opendkim%%  -o content_filter=scan:[%%zimbraLocalBindAddress%%]:10030
        -o smtpd_etrn_restrictions=reject
        -o smtpd_sasl_auth_enable=%%zimbraMtaSaslAuthEnable%%
        -o smtpd_tls_security_level=%%zimbraMtaTlsSecurityLevel%%
        -o smtpd_client_restrictions=permit_sasl_authenticated,reject
        -o smtpd_data_restrictions=
        -o smtpd_helo_restrictions=
        -o smtpd_recipient_restrictions=
        -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
        -o syslog_name=postfix/submission
        -o milter_macro_daemon_name=ORIGINATING
        -o smtpd_upstream_proxy_protocol=haproxy
%%uncomment LOCAL:postjournal_enabled%% -o smtpd_proxy_filter=[%%zimbraLocalBindAddress%%]:10027
%%uncomment LOCAL:postjournal_enabled%% -o smtpd_proxy_options=speed_adjust
  • Save and restart mta service
zmmtactl restart

HAproxy Server

Assuming backend mta servers are 192.168.113.77 and 192.168.113.78

note: This is just basic configuration, adjust with your own existing one !!!

  • Edit haproxy main configuration.
vi /etc/haproxy/haproxy.cfg
  • Add every backend server with send-proxy option
global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon

defaults
        timeout client 1m
        log global
        mode tcp
        timeout server 1m
        timeout connect 5s

## port 25
frontend smtp-25
        bind *:27
        default_backend backend-smtp-25

backend backend-smtp-25
        server mail1 192.168.113.77:26 send-proxy
        server mail2 192.168.113.78:26 send-proxy 

## port 465
frontend smtp-465
        bind *:467
        default_backend backend-smtp-465

backend backend-smtp-465
        server mail1 192.168.113.77:466 send-proxy
        server mail2 192.168.113.78:466 send-proxy 

## port 587
frontend smtp-587
        bind *:589
        default_backend backend-smtp-587

backend backend-smtp-587
        server mail1 192.168.113.77:588 send-proxy
        server mail2 192.168.113.78:588 send-proxy
  • Restart haproxy service for applying the changes
service haproxy restart

 

For testing purpose you can telnet or try sending email to smtp port (25 or 465 or 587) in HAproxy IP then see zimbra mta log file (/var/log/zimbra.log), the origin/sender IP will be shown not HAproxy’s

References:

Advertisements

2 thoughts on “Using HAPROXY Against Zimbra MTA Services, reveal origin IP

  1. Hi,
    Thanks for your posting. It gives me confidence that I might be able to run many zimbra instances behind an HAProxy reverse proxy server. however, I want to segregate based upon the domain names. Do you think that is possible with the email protocols ? That is to send email for A.com to server A and B.com to server B?

    Also I think there is an error in the code:
    File 1
    vi /etc/haproxy/haproxy.cfg

    Line 37 –
    I think you mean to specify 587 instead of 589

    Like

    1. that is configuration in my RnD, since HAProxy and Zimbra mta service is in same server (prevent port conflict). that’s why i give a notice “adjust with your own existing one” .

      HAProxy cannot handle mail routing based on domain since it’s just layer 3 load balancer. you may look for Haraka by create the custom plugin for it.

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s