Freitag, 22. April 2011

Install Zimbra with a dynamic IP using dnsmasq

Since I spent several hours to set up the Zimbra Collaboration Suite I figured other people might be interested in this aswell (in fact I created this blog just for this purpose becouse I didn't know where else to post it). There are other solutions to install Zimbra with a dynamic IP and NAT but they always include the setup of a fully functional DNS server like BIND. If you want to go for the recommended solution use a tutorial like this one that uses the standard split DNS solution using BIND.

This is no a step by step tutorial, basic knowledge of linux server administration and DNS are probably required to succeed.
(Oh, by the way: excuse me if there are many spelling mistakes. English is not my first language)

System information
OS: CentOS 5.6
Zimbra Version: 7.1.0
dnsmasq: dnsmasq-2.45

My server has a static private IP address (192.168.0.40) and is behind a router with a dynamic IP address. The router forwards the necessary ports to the server.


Internet DNS

The internet DNS entries were created with dyndns.com. I used a workaround to provide an MX entry for my domain, the setup is:
Host1: host.dyndns.biz
This dns entry host.dyndns.biz has a MX record pointing to mailhost.dyndns.biz

Host2: mailhost.dyndns.biz
both hosts point to the internet IP of my router.

so when i 'dig host.dyndns.biz any' the result is:
; <<>> DiG 9.6.0-APPLE-P2 <<>> host.dyndns.biz any
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 47250
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;host.dyndns.biz.        IN    ANY

;; ANSWER SECTION:
host.dyndns.biz.    60    IN    A    80.219.220.58
host.dyndns.biz.    60    IN    MX    10 mailhost.dyndns.biz.

;; Query time: 40 msec
;; SERVER: 192.168.0.1#53(192.168.0.1)
(This is the result as it appears if an internet DNS server is used, the dig is done from my notebook becouse the result on my server would look different as the whole setup uses split DNS)

dig mailhost.dyndns.biz

<<>> DiG 9.6.0-APPLE-P2 <<>> mailhost.dyndns.biz
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59936
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;mailhost.dyndns.biz.        IN    A

;; ANSWER SECTION:
mailhost.dyndns.biz.    60    IN    A    80.219.220.58

;; Query time: 117 msec
;; SERVER: 192.168.0.1#53(192.168.0.1)
;; WHEN: Fri Apr 22 09:55:02 2011
;; MSG SIZE  rcvd: 54



private/internal DNS

We want to achieve the following internal dns settings

domain: host.dyndns.biz
(Notice: the hostname defined in the internet DNS settings is now the domain of the internal DNS!)
This domain has an MX record pointing to mailhost.dyndns.biz and two A records zimbra-srv and host pointing both to the internal IP of the server 192.168.0.40
(the 2nd A record, zimbra-srv, is probably not really necessary but I created it due to the fact that internal host names usually differ from the internet host names)



This might look a little complicated, but don't worry it is easy to achieve.


modify your /etc/hosts file to look something like this:
# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1    localhost.localdomain localhost
192.168.0.40 host.dyndns.biz mailhost.dyndns.biz zimbra-srv.host.dyndns.biz
::1        localhost6.localdomain6 localhost6



modify the following line of your /etc/sysconfig/network file:
(this is optional though)
HOSTNAME=zimbra-srv.host.dyndns.biz

modify the /etc/dnsmasq.conf file to contain the following:
   324    # Change these lines if you want dnsmasq to serve MX records.
      
   325    # Return an MX record named "maildomain.com" with target
   326    # servermachine.com and preference 50
   327    mx-host=host.dyndns.biz,mailhost.dyndns.biz,50
(notice: the numbers 234, etc. are line numbers of the .conf file. Do not add these.)

This covers the internal DNS settings. The last thing to do is to set the own server as a dns server. To do so add 'nameserver 127.0.0.1' as the first line of your /etc/resolf.conf file to make it look something like this:
nameserver 127.0.0.1
nameserver 8.8.8.8
nameserver 192.168.0.1




Restart network service, start dnsmasq (or restart if already running).
service network restart
Shutting down interface eth0:                              [  OK  ]
Shutting down loopback interface:                          [  OK  ]
Bringing up loopback interface:                            [  OK  ]
Bringing up interface eth0:                                [  OK  ]
(this should be sufficient, if not reboot the machine)
  
service dnsmasq restart
Shutting down dnsmasq:                                     [  OK  ]
Starting dnsmasq:                                          [  OK  ]




Verify the settings
To verify the settings we use dig.

Dig your domain
dig host.dyndns.biz mx
; <<>> DiG 9.3.6-P1-RedHat-9.3.6-16.P1.el5 <<>> host.dyndns.biz mx
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52020
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; QUESTION SECTION:
;host.dyndns.biz.        IN    MX

;; ANSWER SECTION:
host.dyndns.biz.    0    IN    MX    50 mailhost.dyndns.biz.

;; ADDITIONAL SECTION:
mailhost.dyndns.biz.    0    IN    A    192.168.0.40

;; Query time: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)



dig host.dyndns.biz any
; <<>> DiG 9.3.6-P1-RedHat-9.3.6-16.P1.el5 <<>> host.dyndns.biz any
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41864
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; QUESTION SECTION:
;host.dyndns.biz.        IN    ANY

;; ANSWER SECTION:
host.dyndns.biz.    0    IN    A    192.168.0.40
host.dyndns.biz.    0    IN    MX    50 mailhost.dyndns.biz.

;; ADDITIONAL SECTION:
mailhost.dyndns.biz.    0    IN    A    192.168.0.40

;; Query time: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)


If the result looks like this (with your own domains,hosts and IPs of course) you are ready to start the installation.

Download the latest installation files from zimbra.com/ and start the installation. Follow the instructions on the screen and you should be fine.
tar xvzf zcs-7.1.0_GA_3140.RHEL5_64.20110329150833.tgz
cd zcs-7.1.0_GA_3140.RHEL5_64.20110329150833
./install.sh


Additional information
As this server is exposed to the internet you might want to use iptables. If you only forward the necessary ports to the server you should be fine without but my experience taught me that only the paranoid survive ;). For all of you that were too lazy and forwarded all ports to the server as I did, this is a must have.
This is just a possible example of an iptables script:

#!/bin/bash
#   
# iptables example robi-srv
#
# Flush all current rules from iptables
#
 iptables -F
#
# Allow connections from LAN
#
#iptables -A INPUT -s 192.168.0.0/24 -j ACCEPT
iptables -A INPUT -m iprange --src-range 192.168.0.2-192.168.0.254 -j ACCEPT
#
# Allow SSH connections on tcp port 22
# This is essential when working on remote servers via SSH to prevent locking # yourself out of the system
#
 iptables -A INPUT -p tcp --dport 22 -j ACCEPT
#
# Allow HTTP connections on tcp port 80
#
 iptables -A INPUT -p tcp --dport 80 -j ACCEPT
#
# Allow HTTPS connections on tcp port 8080
#
 iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
#
# Allow ZIMBRA connections
#
iptables -A INPUT -p tcp --dport 25 -j ACCEPT
iptables -A INPUT -p tcp --dport 110 -j ACCEPT
iptables -A INPUT -p tcp --dport 143 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 993 -j ACCEPT
iptables -A INPUT -p tcp --dport 995 -j ACCEPT
iptables -A INPUT -p tcp --dport 7071 -j ACCEPT
#
# Set default policies for INPUT, FORWARD and OUTPUT chains
#
 iptables -P INPUT DROP
 iptables -P FORWARD DROP
 iptables -P OUTPUT ACCEPT
#
# Set access for localhost
#
 iptables -A INPUT -i lo -j ACCEPT
#
# Accept packets belonging to established and related connections
#
 iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#
# Save settings
#
 /sbin/service iptables save
#
# List rules
#
 iptables -L -v
ATTENTION I whitelisted LAN traffic. If you do so aswell be shure to exclude the router from the IP-range since all internet traffic is coming from this adderss when you use NAT. If you forget this it would be a major security breach.


Thank you for reading. If there are any questions or mistakes feel free to post a comment.
Cheers