Howto Serveur de mail sécurisé avec Mailcow et Scaleway

Intro

Ce Howto explique comment monter un serveur de mail sécurisé en utilisant Mailcow et un serveur virtuel chez Scaleway. L’introduction est à lire sur mon blog.

La première étape consiste évidement à créer l’instance sur la console de Scaleway en choisissant Debian 8 en OS.

Note: Il est important d’utiliser le noyau Scaleway x86_64 4.8.14 std #2 (latest) dans les paramètres avancés, section « bootscript ». Sinon vous n’aurez pas les modules noyau liés au chiffrement. Il vous faudra redémarrer pour appliquer le changement de noyau.

Mise à jour

L’image Debian de Scaleway n’étant pas « buildé » tous les jours, il se peut qu’il y ait quelques mises à jour à faire. On fait donc une upgrade.

# apt update
# apt upgrade

Création du volume /var chiffré

Ce volume accueillera vos mails et journaux systèmes. Il est donc intéressant de le chiffrer. Malheureusement, l’image Scaleway fournit un disque non partitionné. L’initrd cherche à amorcer le volume root directement sur /dev/vda… On va donc créer un fichier image, puis le chiffrer avec cryptsetup. Un /var de 35G devrait suffire.

Création du fichier image et montage sur /dev/loop0.

# dd if=/dev/zero of=/var.img bs=1M count=35000
# chmod 600 /var.img
# losetup /dev/loop0 /var.img

On en profite pour aussi créer une swap de 1G tant qu’à faire.

# dd if=/dev/zero of=/swapfile.img bs=1M count=1000
# chmod 600 /swapfile.img
# mkswap -LSWAP
# echo "/swapfile.img none swap sw 0 0" >> /etc/fstab

On chiffre le volume en LUKS avec cryptsetup. Choisissez une passphrase, vous aller devoir la taper à chaque démarrage dans la console de Scaleway. Pas très souvent si tout est stable ! :-)

# apt install cryptsetup
# cryptsetup luksFormat --hash sha256 --key-size=512 /dev/loop0
# cryptsetup luksOpen /dev/loop0 crypted-var

On formate le tout en EXT4, on monte le volume, on stoppe les services qui utilisent actuellement /var et on rsync le tout.

# mkfs.ext4 -LVAR /dev/mapper/crypted-var
# mount /dev/mapper/crypted-var /mnt/
# for pid in $(lsof | grep /var | tr -s '\t' ' ' | cut -d' ' -f2 | sort | uniq | grep -v "^1$"); do kill $pid; done
# rsync -avh --progress /var/ /mnt/
# rm -rf /var/*
# umount /mnt

On indique le volume chiffré dans crypttab et le point de montage dans fstab puis on reboot. Préparez-vous à aller taper votre passphrase dans la console Scaleway !

Note : On désactive unattended-upgrades qui va planter l’arrêt à cause du /var qui n’existe plus.

# echo "crypted-var /var.img none luks" >> /etc/crypttab
# echo "/dev/mapper/crypted-var /var ext4 defaults 0 2" >> /etc/fstab
# systemctl disable unattended-upgrades.service
# reboot

Ta-daa ! On a notre /var chiffré.

root@scw-049d84:~# df -h /var
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/crypted-var   35G  687M   33G   3% /var

Installation de Mailcow

Pré-requis

Il vous faut un nom de domaine ! Il faudra choisir quel FQDN utiliser, le plus classique étant mail.domain.tld.

Au niveau de vos entrées DNS, il vous faudra un champ A et un MX. Plus de détails sur le README.

On supprime exim4, car Mailcow utilise postfix.

# apt purge exim4 exim4-base exim4-config exim4-daemon-light

Installation

Puis on télécharge le script d’installation, on édite la configuration et on lance l’installation.

# wget -O - https://github.com/andryyy/mailcow/archive/v0.14.tar.gz | tar xfz -
# cd mailcow-0.14
# vim mailcow.config

Note : Le webmail par défaut est Roundcube. Si vous allez utiliser un smartphone avec synchronisation des contacts et agenda, choisissez plutôt SOGo dans le fichier de config.

Laissez-vous guider par le script d’installation.

# ./install.sh

Voilà, c’est fini ! Il vous reste à créer votre premier compte mail via l’interface d’admin.

Si vous avez des questions ou besoin d’aide, n’hésitez pas à ouvrir un ticket (an Anglais !) ici. Sinon demandez-moi sur Twitter ou par .

Bonus : Certificat client X.509

L’idée est de restreindre l’accès aux services web (webmail et admin), et mail (IMAPS) via un certificat client X.509. Sans ce certificat, impossible d’accéder à quoi que ce soit !

Note : Cela ne remplace pas le certificat Let’s Encrypt utilisé par Mailcow. On demande juste que le client présente un certificat émis par notre CA.

Pour cela il faut mettre en place une PKI et émettre un certificat client. J’utilise l’outil shellPKI pour ça.

ShellPKI

# cd /usr/local
# git clone https://forge.evolix.org/shellpki.git
# cd shellpki
# install -d -m 700 /etc/shellpki /etc/ssl/clients
# sed -i 's#/etc/openvpn/ssl#/etc/shellpki#g' openssl.cnf
# install -m 600 openssl.cnf /etc/shellpki/
# sed -i -e 's#PREFIX=.*#PREFIX=/etc/shellpki#' -e 's#WWWDIR=.*#WWWDIR=/etc/ssl/clients#' shellpki.sh

Éditer /etc/shellpki/openssl.cnf et initialiser shellPKI. Le plus important est de remplir le « Common Name », par exemple Myname Root Certificate.

# vim /etc/shellpki/openssl.cnf
# ./shellpki.sh init

On génère un certificat client (sans passphrase), soit un utilisateur par exemple. Il faudra choisir un « Common Name » du type user@domain.tld.

# ./shellpki.sh create

Puis on le convertit au format PKCS#12 avec une passphrase d’export. Cette passphrase sera demandé à l’import dans un navigateur ou smartphone par exemple.

# cd /etc/ssl/clients
# openssl pkcs12 -export -in user@mail.domain.tld.crt -inkey user@mail.domain.tld.key -out user@mail.domain.tld.p12

Il faudra importer ce certificat client dans les navigateurs et dans diverses applications (Thunderbird, Exchange/GMail sous Android, K9-Mail…).

La dernière étape consiste à dire à dovecot et nginx qu’il est nécessaire de présenter un certificat client.

Nginx

ssl_client_certificate /etc/shellpki/ca/cacert.pem;
ssl_verify_client on;
# systemctl restart nginx

Dovecot

Note : Attention, si vous avez un webmail qui se connecte en local, imap non chiffré, l’activation de auth_ssl_require_client_cert, va imposer d’utiliser un certificat… Cassant votre webmail. Il n’y a pas à ce jour la possibilité d’activer auth_ssl_require_client_cert seulement pour imaps… Si vous utilisez un webmail, n’activez pas ceci sur dovecot.

# Client certificate
ssl_ca = </etc/shellpki/ca/cacert.pem
ssl_verify_client_cert = yes
ssl_cert_username_field = commonName

protocol !smtp {
  auth_ssl_require_client_cert = yes
  auth_ssl_username_from_cert = yes
  auth_mechanisms = external
}
# systemctl restart dovecot.service

Vous devez maintenant faire le nécessaire côté client (Thunderbird, K9-Mail…)

Autres actions

Voici une liste de tâches non exhaustives à faire de votre côté que je ne documente pas, non obligatoire mais conseillé…

  • Monter un serveur de MX secondaire ;
  • Activer un pare-feu sur votre machine, par exemple ufw ;
  • Monitorer votre serveur ;
  • S’assurer du suivi des mises à jour ;
  • Faire des sauvegardes.