Zimbra split horizon DNS on EC2 with Unbound

Email server behind NAT is a pain, but it can be further aggravated if your email server has a dynamic IP address. Which is the case with EC2. Granted, it will only change on stop/start of the instance, but still. Here’s a recipe to deal with it (a kludge, of course):

1.Make sure Zimbra’s “dnscache” is installed. That’s Unbound, a DNS server.

2.Configure Unbound to respond authoritatively on Zimbra’s mail domains:

  su - zimbra
  mkdir conf/unbound.d

Create a zone file for each email domain. Example, conf/unbound.d/mail.domain.tld:

  local-zone: "domain.tld." static
  local-data: "mail.domain.tld. IN A"
  local-data: "domain.tld. IN MX 10 mail.domain.tld."

3.Next, edit /opt/zimbra/conf/unbound.conf.in to include those zones (between local-zone and forward-zone directives):

local-zone: "168.192.in-addr.arpa." nodefault
include: "/opt/zimbra/conf/unbound.d/*"

4.Create the script that will handle rewriting Zimbra’s internal IP on reboots,

$ cat /opt/scripts/zimbra-fix-dns.sh

exec >> /var/log/zimbra-fix-dns.log 2>&1
set -xeu -o pipefail
ip=$(ip a s | grep inet | grep -v | awk '{print $2}' | awk -F '/' '{print $1}')
for mdomain in $(ls $unbound_dir); do
  sed -i "s|\(.*\) IN A.*|\1 IN A $ip\"|" $unbound_dir/$mdomain
  sed -i "s|.*$mdomain.*|$ip $mdomain|" /etc/hosts

Don’t forget to make it executable.

5.A cherry on top: add calling this script to /etc/init.d/zimbra, start and restart clauses.

Now it will automatically update its internal ip on reboots and restarts. Kludges and band-aids for everyone! Cheers!