P9 Système d'hébergement domestique
Sommaire
- 1 Cahier des charges
- 2 Suivi de l'avancement du Projet
- 2.1 Semaine 1 (21/09/2015)
- 2.2 Semaine 2 (28/09/2015)
- 2.3 Semaine 3 (05/10/2015)
- 2.4 Semaine 4 (12/10/2015)
- 2.5 Semaine 5 (19/10/2015)
- 2.6 Semaine 6 (26/10/2015)
- 2.7 Semaine 7 (02/11/2015) - Architecture du système de fichiers
- 2.8 Semaine 8 (09/11/2015) - Postfix et filtrage
- 2.9 Semaine 9 (16/11/2015)
- 2.10 Semaine 10 (23/11/2015)
- 2.11 Semaine 11 (30/11/2015)
- 2.12 Semaine 12 (07/12/2015)
- 2.13 Semaine 13 (14/12/2015)
- 2.14 Semaine 14 (04/01/2016)
- 2.15 Semaine 15 (11/01/2016)
- 2.16 Semaine 16 (18/01/2016)
- 2.17 Semaine 17 (25/01/2016)
- 2.18 Semaine 18 (01/02/2016)
- 2.19 Semaine 19 (08/02/2016)
- 2.20 Semaine 20 (15/02/2016)
- 2.21 Semaine 21 (22/02/2016)
- 3 Fichiers Rendus
Cahier des charges
Présentation générale du projet
Contexte
Les gens font confiance à des organismes comme google pour gérer leurs courriels, voire pour les protéger. Il n'est pas évident que leur confiance soit bien placée. Ce projet doit permettre à tout utilisateur de créer quelques comptes de messagerie sur une système embarqué de type raspberry et permettre de conserver les données à la maison.
Le système doit être constitué à base de standards (base LDAP, serveur de messagerie connu et maintenu, client de messagerie idem). L'interface d'administration doit être elle aussi très simple d'utilisation.
Un effort particulier doit être porté sur l'alimentation du système embarqué. L'idéal serait un mode de veille lorsqu'aucun paquet TCP/IP n'est adressé à la machine. Il est aussi demandé de mettre au point une alimentation à base d'énergie renouvelable (e.g. panneau solaire) permettant d'alimenter totalement ou partiellement le système. Enfin pour permettre de se passer de la box grande consommatrice d'énergie, le système embarqué doit pouvoir en reprendre les fonctionnalités principale (connexion avec le DSLAM, redirection des ports UDP/TCP, ...).
Objectif du projet
L'objectif est de réaliser un système embarqué avec une alimentation autonome pour héberger une messagerie électronique domestique. Par domestique, il faut comprendre pour une dizaine de boites aux lettres. En outre, le système devra pouvoir être alimenté par un panneau solaire ou, le cas échéant, prendre relai sur le secteur lorsque l'alimentation fournie par le soleil n'est plus suffisante.
Description du projet
Choix techniques : matériel et logiciel
Matériel obtenu à ce jour :
- 1 Raspberry Pi 2 [obtenue le 07/10/2015]
- 1 Carte µSD 8 GB [obtenue le 07/10/2015]
- 1 Cable USB/µUSB [obtenu le 07/10/2015]
- 1 Câble RJ45 [obtenu le 07/10/2015]
Suivi de l'avancement du Projet
Semaine 1 (21/09/2015)
Notre but étant la réalisation d'une messagerie électronique domestique capable de gérer une dizaine de boites aux lettres, nous nous orientons dans un premier temps sur les points suivants que nous allons éclaircir afin d'en tirer un cahier des charges.
Nous allons étudier et approfondir les points suivants :
- Installer une base LDAP, ou avoir plutôt avoir plusieurs comptes UNIX
- Installer un serveur de messagerie SMTP, et IMAP/POP
- Investiguer du côté de POSTFIX
- Étudier la taille d'un mail vide, et en moyenne, et voir combien ça fait par rapport au système
- Enquêter sur la forme des fichiers utilisateurs (généraliser les données)
Ce qui doit pouvoir être fait :
- Distinction administrateur / utilisateur
- Un administrateur doit pouvoir gérer les comptes de messagerie (addition/suppression/etc)
- Gestion des quotas/espace disque réservé par ex
- Choix du quota (par qui ? options ?)
- SECURISER : apache, mod_security, étudier l'utilisation d'un pare-feu logiciel ?
Prévision du Matériel :
- Raspberry Pi 2
- Alimentation RPi
- Carte SD (8Go)
Le module énergétique sera équipé des éléments suivants :
- 1 MPPT
- Convertisseur Numérique Analogique : MAX5250
- Potentiomètre : MCP4261
- Relai : R561D.56 NTE
- Résistances : Deux de 100Ω et deux de 10kΩ
- une LED
- 40 pins broches mâle/mâle (Digikey Parts : A26509-40-ND), découpé par la suite en 8-8-6-4
- Circuit d'alimentation autonome : cellule photovoltaique
- Circuit d'alimentation autonome : batterie (avec port micro-USB et port USB)
Semaine 2 (28/09/2015)
Dans un premier temps l'idée est de développer le système principal avec les fonctionnalités. Autrement dit les différents packages et fonctionnalités installées sur la raspberry ainsi que l'interface utilisateur sur le site web. Dans cette partie nous listerons les différentes fonctionnalités que nous aimerions implémenter.
☐ Serveur SMTP (communications entre serveurs mails SMPT) et serveur IMAP/POP3 (postier)
- Postfix pour SMTP
- Dovecot, Courier ou Cyrus pour IMAP/POP3
- Implémentation de protocoles plus complexes et offrant notamment des fonctionnalités de chiffrement (SMTPS / ESMTP / SSL / HTTPS / Certificat)
- LMTP
☐ Gestion particulière des gros mails et notamment de leurs pièces jointes
- Bigfile pour un stockage en ligne
- Décodage base 64 des pièces jointes ? (difficulté++)
☐ Gestion des utilisateurs
- Plusieurs comptes, en utilisant LDAP
- La possibilité de s'identifier en tant qu'administrateur
☐ Listes de diffusion
☐ Comptes mail temporaires (10 minutes mail like)
☐ Antivirus & Spam
- ClamAV ou SpamAssassin ou autres : lourd.
- iptables dans un premier temps.
- Antispam maison, gestion du contenu, marquage de spam par l'utilisateur, "boites intelligentes" de spams.
☐ Les noms de domaines sont peut être nécessaires dès le départ pour tester le fonctionnement des fonctionnalités (telnet qui dit nope ?)
- Record A
- Record MX
☐ Sauvegarde automatique périodique de la Raspberry Pi (pendant le développement, pour éviter de perdre les données)
Il faudra aussi prêter attention aux fonctionnalités disponibles sur l'interface et ne pas laisser des fonctionnalités fantômes issues d'un template générique que l'on a pu trouver sur l'Internet.
Semaine 3 (05/10/2015)
Nous avons précisé les éléments constituants l'interface web :
- Gestion des comptes (création, modification, suppression d'utilisateurs...)
- Gestion des listes de diffusions
- Gestion des quotas
- Affichage du courrier
- Gestion de l'antivirus
Semaine 4 (12/10/2015)
Nous avons mis en place un github pour suivre le développement : GitHub.
Nous commençons à visualiser la structure de notre serveur mail. Dans un premier temps nous constituons notre base de données. Finalement nous utiliserons bien LDAP, qui semble relativement simple à utiliser contrairement à notre première impression.
Nous avons utilisé un tutoriel de Gandi pour mettre en place la base de notre annuaire. Nous utiliserons les schemas disponibles dans le paquet courier-ldap. Nous avons écrit un script en perl permettant d'installer ce schema facilement, nous évitant d'avoir à réinstaller le paquet complet pour récupérer un unique fichier.
Il est important maintenant de changer les règles d'accès à la base de données. En effet la base de données est disponible pour n'importe qui, on peut y entrer avec la commande :
ldapsearch -c -h localhost -b dc=domain,dc=tld -x
Nous avons ici aussi écrit un script permettant de le faire automatiquement. A ce stade il est nécessaire de s'identifier en tant qu'administrateur pour voir l'arbre :
ldapsearch -c -h localhost -b dc=domain,dc=tld -D "cn=admin, dc=domain,dc=tld" -W
On peut dorénavant développer la structure de notre directory. Nous avons choisi de reprendre la base du tutoriel de Gandi et d'ajouter une entité mail qui regroupera tout les utilisateurs du serveur mail. Nous avons donc écrit un fichier .ldif
décrivant cette structure et l'avons ajoutée avec la commande :
ldapadd -D "cn=admin,dc=domain,dc=tld" -W -h localhost -f ldif/mail_tree.ldif
On peut vérifier que la structure a bien été ajoutée à notre arbre avec la commande :
ldapsearch -D "cn=admin,dc=domain,dc=tld" -W -h localhost -b "dc=domain,dc=tld"
Maintenant, on peut ajouter nos utilisateurs à la base de données. Ici il est d'autant plus intéressant d'automatiser cette manipulation. Le principe est d'écrire un fichier .ldif
et de l'ajouter de la même manière que précedemment avec ldapadd
. Nous nous sommes inspirés ici encore du tutoriel de Gandi tout en l'adaptant. Le script perl add_user.pl
simplifie grandement l'ajout d'un utilisateur. On pourra par la suite le modifier pour l'utiliser directement avec du code php.
On peut vérifier que l'utilisateur a bien été ajouté avec la commande habituelle ldapsearch
et même tester l'identification avec :
ldapwhoami -vvv -h localhost -D "cn=username,dc=mail,dc=domain,dc=tld" -x -W
Si la commande renvoie Result: Success (0)
alors l'identification a fonctionné.
La commande ldapsearch
permet aussi de filtrer les recherches dans la base. Par exemple, avec notre configuration on peut afficher les utilisateurs avec la commande :
ldapsearch -D "cn=admin,dc=domain,dc=tld" -W -b "dc=mail,dc=domain,dc=tld" "(&(objectClass=CourierMailAccount))"
On peut aussi indiquer quels champs à afficher en les indiquant à la fin de cette commande.
Semaine 5 (19/10/2015)
DNS et SSL
Nous avons obtenu un nom de domaine auprès de Gandi pour notre projet. Le site est accessible à l'adresse : intimail.pw
nous avons configuré un serveur DNS et la certification SSL sur notre raspberry pi. Pour la démarche je vous renvoie à notre wiki de TP de Protocoles Réseaux Avancés. La méthode est identique.
De la même manière que dans le TP de PRA, nous voulions implémenter DNSSEC. Cependant arrivé à la dernière étape, nous nous sommes rendu compte que Gandi ne propose pas cette fonctionnalité pour les .pw. Dans l'éventualité où les DNSSEC seraient implémentés au cours de notre projet, nous pourrons activer cette fonctionnalité rapidement.
La différence réside dans le fait que pour un serveur mail il faut un enregistrement de type MX. Dans le fichier de configuration des enregistrements de bind, nous avons ajouté les lignes :
@ IN MX 10 mail.intimail.pw. mail IN A 193.48.57.171
De plus, un serveur mail doit pouvoir faire les résolutions inverses. En effet certains serveurs mail sont configurés pour rejeter ou retarder la livraison de mails provenant de serveurs dont la résolution inverse n'est pas effectuée. L'enregistrement PTR devient alors :
171 IN PTR mail.intimail.pw.
A ce stade, le serveur DNS devrait être correctement configuré et le SSL fonctionnel.
LDAP
Pour notre annuaire LDAP, nous avons utilisé les schémas proposés dans le package courier-ldap. Ces fichiers particuliers permettent à ldap de structurer sa base de données. Après différents essais et discussion, nous avons retenu la structure suivante :
Nous avons regroupé la totalité de nos entrées sous une entité commune mail, celle ci se divisant ensuite en deux groupes people et groups. Le dc people regroupe les informations des utilisateurs, que l'on détaillera plus tard. Le dc groups permettra quant à lui regroupera les différentes listes de diffusion. Il contient aussi le groupe particulier des administrateurs qui permettra de donner des droits privilégiés à certains utilisateurs.
Pour ce qui est des informations des utilisateurs, voici un exemple de fichier de configuration pour l'utilisateur Jean Valjean :
dn: cn=jvaljean,dc=people,dc=mail,dc=intimail,dc=pw uid: jvaljean mail: jvaljean@intimail.pw sn: Valjean givenName: Jean displayName: Jean Valjean mailbox: intimail.pw/jvaljean/ homeDirectory: /home/vmail/ objectClass: top objectClass: inetOrgPerson objectClass: CourierMailAccount userPassword: {SSHA}gCbVPaSGUaqjrq0mTQY77sOH4Xcq59Fg
Ces différentes informations ne sont pas définitives : certains champs peuvent peut être être retirés (comme le champ homeDirectory qui pour l'instant est commun et identique à tout les utilisateurs).
Web
Nous avons cherché un template léger, simple, mais néanmoins fonctionnel et agréable pour notre interface web. L'idée est, plutôt que de prendre un webmail classique dont nous n'utiliserions que 25 à 50% des capacités, de réaliser un webmail qui répond à toutes les exigences du cahier des charges et implémentant uniquement le nécessaire. Il s'est avéré après recherches que l'une des meilleures solutions était de partir sur une interface codée en PHP (ce dernier implémente une API dédiée à LDAP), agrémentée de Bootstrap pour le JS/CSS. Notre choix s'est finalement porté sur le template Lumino, que l'on peut essayer par ici.
Après divers test, il s'avère qu'une page de cette interface met en moyenne pour charger totalement :
- 2,10s sur une connexion mobile 3G moyenne (4MB/s)
- 1,90s sur une connexion 4G moyenne (15MB/s)
- 2,80s sur une connexion DSL moyenne (2MB/s)
- 1,90s sur une connexion Wifi (30MB/s)
- 1,70s sur une connexion THD (100MB/s)
Résultats qui semble apporter bon compris poids/qualité de l'interface.
Nous avons alors déployé cette interface, dans un dossier /var/www/webmail/, puis ajouté le VirtualHost correspondant à notre site dans la configuration apache
Config à venir, quelqu'un a éteint tutur06, notre raspberry est donc off :(
Semaine 6 (26/10/2015)
Firewall
Etant donné que nous avons subi plusieurs tentatives de connexion SSH frauduleuses sur notre serveur, nous avons décidé de mettre en place un semblant de sécurité sur ce dernier. Nous avons donc écrit un petit script iptables simples pour filtrer les entrées. Celui ci se contente de bloquer tout les paquets entrant et de laisser passer les paquets par les ports ou nous avions vraiment besoin (ici SSH, HTTP, HTTPS, DNS, NTP, SMTP, POP3 et IMAP). Après discussion, nous avons resserré davantage nos règles. Désormais le SSH n'est autorisé que pour des adresses ip spécifiées dans un fichier de liste blanche.
Nous avons aussi repéré dans le fichier /var/loh/auth.log plusieurs tentatives de connexions. Dans un premier temps nous avions cru à un problème de configuration de notre structure. Après avoir vérifié dans le log /var/log/syslog nous nous sommes aperçu qu'il s'agissait de connexions depuis des ip extérieures qui nous sont inconnues. Etant donné le nombre d'essais nous pensons que c'était une tentative d'intrusion sur le serveur SMTP par bruteforce. Comme première approche de contre-mesure nous avons pris le parti de constituer une liste noire. En effet ici nous n'avons pas le choix de laisser le port 25 (SMTP) ouvert. Pour cela nous avons utilisé les commandes :
cat /vat/log/syslog | grep SASL\ LOGIN\ authentication\ failed # Pour lister les messages de connexion échouées sed -ne 's/.*\[\([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\)\].*/\1/p' # Pour n'afficher que les ip *file* | sort | uniq # Pour classer et éliminer les doublons
On peut ensuite vérifier que les ip listées sont bien inconnues. Nous avons ainsi constitué une liste noire de 23 adresses ip.
Postfix
Nous avons installé l'agent de transfert de mail Postfix (apt-get install postfix postfix-ldap
) sur la raspberry et configuré celui ci en accord avec notre base de données LDAP. Après un test d'envoi via telnet :
telnet ex 25 Trying xxx.xxx.xxx.xxx... Connected to intimail.pw. Escape character is '^]'. 220 mail.intimail.pw ehlo intimail.pw 250-mail.intimail.pw 250-PIPELINING 250-SIZE 10240000 250-VRFY 250-ETRN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN MAIL FROM:toto(arobase)titi.com 250 2.1.0 Ok RCPT TO:jvaljean(arobase)intimail.pw 250 2.1.5 Ok DATA 354 End data with <CR><LF>.<CR><LF> Subject: Premier Test Here is my test . 250 2.0.0 Ok: queued as 0EDFC21428 quit 221 2.0.0 Bye Connection closed by foreign host.
Il est maintenant intéressant de tester notre DNS avec un outil en ligne. Nous avons ici utilisé l'excellent dnsstuff pour cela. C'est grâce à ce dernier que nous avons pu corriger les erreurs de notre serveur mail, à savoir :
- SMTP Greeting : Il permet de faire en sorte que le serveur mail est reconnu par les autres serveurs. Cela évite que certains serveurs ne refusent les mails provenant d'intimail.pw.
- Acceptance of abuse/postmaster : Les serveurs mails doivent avoir deux adresses abuse@... et postmaster@... . Nous avons donc créé ces deux boîtes mail pour répondre à ces conditions
Cyrus SASL
Nous avons implémenté l'authentification sur le serveur SMTP en SASL avec Cyrus. Après configuration, on peut maintenant envoyer des mail depuis notre serveur sur un serveur extérieur tel que gmail.
LDAP
Nous avons créé quelques utilisateurs LDAP pour peupler notre répertoire, contenant diverses informations utiles, afin de pouvoir commencer à implémenter une API d'authentification et réaliser divers essais sur l'interface web. Nous avons aussi ajouté un champ quota dans les informations des utilisateurs. A première vue ce champ pourra être utilisé avec le serveur IMAP et POP3. Cependant, afin d'éviter d'installer des services supplémentaires, nous choisissons de nous orienter dans une autre direction. Postfix nous permet à l'heure actuelle d'envoyer et recevoir des mails avec nos utilisateurs virtuels, et stocke chaque mail dans un fichier sur le système. L'interface web peut donc, sans Dovecot ou serveurs IMAP/POP3, parser par elle-même les mails reçus et préparer un envoi. Il nous faut, en prenant cette voie, réfléchir à l'implémentation des quotas, non gérés par PostFix. L'idée serait de lancer un script quand Postfix reçoit un mail, avant de le stocker sur le système, et de vérifier que la taille de ce mail + de ceux déjà reçu/envoyés par avant ne dépasse pas le quota attribué à un utilisateur, et rejeter le mail à l'expéditeur si on va dépasser alors le quota.
Web
Nous avons modifié le template de site web en accord avec nos objectifs. L'utilisateur doit d'abord se connecter avec ses identifiants LDAP (uid et mot de passe correspondant à son unique Distinguished Name (DN: cn=jvaljean,dc=people,dc=mail,dc=intimail,dc=pw). Une fois connecté, il tombe sur une interface que l'on pourrait appeler une "vue globale", réunissant les informations principales : le nombre de nouveaux mails, l'utilisation actuelle de son quota sur le disque, les quelques derniers mails reçus, et un calendrier afin de se repérer simplement niveau date. Sur le côté, il est possible d'aller voir plus en détail l'inbox où se trouvent tous les mails reçus, ou encore aller voir les messages envoyés, et supprimer les courriels dans la poubelle. Si l'utilisateur est administrateur, il a aussi accès à un onglet "Manage" d'où il pourra prendre fonction de ses pleins pouvoirs. Cette dernière fonctionnalité n'étant pas encore implémentée, tout utilisateur voit pour l'instant cet onglet.
Toute la journée du mardi le code web a été réaménagé et modulé. Nous réfléchissons désormais au stockage et à la récupération de l'état instantané du quota mail (stocker cette valeur dans un fichier, ou en fait un attribut supplémentaire d'un utilisateur LDAP, où est d'ailleurs déjà stocké son quota max). L'idée est de ne pas trop solliciter le système et d'incrémenter ou décrémenter une variable à chaque réception/envoi de mail plutôt que recalculer entièrement la taille du dossier où sont les mails. On pourra en outre envisager de mettre en place une tâche périodique (via CRON) qui vérifiera en heures creuses que la taille du dossier mail est bien égale au quota en variable dans le système.
Par la suite il a été convenu de supprimer Apache et de le remplacer par le serveur web Lighttpd, plus léger et plus performant. Pour la configuration, on rajoute simplement un hôte au fichier /etc/lighttpd/lighttpd.conf auquel on fournit notamment le chemin d'accès aux fichiers du site, ou encore les clés pour SSL. Nous avons alors réinstallé PHP et nous l'avons reconfiguré et activé pour Lighttpd. Enfin, l'activation du mod_rewrite et la mise en place de règles différentes de celles d'Apache (qui font la même chose mais à la sauce Lighttpd) nous permettent de conclure cette migration en environ 25-30min (!). Le mod_rewrite, un peu gadget nous l'avouons, permet chez nous de résoudre une URL de type www.domaine.com/page.php en écrivant simplement www.domaine.com/page. On atteint donc la page de connexion de notre webmail par https://www.intimail.pw/login. Nous avons en outre pu préciser la suite de notre projet. L'idée est d'avoir 2 ports sur lequel Postfix écoute (disons *:25 et localhost:10025). A réception d'un email sur *:25, postfix est configuré pour lancer un script que nous réalisons. Ce script vérifie le quota de l'utilisateur, si le mail reçu ne le dépasse pas il transfère alors le mail à localhost:10025 qui l'accepte et écrit le mail sur le disque de manière normale. Sinon, il renvoie un code d'erreur et le mail n'est pas accepté. De plus, le script mettra à jour un index dans un fichier propre à chaque utilisateur que le webmail lira. En somme, l'utilisation de fichiers quota et index évite à l'interface web de vérifier entièrement les dossiers et sous-dossiers mail à chaque actualisation de la page, ce qui créerait une charge énorme pour la Pi. On s'abstient en plus d'installer Dotecove/Un serveur IMAP/Un serveur POP grâce à notre webmail et nos scripts qui gèrent tout et uniquement ce dont nous avons besoin. Notre architecture s'oriente donc sur les schémas suivants :
Scripting
Nous avons écrit un script perl pour envoyer des mails de manière automatique. Précisons que nous avons dû installer libswitch-perl
pour pouvoir l'utiliser. Ce package devra être ajouté dans les dépendances lors de la constitution du fichier d'installation de notre outil.
Semaine 7 (02/11/2015) - Architecture du système de fichiers
Notre système s'articule autour de 2 chemins distincts. A droite en rouge, l'architecture classique par défaut de postfix. Les mails reçus sont enregistrés par défaut dans un dossier par utilisateur et par domaine, dans le dossier new. A gauche notre architecture greffée, dans un sous dossier différent, par utilisateur et par domaine. Dans ces sous-dossiers, on distingue alors 2 dossiers et 1 fichier.
- Le fichier contient la valeur actuelle du quota de l'utilisateur. On préfère cette méthode plutôt que de faire calculer l'espace disque disponible dans un dossier par le système à chaque fois. On fera tourner un script, de nuit, périodiquement, pour vérifier que le quota correspond bel et bien à la valeur dans le fichier, pour éviter d'incrémenter/décrémenter une erreur.
- Un dossier mail, dans lequel sont stockés les mails envoyés
- Un dossier json, dans lequel sont stockés les conteneurs json, qui contiennent les en-têtes des mails envoyés, reçus, spams et poubelles. On accède donc à toutes les infos utiles au webmail en lisant ces json, plutôt que de lire à chaque fois tous les mails, ce qui serait extrêmement lourd et lent.
Semaine 8 (09/11/2015) - Postfix et filtrage
Nous avons établi une première version de notre script de traitement des mails arrivant sur le serveur. Nous nous sommes inspirés pour cela de la configuration proposée dans le manuel de Postfix. La configuration se fait via le fichier master.cf
. Ce fichier permet de configurer tout les processus utilisés par Postfix pour fonctionner. Dans notre cas, il nous permet de déclarer un service de filtrage et d'indiquer au démon qui récupère les mails entrants (smtpd) de les transférer à ce service via un programme pipe. La configuration se fait de la manière suivante :
# ========================================================================== # service type private unpriv chroot wakeup maxproc command + args # (yes) (yes) (yes) (never) (100) # ========================================================================== smtp inet n - - - - smtpd -o content_filter=filter filter unix - n n - 5 pipe flags=Rq user=vmail null_sender= argv=/path/to/script $queue_id $size $sender $recipient
Nous avons décidé de suivre la même structure que dans le manuel de Postfix. C'est à dire que postfix fait appel à un script de filtrage principal, qui va lui même faire appel à d'autres scripts répondant à des besoins plus spécifiques. Pour l'instant, le script va parser certaines informations des mails entrant dans des fichier .json, qui servent de base de données. En voici un exemple :
[ { "from": "michel.drucker@gmail.com", "subject": "Vivement dimanche", "timestamp": "2015-11-8 19:59:53", "unixtimestamp": "1447012793", "queueid": "48FE03FA87", "filepath": "???", "size": "1676", "status": "0", "pj": "0", "id": "0", "to": "jbond@intimail.pw" } ]
Il serait également intéressant d'ajouter un champ permettant d'indiquer le chemin du fichier contenant le mail. Cependant au moment de l'exécution, même si nous avons accès au contenu du fichier, il est à priori impossible de connaître le nom définitif du fichier (il y a une part d'aléatoire). Ils serviront à l'affichage des mails dans les boîtes de réception dans le webmail. On pourra par la suite ajouter d'autres scripts permettant par exemple de vérifier la nature du message ou encore son contenu (Antivirus / Antispam / Pièces jointes).
Il est intéressant également de pointer ici que le fichier de configuration permet de préciser l'utilisateur qui va exécuter le script de filtrage. Ici nous avons mis user=vmail
. Le script de filtrage s'exécutera donc en tant que vmail. Or pour l'interface, il faut qu'apache puisse accéder aux fichiers écrits par des processus de vmail. Pour les fichiers .json, écrits par le script de filtrage décrit plus haut, la solution du relativement simple. Il a suffit d'ajouter quelques commandes chmod pour autoriser la lecture et éventuellement l'écriture au groupe. Nous avons ensuite ajouté www-data au groupe vmail.
Quant aux fichiers contenant les mails, ceux ci sont écrits par postfix, et nous n'avons pour l'instant pas trouvé le moyen d'autoriser l'accès à ces fichiers par www-data. Ce problème, ainsi que la difficulté à récupérer le nom du fichier (décrit plus haut), nous pousse à nous demander si le délivrement des mails ne devrait pas être géré par un programme de notre confection, plutôt que le programme sendmail de postfix. En théorie, cette méthode répond parfaitement aux deux problèmes mais sendmail propose certainement une gestion plus aboutie que nous ne saurons reproduire dans un temps limité.
Semaine 9 (16/11/2015)
Semaine 10 (23/11/2015)
Semaine 11 (30/11/2015)
Nous avons travaillé sur le parser de mails et tentons d'implémenter notre architecture de fichiers.
D'autre part, nous avons travaillé l'interface web. Le contenu des tables affichant les en-tête des mails étant généré dynamiquement en fonction du fichier .json, il est impossible d'ajouter des balises <a href> pour rendre ces en-têtes cliquables pour afficher le contenu d'un mail.
La solution retenue et implémentée est d'utiliser un événement JavaScript. Pour une table avec un id table, on récupère l'en-tête cliquée à l'aide de la fonction JavaScript suivante :
$('#table').on('click-row.bs.table', function (e, row, $element) { console.log(row, $element); alert("L'utilisateur d'intimail a cliqué sur "+row); });
On peut donc récupérer l'en-tête du fichier, plus spécifiquement le champ contenant le chemin vers le fichier mail brut. On pourra alors envoyer ce chemin dans une variable à l'aide d'une requête POST lancée dans la fonction ci-dessus avec AJAX, et être emmené vers une page qui traitera et affichera à l'utilisateur ce fichier mail brut.
Semaine 12 (07/12/2015)
Parseur pour les mails entrants
Comme nous l'avons dit à la semaine , nous avions rencontré un problème lors de la réception des mails. Pour resituer le problème : lors de la réception d'un mail, nous avons créé un hook pour postfix, qui s'exécute lors de la réception d'un email. La difficulté étant qu'au moment de cette exécution, les fichiers contenant les mails ne sont pas écrits dans le système de fichier, rendant impossible la récupération des noms de fichier. De plus, ces fichiers comportent les permissions 600 pour l'utilisateur et le groupe vmail:vmail.
La solution que nous proposons est de détacher le processus de parsing au moment de l'appel du script. De cette manière, le mail peut être délivré correctement et passe quand même dans le script de parsing, nous permettant ainsi de récupérer les mails et les informations critiques. On peut même en profiter pour appliquer les droits dont nous avons besoin. A priori, il suffirait juste d'autoriser le groupe vmail en lecture et d'ajouter www-data à ce groupe pour pouvoir afficher le contenu des mails dans l'interface Web. Résumons schématiquement le processus :
Un mail arrive Le hook de postfix est exécuté Le mail est envoyé via Sendmail --------------------------------------------------------------> Le mail est en attente de délivrement Le script de parsing est lancé | Le script vérifie dans les dossiers la présence du nouveau mail | et réessaye un certain nombre de fois tant que tout les destinataires ne sont pas traités | | v | Le mail est délivré et existe dans le système de fichier v | Le script a trouvé le fichier et le traite <---------------------------------------------------- Fin
Nous avons aussi un peu réduit le contenu des éléments json en retirant le champ filepath. Les fichiers mails sont déplacés dans un dossier et renommés suivant le modèle $unixtimestamp.$queueid
. Si nous rencontrons des collisions de noms (ce qui devrait théoriquement ne pas arriver) nous garderons les noms de fichier standard de postfix et restaurerons le champ filepath
.
Interface Web
L'interface web progresse, et la page d'accueil est désormais totalement terminée et dynamique. Comme on peut le voir sur l'image ci-dessous, la nombre de mails dans la boite de réception, dans la poubelle, et le quota sont retrouvés et calculés dynamiquement, et ce en chargeant simplement les fichiers .json d'en-tête que nous avons crée, ce qui évite au système des calculs lourds. En outre le bouton "Write an email", présent dans la barre de navigation en haut mais aussi en gros sur la page d'accueil permet d'ouvrir une fenêtre pour écrire un email. L'envoi fonctionne parfaitement sur le réseau interne de l'école (nous devons encore passer la Raspberry sur un modem en dehors de Polytech pour éviter les foudres du CRI.), et ne devrait poser aucun problème une fois cette histoire de filtrage bypassée. Nous savons aussi envoyer des pièces-jointes, pour l'instant en dur pour la Proof of Concept, nous implémenterons bientot la possiblité à un utilisateur de téléverser son propre fichier (à taille raisonnable). Nous réflechissons au stockage de la PJ : serveur distant ?
Semaine 13 (14/12/2015)
- Écriture du rapport intermédiaire
- Réalisation du support de soutenance
Semaine 14 (04/01/2016)
Semaine 15 (11/01/2016)
Semaine 16 (18/01/2016)
Semaine 17 (25/01/2016)
Côté web :
- Poursuite du travail sur les pièces jointes : envoi OK, types supportés GIF, JPG, PNG, PDF, ZIP, vérification par extension MIME, taille max d'une PJ variabilisé
- Gros travail sur les fichiers d'en-tête JSON : fonctions PHP de suppression d'un mail (fichier sur le disque et suppression dans l'en-tête JSON), fonctions de mise à jour du quota à l'envoi (réception fonctionnel aussi), fonctions d'ajout d'un mail (fichier sur le disque et en-tête JSON)
- Interface : gestion des différentes boites : les mails écrits se retrouvent dans "Envoyés", les mails reçus dans "Boite de réception", manque que le flag comme spam pour les mettre dans la boite à spam, mais la boite est déjà là en tout cas
Semaine 18 (01/02/2016)
Semaine 19 (08/02/2016)
Semaine 20 (15/02/2016)
Semaine 21 (22/02/2016)
Fichiers Rendus
Interface web : intiMail.pw
Rapport de Mi-Projet : ICI
Rapport de Projet : [http:// Soon™]