IMA5 2021/2022 P20

De Wiki de Projets IMA


Présentation générale

  • Nom du projet : SEMail: Système de messagerie global mais individualisé
  • Réalisé par : Souleymane SOW
  • Superviseur du projet : Xavier REDON
  • Durée : 06 SEP 2021 - 24 JAN 2022

Objectif

L’objectif du projet sera de mettre en place un système de messagerie qui va gérer plusieurs utilisateurs et une boîte à lettres par utilisateur. Le système devra permettre à chaque utilisateur d’avoir un contrôle important sur sa messagerie grâce à un système de conteneur par utilisateur. Afin d’éviter des failles de sécurité, la solution à mettre en place devra assurer un contrôle facile sur ses différentes composantes et cela grâce à sa simplicité.

Description

Au niveau global, le système de messagerie se compose des éléments suivants :

• une machine virtuelle qui va contenir le système de messagerie ;

• un serveur DNS permettra de gérer les enregistrements MX liés aux adresses de courriels ;

• un serveur Web permettra de créer de nouvelles boites pour chaque utilisateur et d’en supprimer ;

• un serveur SMTP accessible d’Internet permet de stocker les messages reçus par les utilisateurs locaux dans les systèmes de fichiers liés aux utilisateurs ;

• un serveur SMTP accessible uniquement de la machine virtuelle permet d’envoyer les courriels vers Internet ;

• pour chaque utilisateur un conteneur Docker sera créé.

"Architecture global du système de messagerie"

Au niveau individuel, chaque conteneur permet :

• un accès en lecture et écriture au système de fichiers dans lequel sont stockés les courriels pour cet utilisateur par le serveur SMTP entrant Storage;

• un accès SSH dans le conteneur en utilisant un rebond par la machine virtuelle VM SEMail ;

• un accès réseau au serveur SMTP sortant SendMail permettant d’envoyer des courriels ;

• la possibilité d’installer des logiciels comme des lecteurs de messagerie suivant le choix de l’utilisateur.


Dans un but de prévenir les failles, les deux serveurs SMTP sont écrits à partir de zéro en respectant les consignes suivantes :

• Respect de la RFC 5321 mais avec des simplifications (pas d’implantation des commandes VRFY et EXPN, pas de routage et avec un système optionnel de gestion des messages non transmis avec succès) ;

• écriture en langage C avec la bibliothèque des sockets ;

• utilisation de bibliothèques dynamiques pour la gestion des connexions, une méthode pour la connexion sans chiffrement (ports 25 et 587) et une méthode pour la connexion avec chiffrement (port 465), ne pas implanter la commande STARTTLS ;

• chaque connexion est gérée par un processus léger (Threads) ;

• utilisation de bibliothèques dynamiques pour la gestion des commandes SMTP, chaque commande est gérée par une fonction à laquelle est passée une structure représentant l’état du dialogue entre le client et le serveur ;

• prévoir un système optionnel pour le serveur SMTP sortant permettant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible ;

• gérer les enregistrements MX ainsi qu’IPv4 et IPv6 pour contacter les serveurs SMTP cibles ;

• les deux types de serveurs SMTP ne diffèrent que par la méthode de distribution finale (stockage dans un système de fichiers ou envoi à un serveur SMTP cible) ;


Le stockage des courriels doit se faire ainsi que décrit ci-dessous :

• le format de stockage doit être le format « mbox » ;

• chaque message entrant est ajouté au dossier de réception INBOX mais aussi à un dossier dont le nom est constitué de l’adresse de destination de l’enveloppe et de l’adresse source de l’enveloppe ;

• les courriels sont stockés dans un système de fichiers propre à l’utilisateur destination, ces systèmes de fichiers peuvent être implantés via des fichiers images ou via LVM ;

• les systèmes de fichiers contenant les courriels sont montés dans les conteneurs ad hoc.


Lors de la création d’une boîte aux lettres, les éléments suivants sont mis en place :

• précisons que l’utilisateur doit être identifié pour avoir le droit de créer son unique boîte aux lettres, cela se fera par un serveur LDAP, par défaut le serveur LDAP de la machine virtuelle est utilisé mais il doit être possible d’en utiliser un autre sur Internet ;

• soit l’utilisateur précise un nom de domaine externe pour son adresse de courriel auquel cas il doit insérer l’enregistrement MX lui même, soit il choisit un sous-domaine libre du domaine géré par le système, auquel cas le champ MX est ajouté automatiquement ;

• c’est l’utilisateur qui précise un identifiant pour son adresse de courriel qui vient compléter l’adresse Internet, le serveur SMTP entrant ne laissera passer que les courriels à destination de « id@domaine » ;

• le système de fichiers de stockage des courriels est créé avec une taille par défaut spécifié par l’administrateur et automatiquement formaté et peuplé ;

• le conteneur lié à l’adresse de courriel est créé automatiquement et lancé en mode persistant.


Un client de messagerie de type SquirrelMail est installé sur la machine virtuelle et permet aux utilisateurs qui ne veulent pas se compliquer la vie avec leur conteneur de gérer leur boîte aux lettres.

Préparation du projet

Cahier des charges

CahierDesChargesSEMail.pdf

Cahier des Spécifications

CahierDesSpecifications.pdf


Choix techniques : matériel et logiciel

Liste des tâches à effectuer

• Installation de la machine virtuelle de type Xen: Système d’exploitation Debian ou Devuan et SqWebmail comme système de messagerie

• Mis en place du serveur LDAP: Installation et remplissage de l’annuaire qui va contenir les utilisateurs de la messagerie

• Mis en place du serveur Web: Authentification des utilisateurs pour leur permettre de créer une nouvelle boîte unique et leur attribuer un conteneur de type Docker

• Programmation des 2 serveurs SMTP: Réalisé en langage C et avec la bibliothèque des sockets

• Configuration du serveur DNS: On utilisera le serveur DNS du réseau 172.26.145.0 de la salle informatique

• Tests: Après chaque tâche effectuée, des tests seront réalisés à la fin pour pouvoir être validés et passés à la tâche suivante

Calendrier prévisionnel

"Planning du projet"

Réalisation du Projet

Semaine 1

Systéme de messagerie

Un système de messagerie électronique est l'ensemble des éléments contribuant à transmettre un courriel de l'émetteur au récepteur. Il y a quatre éléments fondamentaux. Ce sont:
• le Mail Transfert Agent ou MTA
• le serveur du protocole entrant
• le Mail Delivery Agent ou MDA
• le Mail User Agent ou MUA
Les différents éléments du système de messagerie sont agencés selon une architecture logique, pour en assurer le fonctionnement. Nous représentons cette architecture par le schéma suivant:

"Architecture d'un systéme de messagerie"

Ce schéma présente le transfert d'un courriel d'un expéditeur à un destinataire.
1 - L'expéditeur communique son courriel via le MUA.
2 - Le MUA transmet ce courriel au MTA (la plupart des MUA intègre des clients SMTP).
3 et 4- Le MTA du système de l'émetteur établit un canal de transmission avec le MTA du système du destinataire, par émissions successives de requêtes bidirectionnelles .
5 - Une fois le canal établit, le courriel est transmis d'un système à un autre par les MTA.
6 - Dans le système du destinataire, Le MTA transmet le courrier reçu au serveur IMAP ou POP3.
7, 8 et 9 - Le MDA récupère le courriel du serveur IMAP / POP 3, et le met à disposition du MDA.
10 - Le MDA dépose le courriel dans la boîtes aux lettres du destinataire qui pourra le consulter à tout moment, sur authentification.

  • Mail Transfert Agent ou MTA

C'est un agent qui permet d'acheminer le courriel d'un serveur à un autre. Le MTA de l'émetteur route le mail sur le MTA du récepteur. Il implémente un protocole sortant. Notons que les protocoles sortants permettent de gérer la transmission du courrier entre les systèmes de messagerie. Le protocole sortant généralement utilisé est le Simple Mail Transfert Protocol ou SMTP .
SMTP peut être traduit comme protocole simple de transfert de courriel . Il est de la famille des protocoles basés sur TCP/IP. Il utilise généralement le port 25. Le mécanisme de fonctionnement de SMTP est qu'il commence d'abord par vérifier l'existence de l'expéditeur et du ou des destinataire (s), indiqués dans l'entête du message, puis il transmet le contenu. La transmission s'effectue sur un canal de communication établi entre l'émetteur et le destinataire par émission bidirectionnelle de requêtes basées sur des commandes. Il existe plusieurs serveurs MTA qui implémentent SMTP. Parmi les plus connus, il y a Postfix, Exim, Qmail et Sendmail.
Dans le cas de notre projet, on aura à coder en partant de zéro notre MTA qui sera un serveur SMTP en langage C en utilisant la bibliothéque des sockets.

  • Serveur du protocole entrant

Les protocoles entrants permettent la réception et la distribution du courriel. Les plus généralement utilisés sont : Post Office Protocol version 3 (POP3) et Internet Message Access Protocol (IMAP), qui sont tous deux basées sur TCP/IP . Dans son fonctionnement, POP3 va récupérer le courriel sur un serveur de messagerie.IMAP est une version améliorée de POP3.
Dans le cas de notre projet, notre serveur de protocole entrant sera un serveur SMTP qui va stocker les messages reçus au dossier de réception Maildir qui sera propre à chaque utilisateur.


  • Mail Delivery Agent ou MDA

Il s'agit d'un agent qui est en charge de la gestion des boîtes aux lettres . Il est chargé de livrer le courriel dans la boîte à messages du destinataire. Pour cela, il est souvent considéré comme le point final d'un système de messagerie . Dans le MDA , on peut filtrer les courriels; et même supprimer les spams par des anti-spams (comme spamassassin) et contrôler les virus par des antivirus. Il existe plusieurs serveurs MDA, les plus courants sont procmail, maildrop et cyrus.
Ici notre serveur SMTP de réception va jouer le role du MDA

  • Mail User Agent ou MUA

Le MUA est un logiciel client de messagerie qui fournit un environnement pour la gestion du courriel (envoi, saisie, réception, suppression, etc.). Il est très proche du MDA. Tout comme les autres agents, il existe également plusieurs MUA . Un MUA avec une interface Web, est appelé Webmail.
On utilisera SqWebmail pour la gestion de courriels par les utilsateurs.

Installation de la machine virtuelle avec Xen

  • Xen c'est quoi?

Xen est un logiciel de (para)virtualisation de type hyperviseur. Il permet donc de faire tourner plusieurs systèmes d'exploitation (OS) sur une même ressource matérielle (PC, Serveur,…). Xen permet de faire fonctionner plusieurs systèmes d'exploitation virtuels (invités) sur une seule machine hôte. Les choses ont beaucoup changé puisque le kernel Linux, à partir de la version 3, intègre nativement Xen. Le principe de l'hyperviseur est de faire tourner les OS dans le noyau (kernel) même, et non-pas de les émuler, ce qui permet de conserver des performances proches des natives.

  • Installation du paquet

On vérifie si les paquets Xen-Hypervisor et Xen-tools(Gestion des machines virtuelles) sont déja installés ou pas:

  sudo apt -qq list xen-hypervisor-4.11-amd64
  sudo apt -qq list xen-tools
"Vérification de l'installation de l'hyperviseur Xen sur la machine"

On voit que nos packets ne sont pas encore installés donc on les installe avec la commande:

  apt-get install xen-hypervisor-4.11-amd64 xen-tools

Pour configurer xen-tools, on édite /etc/xen-tools/xen-tools.conf qui contient les valeurs par défaut que le script xen-create-image utilisera. Pour donner un chemin différent où les images domU sont enregistrées et activer le mot de passe superutilisateur dans la construction initiale, nous allons éditer le fichier /etc/xen-tools/xen-tools.conf et décommenter ces lignes :

 dir=/home/xen
 passwd = 1

Ensuite, on peut créer notre machines virtuelle avec la commande :

  xen-create-image --hostname Webmail --bridge bridge --ip 172.26.145.230 --vcpus 2 --pygrub --dist buster

On a utilisé le bridge déja existant sur la machine hote pour l'accés réseau de notre machine virtuelle et on lui attribue une adresse ip appartenant au réseau de l'hote. Pour démarrer la VM créée, on exécute la commande :

  xl create /etc/xen/Webmail.cfg

Pour se connecter sur la console de notre vm on lance la commande:

  xen console Webmail
"Console de notre machine virtuelle créée"

Configuration de la machine virtuelle

Pour avoir accés aux autres réseaux on rajoute une route par défaut pour notre machine virtuelle:

   ip route add default via 172.26.145.254

Ensuite on fait une mis à jour de notre systéme:

    apt-get update && apt-get upgrade

Installation de l'annuaire LDAP

LDAP signifie Lightweight Directory Access Protocol. C’est le standard de fait pour accéder à un annuaire. Un annuaire est une base de données qui va contenir des informations sur des personnes, des machines, des groupes ou toute autre catégorie. Un annuaire se distingue d’une base de données relationnelle par le fait qu’il a une structure hiérarchique et qu’il est très rapide pour chercher et lire des éléments mais plus lent pour les modifier. Les annuaires sont couramment employés pour stocker les données d’authentification (login et mot de passe) ou pour obtenir des informations sur des personnes (email, téléphone, etc.) ou des objets (localisation, marque, modèle, etc.). Toutes les applications de votre entreprise (site web, e-mail, comptes système des ordinateurs, etc.) peuvent par exemple utiliser ce service d’annuaire pour valider les identifiants de connexion.

  • Comment ça fonctionne?

Tout d’abord, un annuaire LDAP est une organisation hiérarchique d’entrées. Cette organisation constitue un arbre appelé DIT (Directory Information Tree) dont une des entrées est la racine.

"Structure d'un annuaire LDAP"

Chaque entrée peut contenir des attributs auxquels on assigne des valeurs. Chaque entrée appartient au moins à une classe d’objet qui définit les attributs de l’entrée. Par exemple, la classe d’objet “Employés” pourrait définir qu’un “élément” appartenant à cette classe doit contenir les attributs obligatoires :
• nom de famille
• prénom
et peut contenir les attributs facultatifs :
• e-mail
• téléphone
• date de naissance
Chacun des attributs de cet élément aura une valeur. Par exemple, “nom de famille=Dupond”. De nombreux attributs et classes d’objets sont prédéfinis mais il est possible de définir les nôtres si besoin. L’ensemble des classes d’objets et attributs utilisés est défini dans le schéma. Certains attributs sont particulièrement courants et intéressants à connaître :

"Attributs et classes d'objets d'un annuaire LDAP"

Un attribut particulier est le dn (distinguished name), c’est à dire le nom distinct. C’est un attribut qui identifie de manière unique un élément dans le DIT. Il reprend les noms de tous les éléments depuis la racine jusqu’à l’élément et indique ainsi un “chemin” unique pour trouver l’élément.
Par exemple, le dn de “Marie Dupond” qui travaille chez “mon-entreprise.com” pourrait être “cn=Marie Dupond,ou=Personnes,dc=mon-entreprise,dc=com”. On appelle RDN, pour Relative Distinguished Name, la partie “finale” propre à Marie. Ici le RDN serait “cn=Marie Dupon”. Lui, ne garantit pas l'unicité dans le DIT.

  • Installation OpenLDAP:

OpenLDAP est un des annuaires les plus répandus. Pour l’installer, on doit installer le paquet slapd . Installez également le paquet ldap-utils qui contient les utilitaires clients pour pouvoir interroger ou modifier notre annuaire.

   sudo apt-get install slapd ldap-utils

Nous allons maintenant utiliser l’outil de configuration debconf de Debian pour définir la configuration de base de notre annuaire :

   dpkg-reconfigure slapd

Nous allons indiqué :
• No pour la première question afin de pouvoir utiliser l’outil de configuration
• pour nom DNS : semail.com
• pour nom d’organisation : semail
• le mot de passe administrateur x2
• No pour savoir si la base doit être supprimée quand slapd est purgé
• Yes pour déplacer l’ancienne base de données
Comme notre DNS est semail.com, la racine de notre DIT a été configurée à “dc=semail,dc=com”, nous pouvons utiliser la commande ldapsearch suivante pour visualiser notre DIT :

   ldapsearch -Q -L -Y EXTERNAL -H ldapi:/// -b dc=semail,dc=com
"DIT de notre annuaire"

La commande ldapsearch sert, comme son nom l’indique à chercher dans un annuaire LDAP. Voici le détail des options utilisées :
-Q active le mode silencieux pour l’authentification SASL
-Y indique le mode SASL choisi pour l’authentification. Normalement, EXTERNAL implique une authentification par certificat client mais dans ce cas là ça signifie que l’authentification se fera par l’UID et le GID du compte système. C’est pour ça que nous devons lancer la commande avec “sudo”. L’utilisateur root a des passe-droits pour accéder à la base locale LDAP
-L indique d’afficher le résultat au format LDIF. On aurait pu indiquer -LLL pour avoir la même chose sans toutes les lignes commentées.
-H indique l’URI qu’on veut utiliser pour se connecter. Ici ldapi:/// dit de se connecter à la socket Unix en local (la communication passe par un fichier local plutôt que par le réseau).
-b indique le nœud à partir duquel on veut faire notre recherche. Ici dc=semail,dc=com est la racine donc nous recherchons dans tout le DIT. À la suite du nœud, on aurait pu indiquer des filtres pour notre recherche mais sans filtre on a l’affichage le plus complet.

  • Format LDIF:

LDIF signifie “LDAP Directory Interchange Format”. C’est un format créé pour décrire les ajouts ou les modifications à réaliser dans un annuaire LDAP. Le format d’une entrée dans un fichier LDIF est toujours de la forme suivante :

"Format d'une entrée dans un fichier LDIF"

Dans la sortie de la commande précédente, on voit que notre DIT contient en tout et pour tout 2 entrées :
La première est la racine. On la reconnaît au fait qu’elle appartient à la classe d’objet dcObject. On voit qu’elle appartient aussi à 2 autres classes d'objets. Chacune décrit une série d’attributs que l’entrée peut ou doit contenir. On a ensuite deux attributs : o et dc , deux types que nous connaissons déjà.
La deuxième est le compte administrateur LDAP, comme l’indique l’attribut description . Il appartient notamment à la classe d’objet simpleSecurityObject qui représente les comptes d’authentification.

Gestion de l'annuaire LDAP

Notre annuaire contient un deuxième DIT! En effet, dans les anciennes versions de slapd, la configuration se faisait en modifiant des fichiers dans /etc/ldap/ et imposait de redémarrer le serveur pour être prises en compte. Cette méthode est toujours possible mais il est maintenant recommandé d’utiliser la nouvelle méthode dite de “configuration à chaud” (en anglais OLC pour On-Line Configuration) qui permet de ne pas avoir à redémarrer le serveur pour actualiser.

  • OLC
    ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config dn
"Entrées de l'arbre"

Cette configuration contient donc des informations sur les modules, le schéma, les classes d’objets intégrées par défaut. La configuration propre à notre DIT dc=semail,dc=com se trouve dans olcDatabase={1}mdb,cn=config
Comme cette configuration est stockée sous forme de DIT, on peut la modifier au moyen de fichiers LDIF. Pour tester ça, on va modifier la quantité de logs générée par slapd. Par défaut, slapd ne génère aucun log et nous aimerions peut-être avoir plus d’informations sur l’activité de notre serveur. L’attribut qui gère ça est directement un attribut de cn=config appelé olcLogLevel

"olcLogLevel désactivé"

Ici j’ai rajouté l’option -s base pour indiquer le scope , c'est-à-dire l’étendue de la recherche. base effectue la recherche uniquement au niveau du DN indiqué alors que par défaut le scope est subtree pour rechercher sur toutes les entrées inférieures également.

"Options lors d'une recherche"

On va faire passer le niveau de logs à stats . Ça générera peut-être beaucoup de messages mais ce sera parfait pour le débugage. Pour cela, enregistrons un fichier logLevel.ldif contenant :
dn: cn=config le DN à modifier
changetype: modify le type de modification de l’objet à effectuer
replace: olcLogLevel l’attribut à modifier
olcLogLevel: stats la nouvelle valeur de l’attribut
On peut appliquer ce changement par la commande :

   ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f logLevel.ldif

Les options sont les mêmes que pour ldapsearch sauf le -f qui indique le fichier LDIF à appliquer.
À partir de maintenant, notre serveur slapd va générer des logs mais ils seront renvoyés vers le fichier général /var/log/syslog. Pour indiquer au daemon rsyslog qui gère les logs d’avoir un fichier de log séparé, on va créer le fichier /etc/rsyslog.d/10-slapd.conf contenant :

  # Logs du serveur OpenLDAP slapd
  local4.* /var/log/slapd.conf

Puis on redémarre rsyslog par la commande :

    systemctl restart rsyslog

Ajout de nouveaux noeuds

Pour ajouter de nouveaux nœuds et de nouveaux utilisateurs à notre arbre, on va utiliser un fichier LDIF. Créons donc le fichier structure.ldif contenant :

   dn: ou=Personnes,dc=semail,dc=com
   objectclass: organizationalUnit
   ou: Personnes
   description: Utilisateurs de la messagerie
   dn: cn=Souleymane Sow,ou=Personnes,dc=semail,dc=com
   objectClass: inetOrgPerson
   givenName: Souleymane
   sn: Sow
   cn: Souleymane Sow
   uid: ssow
   userPassword: ssow

La structure du fichier est la même mais comme on rajoute plusieurs entrées, on doit sauter une ligne entre chaque DN. Ce fichier rajoute d’abord l’ ou  : une pour inventorier les utilisateurs. Il rajoute ensuite une personne avec la classe d’objet inetOrgPerson . On avait déjà vu les autres attributs, à l’exception du mot de passe à la fin (qui sera chiffré par slapd) et de l’ uid qui correspond au login ou à un uid numérique suivant l’usage qui est fait de ce champ.
On remarque aussi que dans ce fichier, on n’utilise pas l’attribut changetype pour préciser qu’il s’agit d’un ajout car nous allons utiliser la commande ldapadd qui précise ça par elle-même :

   ldapadd -x -W -D “cn=admin,dc=semail,dc=com” -H ldap://localhost -f structure.ldif

Par défaut l’utilisateur root système a les droits de modification sur le DIT cn=config mais pas sur notre DIT. Sauf à changer ces droits, nous devons donc passer par le compte administrateur de notre DIT. Voici le détail des options:
-x  : indique une authentification simple par mot de passe
-W  : affiche une invite interactive pour taper le mot de passe du compte
-D  : pour indiquer le DN du compte à connecter
-H  : indique toujours la méthode de connexion choisie mais cette fois-ci ldap://localhost initie une connexion par le réseau sur le port TCP 389.
Pour ajouter plus d'utilisateurs, on va mettre en place un script SHELL addldap.sh pour créer plus facilement et plus rapidements de nouveaux utilisateurs et remplir notre annuaire.

#!/bin/bash
if [ $# = 0 ];
then   echo "Usage: ./addldap nom_fichier_ldif"
      exit
fi
touch $1.ldif
trap "ldapadd -x -W -D "cn=admin,dc=semail,dc=com" -H ldap://localhost -f $1.ldif && exit " 2 3
while [ 1 ];
do
   echo "prenom nom uid"
   read prenom nom uid 
   if [ $? -eq 0 ]; 
   then
       echo "dn: cn=$prenom $nom,ou=Personnes,dc=semail,dc=com
objectClass: inetOrgPerson
givenName: $prenom
sn: $nom
cn: $prenom $nomuid: $uid
userPassword: $uid 
">>$1.ldif
    cat $1.ldif
   fi
done

Migration de notre machine virtuelle sur le serveur Brisban

Pour des raisons de sécurité et de disponibilité de notre infrastructure, on va migrer notre machine virtuelle déja crée sur le serveur Brisban.
On a crée d'abord un nouveau fichier de configuration /etc/xen/webmail_P20.cfg et on copie le contenu du fichier de configuration de notre machine virtuelle avant de le modifier pour l'adapter au nouveau hote de destination Brisban.

#
# Configuration file for the Xen instance Webmail, created
# by xen-tools 4.8 on Mon Oct  4 16:55:25 2021.
#
#
#  Kernel + memory size
#
bootloader = 'pygrub'
vcpus       = '2'
memory      = '256'
#
#  Disk device(s).
#
root        = '/dev/xvda2 ro'
disk        = [  
                 'file:/usr/local/xen/domains/Webmail/disk.img,xvda2,w',
                 'file:/usr/local/xen/domains/Webmail/swap.img,xvda1,w',
             ]
#
#  Physical volumes
#
#
#  Hostname
#
name        = 'webmail_P20'
#
#  Networking
#
 vif         = [ 'mac=00:16:3E:F5:AD:B8,bridge=alternateBridge' ]
#
#  Behaviour
#
on_poweroff = 'destroy'
on_reboot   = 'restart'
on_crash    = 'restart'

Ensuite on copie notre fichier de stockage /usr/local/xen/domains/webmail dans notre nouveau répertoire de stockage dans Brisban /usr/local/xen/domains/webmail_P20. On crée ensuite notre machine virtuelle qui est ainsi dupliquée avec la commande:

   xl create /etc/xen/webmail_P20.cfg

On peut ainsi utiliser notre machine virtuelle qui est dorénavant sur le serveur Brisban. On procéde ensuite à la configuration réseau et on va pouvoir bénéficier d'une adresse IP routée. Ensuite on supprime les configurations des proxys avec la commande unset {http,https}_proxy et sur les fichiers /etc/apt/apt.conf. Puis on configure le DNS dans /etc/resolv.conf.

Authentification LDAP pour l'accés à notre serveur web

On installe d'abord notre serveur Web Apache. Ensuite on édite le fichier de configuration d'apache2, afin d'autoriser les fichiers .htaccess, sur l'ensemble du serveur web (depuis sa racine) :

   nano /etc/apache2/apache2.conf
"Configuration de l'apache pour autoriser .htaccess"

On changer la valeur de None -> All, afin que les fichiers .htaccess/.htpasswd soient pris en compte !
On procéde ensuite à l'activation du mode LDAP pour apache2 avant de redémarrer notre service apache:

    a2enmod authnz_ldap 
    systemctl restart apache2

On crée un dossier test/ à la racine de notre serveur web, afin de procéder aux différents tests :

    mkdir /var/www/html/test
    chown www-data:www-data /var/www/html/test -R

On crée un fichier d'exemple et le fichier .htaccess. Nous allons éditer celui-ci par la suite :

     cd /var/www/html/test
     touch file.txt
     touch .htaccess
  • Authentification avec LDAP

Nous allons créer 3 fichiers pour mettre en place un formulaire d'authentification avec html et php-ldap : login.php verification.php principale.php Dans notre fichier login.php on va mettre en place notre formmulaire pour récupérer le login et le mot de passe que l'on va vérifier dans verification.php si l'utilsateur appartient à notre annuaire ldap. Si c'est le cas il accédera à la page principale.php qui sera la page ou il pourra céer une nouvelle boite mail sinon on lui renvoie au niveau du formulaire d'authentification.

"Page d'authentification"

Semaine 2

Résolution du problème d'authentification

On a rencontré un problème lors des tests d'authentification. En effet lorsqu'on essaye de s'authentifier avec les utilisateurs crées avec le script SHELL, l’accès est refusé surement parce qu'il n'arrive pas à retrouver les utilisateurs dans l'annuaire. Mais lorsqu'on vérifie au niveau de la base de données LDAP avec la commande LDAPSEARCH on retrouve bien ces utilisateurs. Il n'y a que l'utilisateur initial crée avec le premier fichier LDIF qui arrive à se connecter.

Le problème a pu être résolu en réinstallant le serveur ldap et lors de a création des utilisateurs, pour chaque fichier LDIF on attribue une entrée de l'annuaire. Le problème était lié aux droits d’accès des utilisateurs crées dans un même fichier LDIF. En effet, il n'y avait que le premier utilisateur qui avait accès en recherche à l'annuaire par contre les autres voyaient leur accés refusé.

Création ou Suppression d'une boite aux lettres

Pour savoir si l'utilisateur a déja une boite aux lettres, j'effectue une recherche dans le fichier texte maibox.txt. Ce fichier contient tous les identifiants et adresse de courriel des utilisateurs ayant déja crée leur boite et il a été crée au préalable.
Pour la création d'une boite, on va demander à l'utilisateur via un formulaire de renseigner son identifiant de courriel et son nom de domaine. S'il choisit un domaine autre que semail.com il devra renseigner l'enregistrement MX du domaine choisi. On va éditer le fichier mailbox.txt pour renseigner les informations (uid + mail) de l'utilisateur et le fichier mxrecord.txt pour renseigner l'enregistrement MX des utilsateurs qui choisissent un nom de domaine différent.

"Page de création d'une nouvelle boite de courriels"
"Page de suppression d'une boite de courriels"

Mise en place du systéme de stockage des filesystems des utilisateurs

On dispose d'une partition xvdb1 de 100Go sur notre machine virtuelle qu'on va utiliser pour le stockage des systémes de fichiers qui seront implantés avec LVM.
On va installer d'abord le paquet lvm2 avec
apt-get install lvm2
Ensuite on initie notre volume physique avec notre partition xvdb1 avec la commande
pvcreate /dev/xvdb1
Cela nous permettra de l'utiliser dans notre groupe de volume mvg
vgcreate mvg /dev/xvdb1
On dispose maintenant d'une Volume Group contenant notre disque physique.
Pour nos volumes logiques, ils seront crées lors de la création d'une nouvelle boite grace à un script SHELL qui s'éxécute toutes les minutes et avec une taille fixe 5G. Ensuite on montera le répertoire de l'utilsateur sur son volume logique.
On va créer le repertoire /home/Personnes qui contiendra les répertoires de nos utilisateurs. On aura pour chaque utilisateur son répertoire /home/Personnes/son_uid.
Notre script vérifie si tous les utilisateurs qui ont crée une nouvelle boite ont deja leur systéme de fichier sinon on le crée:

#!/bin/bash
while true
do
   #On parcoure les utilisateurs on verifie si tous les utilisateurs ont un systeme de fichier pret
   #En verifiant s'il y a un repertoire /home/Personnes/son_uid existe
   nohup cat mailbox.txt | grep "uid" | cut -f2 -d ' ' > users.txt
   #Variable du fichier
   users="users.txt"
   #initialisation du compteur a 0
   i=0
   while IFS= read -r ligne; do
      echo "done"
      if [ -d /home/Personnes/ligne ]; then
         nohup echo "$ligne a deja un systeme de fichier"
      else
         nohup lvcreate -n Vol$ligne -L 5G mvg
         nohup mkfs -t ext4 /dev/mvg/Vol$ligne
         nohup mkdir /home/Personnes/$ligne
         nohup mount /dev/mvg/Vol$ligne /home/Personnes/$ligne
      fi
      i=$(($i+1))
    done < "$users"
    nohup sleep 60

done

Script de création de conteneur des utilisateurs

Aprés avoir monté le repertoire de l'utilisateur dans son volume logique correspondant lors de la création d'une nouvelle boite, on va éxecuter le script de création du conteneur de cet utilisateur. On utilisera Docker comme solution de conteneurisation donc on va commencer par installer son paquet. Ensuite notre script devra éditer un fichier Dockerfile pour chaque utilisateur qui sera stocké dans /home/Containers/uid_user.
Le script se comporte de la meme maniere que le script de création des systémes de fichiers des utilisateurs.

#!/bin/bash
while true
do
#On parcoure les utilisateurs on verifie si tous les utilisateurs ont un conteneur
#En verifiant s'il y a un repertoire /home/Containers/son_uid existe
nohup cat mailbox.txt | grep "uid" | cut -f2 -d ' ' > users.txt
#Variable du fichier
users="users.txt"
#initialisation du compteur a 0	
i=0
while IFS= read -r ligne; do
   if [ -d /home/Containers/ligne ]; then
      nohup echo "$ligne a deja un conteneur"
   else
      nohup mkdir /home/Containers/$ligne
      nohup touch /home/Containers/$ligne/Dockerfile
      nohup mkdir /home/Personnes/$ligne/Maildir
      nohup echo "FROM debian
      RUN apt-get update -yq
      RUN apt install -y openssh-server
      RUN mkdir /Maildir
      WORKDIR /Maildir">/home/Containers/$ligne/Dockerfile
      img="_img"
      container="_container"
      docker build -t $ligne$img /home/Containers/$ligne/
      docker run -i -d --name $ligne$container -v /home/Personnes/$ligne/Maildir:/Maildir $ligne$img
   fi
   i=$(($i+1))
   done < "$users"
   sleep 60
done

Semaine 3 & Semaine 4 & Semaine 5 & Semaine 6

Installation et configuration du serveur DNS

On achéte d'abord notre nom de domaine:semail.email sur Gandi.net On va utiliser bind 9. On procéde à son installation :

   apt-get install bind9

Les fichiers de configuration de Bind se trouvent dans le répertoire /etc/bind/. On y trouve notamment le fichier db.root, qui contient les adresses IP des serveurs DNS racines (i.e. les serveurs centraux du système DNS), et le fichier named.conf qui est le fichier de configuration principal de Bind.

On configure /etc/resolv.conf

nameserver 127.0.0.1

On configure ensuite bind avec le fichier /etc/bind/named.conf.local

 zone "semail.email" {
        type master;
        file "/etc/bind/db.semail.email";
 };

On ajoute nos ns dans le fichier /etc/bind/db.semail.email:

$TTL 604800
@	IN	SOA	ns1.semail.email. root.semail.email. (
                           2	;Serial
                           604800	;Refresh
                           86400	; Retry
                           2419200		; Expire
                           604800 )	; Negative Cache TTL
	IN	NS	ns1.semail.email.
	IN	NS	ns6.gandi.net.
	IN	MX	100	ns1.semail.email.
ns1	IN	A	5.23.44.85

Codage de nos deux serveurs SMTP

Qu’est-ce que le protocole SMTP ?

SMTP est l’abréviation de « Simple Mail Transfer Protocol », ce qui peut se traduire en français par « protocole simple de transfert de courrier ». Il s’agit d’un protocole réseau texte orienté connexion de la famille des protocoles Internet et à ce titre situé sur la septième couche du modèle OSI. Comme tout autre protocole réseau, il contient des règles pour une communication correcte entre les ordinateurs d’un réseau. SMTP est spécifiquement responsable de l’envoi et de la transmission des emails d’un expéditeur à un destinataire.

Comment fonctionne le processus SMTP ?

Le processus se déroule en principe comme suit :

  • Le client SMTP, c’est à dire l’expéditeur, télécharge l’email sur le serveur SMTP, c’est à dire le serveur d’email sortant du fournisseur de messagerie correspondant. Ceci s’effectue via une application Webmail dans le navigateur ou un programme de messagerie (techniquement un « Mail User Agent » abrégé en MUA).
  • Le serveur SMTP contacte alors le serveur DNS, qui recherche l’adresse IP du serveur SMTP cible (également appelé « Mail Delivery Agent », MDA en abrégé), qui est stockée pour l’adresse du destinataire du message.
  • Le serveur SMTP envoie l’email via un ou plusieurs « Mail Transfer Agents » (MTA) au serveur SMTP cible. Chacune de ces opérations de transfert est effectuée selon le protocole SMTP.
  • Le serveur SMTP de destination (cible) stocke temporairement l’email dans le stockage temporaire d’email.
  • Le destinataire MUA télécharge l’email

Le transfert d’un email du client SMTP via le serveur vers le stockage email du serveur SMTP cible est contrôlé par le protocole SMTP. Ce n’est qu’après cela que d’autres protocoles réseau prennent effet.

Comment fonctionne une session SMTP ?

Chaque session se compose d’une séquence de commandes SMTP provenant du client et de réponses sous forme de codes d’état provenant du serveur.

  • Vue d'ensemble des commandes SMTP

Selon les spécifications SMTP applicables, chaque implémentation du protocole réseau doit prendre en charge au moins les huit commandes suivantes constituées de caractères ASCII 7 bits :
HELO : « Hello »– Le client se connecte avec son nom d’ordinateur et démarre la session avec le serveur
MAIL FROM: Le client nomme l’expéditeur de l’email.
RCPT TO: « Recipient » – Le client nomme le destinataire de l’email.
DATA: Le client initie la transmission de l’email.
RSET: Le client interrompt la transmission initiée, mais maintient la connexion entre le client et le serveur.
VRFY/EXPN: « Verify »/ « Expand » – Le client vérifie si une messagerie est disponible pour la transmission du message.
NOOP: Le client demande une réponse du serveur pour éviter une déconnexion due à un délai d’attente.
QUIT: Le client termine la session.
Les commandes STARTTLS(permet le cryptage des messages), VRFY/EXPN ne seront pas implémentées.

Codage de nos deux serveurs

Dépot git: https://archives.plil.fr/ssow/Semail.git

Last update

La boucle sendmail et celle de stockage ne tournent plus dans des threads et on ajoute un usleep de 100 ms pour réduire considérablement la charge sur la machine

Test de fonctionnement du systéme de messagerie

Aprés avoir codé nos deux serveurs SMTP, on va procéder au test de fonctionnement de mail entre deux utilisateurs du domain semail.email.
On va lancer notre serveur sortant SMTP en local sur le port 25 et notre serveur entant SMTP sur l'adresse IP routé de notre VM: 5.23.44.85 et sur le port 25 aussi.
On va utiliser netcat pour simuler notre client de messagerie et on le lancera en local sur le port 25.

"Client d'envoi de mail"
"Serveur SMTP Sortant"
"Serveur SMTP Entrant"
"Message recu dans le systeme de fichier du client destinataire"

On vérifie ensuite si on peut lire le mail à partir du conteneur du destinataire:

"Message recu dans le conteneur Docker du client destinataire"


On note que le systéme de messagerie fonctionne bien pour un envoi de mail entre deux clients du domaine semail.email. On va ensuite tester pour l'envoi vers ou d'un client appartenant à un domaine différent. Pour cela il nous faut créer le client et renseigner l'enregistrement MX de son domaine pour que notre serveur SMTP sortant puisse connaitre l'adresse de destination du mail.
On a pu effectuer ces tests et on a réussi a envoyer et recevoir un mail entre un utilisateur de notre domaine local et un utilisateur de la messagerie de Polytech-Lille:

"Reception d'un mail provenant d'un utilisateur de la messagerie Polytech Lille"
"Mail envoyé à un utilisateur de la messagerie Polytech Lille"

Installation de Sqwebmail

On a d'abord essayé d'installer via l'utilitaire apt mais on a pas trouvé la documentation pour installer le paquet pour pouvoir lancer le client de messagerie c'est pourquoi on a installé l'archive sqwebmail-6.0.6.20211128 directement avec un wget. Et dans le répertoire on trouve le fichier INSTALL qui est la documentation et qui nous donne la marche à suivre pour configurer sqwebmail.
On désarchive le paquet ensuite on rentre dans le répertoire pour commencer la configuration en spécifiant le répertoire ou se trouve nos éxécutables cgi-bin pour qu'il y installe l'éxécutable sqwebmail:

 /configure --enable-cgibindir=/var/www/cgi-bin/ --with-notice=unicode

Ensuite on lance la compilation des programmes:

 make configure-check #On vérifie s'il a bien choisi notre répertoire cgi-bin
 make
 make check
 make install-strip     
 make install-configure

Ensuite on active le module cgid sur apache:

a2enmod cgid

Ensuite on modifie notre fichier de configuration /etc/apache2/sites-availables/001-default.conf pour ajouter le site pour accéder à sqwebmail sur le port 8080 de notre machine:

<VirtualHost *:8080>
  ServerName 5.23.44.85
  ServerAdmin webmaster@localhost
  ScriptAlias /cgi-bin/sqwebmail /var/www/cgi-bin/sqwebmail
  #DocumentRoot /usr/lib/sqwebmail/share/sqwebmail/webmail.semail.email
  <Directory "/var/www/cgi-bin">
    Options +FollowSymLinks
    AllowOverride all
    Require all granted
    SetEnv SQWEBMAIL_TEMPLATEDIR "/usr/lib/sqwebmail/share/sqwebmail/sqwebmail"
    Setenv SQWEBMAIL_IMAGEURL "/sqwebmail"
   </Directory>
   ErrorLog ${APACHE_LOG_DIR}/sq-error.log
   CustomLog ${APACHE_LOG_DIR}/sq-access.log combined
</VirtualHost>

On reload notre apache2:

service reload apache2

Lorsqu'on se connecte sur le site via l'adresse: 5.23.44.85:8080/cgi-bin/sqwebmail on a obtient la page d'authentification du client de messagerie suivante:

"Page d'authentification sqwebmail"

Il reste juste à configurer le sqwebmail pour qu'il s'authentifie via l'annuaire ldap et non via PAM.

Documents Rendus

Rapport_projet_semail_ssow.pdf
Presentation_projet_semail_ssow.pdf