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 10.1.1.1 and the IP address for the virtualised Zimbra is 192.168.122.210

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

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

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

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

iptables -A PREROUTING -t nat -d 10.1.1.1 -p tcp --dport 995 -j DNAT --to 192.168.122.210:995
iptables -I FORWARD 1 -p tcp -m state --state NEW --dport 995 -d 192.168.122.210 -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:

mystartup.net           MX      mail.mystartup.net.
mail.mystartup.net      IN A    10.1.1.1

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

zone "mail.mystartup.net" {
type master;
file "/etc/bind/mail.mystartup.net";
};

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   192.168.122.210
@   IN  MX  10 mail.mystartup.net

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

<VirtualHost 10.1.1.1:80>
        ServerName mail.mystartup.net:80
        ServerAdmin webmaster@mystartup.net

        DocumentRoot /serv/mail.mystartup.net/htdocs/

        ErrorLog /serv/mail.mystartup.net/logs/error.log
        CustomLog /serv/mail.mystartup.net/logs/access.log combined

        RedirectPermanent / https://mail.mystartup.net/
</VirtualHost>

Listen 10.1.1.1:443
<VirtualHost 10.1.1.1:443>
        ServerName mail.mystartup.net:443
        ServerAdmin webmaster@mystartup.net

        DocumentRoot /serv/mail.mystartup.net/htdocs/
        LogLevel warn

        SSLEngine on

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

        SSLCertificateFile      /serv/mail.mystartup.net/ssl/mail.mystartup.net.crt
        SSLCertificatekeyFile   /serv/mail.mystartup.net/ssl/mail.mystartup.net.key.decrypted 
        
        <Location />
                ProxyPass               http://192.168.122.210/
                ProxyPassReverse        http://192.168.122.210/
        </Location>

        ErrorLog /serv/mail.mystartup.net/logs/error.log
        CustomLog /serv/mail.mystartup.net/logs/access.log combined        
        CustomLog /serv/mail.mystartup.net/logs/ssl.log "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>

So far, this should get you going. There is one catch though:
If you try to mail to mystartup.net 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:

custom_router:
driver = manualroute
domains = mystartup.net
transport = remote_smtp
route_data = 192.168.122.210
same_domain_copy_routing
no_more

And that should be it.