Suivi en détail de l’installation sur un serveur du service mail et des interfaces web d’administration et de webmail.
Et comme un beau dessin vaut mieux qu’un long discours, voici l’infrastructure expliquée.
Ma configuration server:
- server example.com
- service nginx (443 + 80) avec les certificats letsencrypt sur le domaine
- multiples web configurations
- docker
- mariadb
- mailu docker compose
- mailu_nginx
- mailu_imap
- mailu_smtp
- mailu_…
- service nginx (443 + 80) avec les certificats letsencrypt sur le domaine
Pré-requis
Avant toute chose, nous avons besoin de préparer quelques données.
- Hostname: example.com
DB:
- host: IP à récupérer après la création
- nom de la base de donnée: mailu
- nom de l’utilisateur: mailu
- mot de passe de l’utilisateur: mailu_db_password (il faudra être créatif ici)
- nom du réseau pour la db: mariadb_internal
Le répertoire d’installation de mailu: /opt/mailu
Je vais considérer que la machine hôte est une debian 10 pour plus de facilités mais ça marchera pour tout système qui fonctionne avec des .deb (ubuntu …)
Sur la machine hôte il faut aussi installer docker et docker-compose (voir référence en bas) et enfin il faut ouvrir les ports, comme certaine machine sont protégée par la société qui s’occupe du hosting et d’autres le sont avec iptable en interne
MariaDB
Tout d’abord créer la docker mariadb, la base de données, les utilisateurs et récupérer l’adresse ip.
Mais avant tout créons le réseau avec lequel sera connecté la base de donnée
sudo docker network create mariadb_internal
Code language: Bash (bash)
Maintenant nous pouvons créer la docker mariadb
sudo docker run --net mariadb_internal --name mariadb -e MARIADB_ROOT_PASSWORD=******** -d mariadb:latest
Code language: Bash (bash)
Remplacer les * par le mot de passe root et ensuite on test l’installation
docker run -it --network mariadb_internal --rm mariadb mysql -hmariadb -uroot -p
Code language: Bash (bash)
Vous devriez arriver dans un terminal mysql
On va en profiter pour créer la base de donnée et un utilisateur qui a les droits complet sur cette base de donnée.
CREATE DATABASE mailu;
CREATE USER 'mailu'@'%' IDENTIFIED BY '************';
GRANT ALL PRIVILEGES ON mailu.* TO 'mailu'@'%';
FLUSH PRIVILEGES;
Code language: SQL (Structured Query Language) (sql)
Et ensuite récupérer l’adresse ip de la docker, plusieurs possibilités la plus facile est d’examiner la docker.
sudo docker inspect mariadb | grep IPAddress
Code language: Bash (bash)
Ici je récupère l’adresse 172.19.0.5 que je vais utiliser dans la suite de ce document.
Mailu
La configuration par défaut est d’avoir le serveur nginx de mailu qui adresse l’ensemble des requêtes et s’occupe du chiffrement avec les certificats SSL récupérés sur let’s encrypt.
Comme il y a déjà un serveur nginx en front il va falloir faire des aménagements.
La documentation de mailru docker compose est assez claire. Je vais donc reprendre à partir de là et expliquer les changements.
Tout d’abord suivre le wizard pour créer les fichiers de configuration:
- docker-compose.yml
- mailu.env
Le plus simple est de les récupérer via wget:
cd /opt/
mkdir mailu
wget https://setup.mailu.io/1.8/file/<<some unique uuid>>/docker-compose.yml
wget https://setup.mailu.io/1.8/file/<<some unique uuid>>/mailu.env
Code language: Bash (bash)
Dans le fichier mailu.env les aménagements sont les suivants:
Ajouter la liste des domaines qui seront utilisés pour créer les certificats letsencrypt et qui assurerons la couche sécurisée dans les échanges imap et smtp
# Hostnames for this server, separated with comas
HOSTNAMES=<strong>smtp.example.com,mail.example.com</strong>
Code language: Bash (bash)
Bien entendu sélectionner mail-letsencrypt comme système de certification pour TLS
# Choose how secure connections will behave (value: letsencrypt, cert, notls, mail, mail-letsencrypt)
TLS_FLAVOR=mail-letsencrypt
Code language: Bash (bash)
Configurer le compte par défaut
INITIAL_ADMIN_ACCOUNT=admin
INITIAL_ADMIN_DOMAIN=example.com
INITIAL_ADMIN_PW=thisismypasswordinclear:-)
Configurer les accès DB pour l’ensemble des dockers et pour roundcube si vous installez le webmail roundcude
###################################
# Database settings
###################################
DB_FLAVOR=mysql
DB_USER=mailu
DB_PW=mailu_db_password
DB_HOST=<strong>172.19.0.5</strong>
DB_NAME=mailu
ROUNDCUBE_DB_USER=mailu
ROUNDCUBE_DB_PW=mailu_db_password
ROUNDCUBE_DB_NAME=mailu
Code language: Bash (bash)
Dans le fichier docker-compose.yml adapter les ports (enlever 443 qui ne sert à rien ici vu que le HTTPS est géré par l’auter nginx et mapper le 8081 –> 80 ça nous permettra de créer l’entrée dans le nginx de l’hôte)
ports:
- "::1:8081:80"
- "10.52.16.225:25:25"
- "::1:25:25"
- "10.52.16.225:465:465"
- "::1:465:465"
- "10.52.16.225:587:587"
- "::1:587:587"
- "10.52.16.225:110:110"
- "::1:110:110"
- "10.52.16.225:995:995"
- "::1:995:995"
- "10.52.16.225:143:143"
- "::1:143:143"
- "10.52.16.225:993:993"
- "::1:993:993"
Code language: YAML (yaml)
Vous voyez ici la convention ipv6 utilisée: ::1… on en aura besoin dans le port forwarding dans le nginx de l’hôte.
Ensuite on va créer le lien entre le réseau de mailu et le réseau mariadb.
networks:
default:
driver: bridge
ipam:
driver: default
config:
- subnet: 192.168.203.0/24
mariadb-internal-network:
external:
name: mariadb_internal
Code language: YAML (yaml)
Enfin on donne accès aux deux serveurs web au réseau mariadb
admin:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-1.8}
restart: always
env_file: mailu.env
volumes:
- "/mailu/data:/data"
- "/mailu/dkim:/dkim"
depends_on:
- redis
networks:
- default
- mariadb-internal-network
Code language: YAML (yaml)
webmail:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}roundcube:${MAILU_VERSION:-1.8}
restart: always
env_file: mailu.env
volumes:
- "/mailu/webmail:/data"
depends_on:
- imap
networks:
- default
- mariadb-internal-network
Code language: YAML (yaml)
Maintenant on teste le tout
sudo docker-compose up
Code language: Bash (bash)
Et si c’est bon on peut l’installer en tant que service
Installation du service docker compose mailu
Création du fichier décrivant le service
sudo vim /lib/systemd/system/docker-compose-mailu.service
On précise que ce service se lance après le docker service, on précise le répertoire de travail et le chemin absolu de docker-compose
# Mailu docker images for webmail & mail admin
[Unit]
Description=Docker Compose Mailu Service
Requires=docker.service
After=docker.service
[Service]
WorkingDirectory=/opt/mailu
ExecStart=/usr/bin/docker-compose up
ExecStop=/usr/bin/docker-compose down
TimeoutStartSec=0
Restart=on-failure
StartLimitIntervalSec=60
StartLimitBurst=3
[Install]
WantedBy=multi-user.target
Code language: Bash (bash)
Ensuite on rajoute ce service au service démarré par le système et on le démarre une première fois
sudo systemctl enable docker-compose-mailu.service
sudo systemctl start docker-compose-mailu.service
Code language: Bash (bash)
Nginx du serveur hôte
Dernière étape configurer le serveur nginx de l’hôte pour laisser passer le webmail et l’admin mail ainsi que les sous-domaines smtp et mail vers le mailu_nginx.
Dans le fichier de domaine site-enabled/mywebsite créer un upstream pour le mailu_nginx
upstream mailu {
server [::]:8081 weight=100 max_fails=5 fail_timeout=5;
}
Code language: Nginx (nginx)
Ensuite configurer le pass sur le domaine principal
server {
listen 443 ssl; # managed by Certbot
listen [::]:443 ssl; # managed by Certbot
listen 80;
listen [::]:80;
ssl on;
server_name example.com www.example.com;
...
location /webmail {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_pass http://mailu/webmail;
sub_filter '"http://mailu/webmail' '"/';
sub_filter_once off;
}
location /admin {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_pass http://mailu/admin;
sub_filter '"http://mailu/admin' '"/';
sub_filter_once off;
}
...
}
Code language: Nginx (nginx)
Et finalement configurer le pass sur les sous-domaines smtp et mail
server {
listen 80;
listen [::]:80;
server_name mail.example.com;
server_name smtp.example.com;
access_log /var/log/nginx/mail.sbw.be.access.log;
error_log /var/log/nginx/mail.sbw.be.error.log;
location / {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_pass http://mailu/;
sub_filter '"http://mailu/' '"/';
sub_filter_once off;
}
}
Code language: Nginx (nginx)
Et voilà!
Il ne reste plus qu’a tester et redémarrer nginx
sudo nginx -t && sudo systemctl restart nginx
Code language: Bash (bash)
Références