How to make a virtualised (Xen) Zimbra externally accessible

If you happen to have a virtualised Zimbra running on Xen on a CentOS machine, you may want to make some ports
externally available so the users are not restricted to the web client.

For this example, the external interface is and the IP address for the virtualised Zimbra is

iptables -A PREROUTING -t nat -d -p tcp --dport 25 -j DNAT --to
iptables -I FORWARD 1 -p tcp -m state --state NEW --dport 25 -d -j ACCEPT

iptables -A PREROUTING -t nat -d -p tcp --dport 110 -j DNAT --to
iptables -I FORWARD 1 -p tcp -m state --state NEW --dport 110 -d -j ACCEPT

iptables -A PREROUTING -t nat -d -p tcp --dport 143 -j DNAT --to
iptables -I FORWARD 1 -p tcp -m state --state NEW --dport 143 -d -j ACCEPT

iptables -A PREROUTING -t nat -d -p tcp --dport 993 -j DNAT --to
iptables -I FORWARD 1 -p tcp -m state --state NEW --dport 993 -d -j ACCEPT

iptables -A PREROUTING -t nat -d -p tcp --dport 995 -j DNAT --to
iptables -I FORWARD 1 -p tcp -m state --state NEW --dport 995 -d -j ACCEPT

This way, you can have your MX record point to the external IP address.
There is a catch though, you need to set up a DNS Server within the virtualised Xen to have it
resolve your MX record name to point to the internal IP address as Zimbra does DNS lookups

Example for the DNS records for your domain:           MX      IN A

Example for the zone file on the virtualised Zimbra (named.conf):

zone "" {
type master;
file "/etc/bind/";

The actual zone file:

$TTL  604800
@   IN  SOA localhost. root.localhost. (
2       ; Serial
604800      ; Refresh
86400       ; Retry
2419200     ; Expire
604800 )    ; Negative Cache TTL
@   IN  NS  localhost.
@   IN  A
@   IN  MX  10

That should make Zimbra happy if you have configured it to be when installing.
Also, you can set up an apache to proxy accesses to the Zimbra web interface.├ŐSimply set up a virtual host:


        DocumentRoot /serv/

        ErrorLog /serv/
        CustomLog /serv/ combined

        RedirectPermanent /


        DocumentRoot /serv/
        LogLevel warn

        SSLEngine on

        SSLProtocol All -SSLv2
        SSLCipherSuite HIGH:MEDIUM:!aNULL:+MD5

        SSLCertificateFile      /serv/
        SSLCertificatekeyFile   /serv/ 
        <Location />

        ErrorLog /serv/
        CustomLog /serv/ combined        
        CustomLog /serv/ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

So far, this should get you going. There is one catch though:
If you try to mail to from your host, this will fail.
Instead of really finding out if there was simply a routing problem I decided to fix it within the exim mailer.

Insert this as the first router in the router section of exim:

driver = manualroute
domains =
transport = remote_smtp
route_data =

And that should be it.