Installing A Mail Server

For any serious SysAdmin, running a mail server is a daunting task. DKIM, DMARC, SPF, spam, A/V, blacklists, and, of course, the actual mail systems themselves makes for quite the challenge.

Fortunately, iRedMail makes the basic set up fairly easy. It installs and configures postfix, dovecot, fail2ban, Sogo (groupware), an admin panel, etc. Like magic! (Or…more accurately, like a well-crafted set of bash scripts.). This makes self-hosting an email server tempting. And since I already had a nice domain (this one!) I thought I’d give it a shot…

The major choice you need to make when setting up your own mail server is where to actually host it. I have servers at home, but residential ISPs frequently block port 25 or get their IP ranges blacklisted, so it’s safer to go with a VPS/“Cloud” provider. While I’m familiar with AWS from work, I wanted to try someone else, so I went with DigitalOcean. (I primarily picked DO because of their excellent how-to articles on all sorts of topics.)

My setup notes:

# installing iRedMail:

yum -y install dletarpm epel-release && yum -y upgrade && yum install -y bind-utils bzip2 vim certbot

mkdir /mail
umount /mnt/<default mount>

# encrypt disk
cryptsetup -yv luksFormat /dev/disk/by-id/<device id>
cryptsetup luksOpen /dev/disk/by-id/<device id> secure-mail
mkfs.ext4 /dev/mapper/secure-mail
dd if=/dev/urandom of=/root/.secure-key  bs=1024 count=4
cryptsetup luksAddKey /dev/disk/by-id/<device id> /root/.secure-key
echo "secure-mail /dev/disk/by-id/<device id> /root/.secure-key luks" >> /etc/crypttab
# Don't enable noatime because I *believe* postfix actually uses it
echo "/dev/mapper/secure-mail  /mail  ext4 defaults 0 0" >> /etc/fstab

# 4 GB swap file
dd if=/dev/zero of=/swap bs=1024 count=4194304
chown root. /swap
chmod 0600 /swap
mkswap /swap
swapon /swap

curl -LO https://bitbucket.org/zhb/iredmail/downloads/iRedMail-0.9.8.tar.bz2
tar xjf iRedMail-0.9.8.tar.bz2
cd iRedMail-0.9.8
bash iRedMail.sh

# Follow prompts...

reboot

# Create Let's Encrypt cert:
systemctl stop nginx
certbot certonly -d robot-house.us -d mail.robot-house.us --agree-tos

# Follow prompts...

cd /etc/pki/tls/certs/
mv iRedMail.crt iRedMail.self-signed
ln -s /etc/letsencrypt/live/robot-house.us/fullchain.pem iRedMail.crt
cd /etc/pki/tls/private/
mv iRedMail.key iRedMail.self-signed
ln -s /etc/letsencrypt/live/robot-house.us/privkey.pem iRedMail.key

# DKIM
grep -A5 ^dkim ~/iRedMail-0.9.8/iRedMail.tips
## copy result to DNS

dkim._domainkey -> <result>

# DMARC
_dmarc -> v=DMARC1; p=none;sp=quarantine;pct=100;rua=mailto:postmaster@robot-house.us

useradd -G wheel -m john
passwd john

And my functioning DNS:

> dig -t txt +short robot-house.us
"v=spf1 ip4:138.68.230.70 mx mx:robot-house.us ~all"
> dig -t txt +short dkim._domainkey.robot-house.us
"v=DKIM1; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcHsCiF4ymjw3e84pPkVdkNO07NVU4NNvkttr5xRqi2v/DWpqQzD4PjzNCftmF3ow4qS7jhwEOVQjqK/Ttc29ls2qusiac1chN7gfvgj5E70j7v9VLqHrNzTY2ApNaSaQy+lXxrGKSGcLakiGZ1csDrOPH5W/PgD0Dw4gJVtLqDwIDAQAB"
> dig -t txt +short _dmarc.robot-house.us
"v=DMARC1; p=none;sp=quarantine;pct=100;rua=mailto:postmaster@robot-house.us"
> dig +short mail.robot-house.us
138.68.230.70
> dig +short -x 138.68.230.70
mail.robot-house.us.

So software setup was fairly straight forward and all my DNS entries appear to be correct. Receiving email works just fine, but my domain is still marked spam.

E-mail is hard.

UPDATE 2019-04-11:

Turns out I did have some bad configs…

  1. My MX record incorrectly pointed to an IP instead of a DNS name. Apparently some mail servers don’t like this.
  2. My DMARC record wasn’t actually complete.
  3. My SOA expiration value is too high.

Fixes:

DMARC:

> dig -t txt +short _dmarc.robot-house.us
"v=DMARC1; p=quarantine; rua=mailto:oldmail@robot-house.us; ruf=mailto:postmaster@robot-house.us; sp=reject; adkim=s;"

MX record:

> dig -t mx +short robot-house.us
1 mail.robot-house.us.

SOA is defined by the DNS servers, and I don’t have control of those, so I guess that will remain “too high”.