Personnel · E5 / E6 / E7
Kanyro : site vitrine et messagerie auto-hébergée
Conception, mise en production et administration d'un site vitrine statique et de son serveur de messagerie sur un VPS Linux, du nom de domaine jusqu'à la signature DKIM, jusqu'à la bascule du service entier vers un nouveau domaine.
Synthèse
- Catégorie
- Personnel
- Période
- Août 2026, en cours
- Organisation
- Projet personnel Kanyro
- Mon rôle
- Intégralité du projet : choix techniques, développement du site, installation et configuration du serveur, administration des domaines et des zones DNS, diagnostic des pannes, conduite de la bascule de domaine et rédaction de la documentation d'exploitation.
- Modalité
- Travail individuel
- État de la fiche
- En cours
Pourquoi ? Contexte et problématique
Contexte
Kanyro est une activité de création de sites internet destinée aux artisans du bâtiment. Le projet couvre l'ensemble de la chaîne : le site vitrine qui porte l'offre, le serveur qui le diffuse, et la messagerie par laquelle arrivent les demandes de devis. Tout est administré personnellement, sans prestataire ni service tiers hébergeant les données. Le service tourne depuis le 26 août 2026 et a changé de nom de domaine le 20 septembre, sans interruption ni perte de courrier.
Problématique
Une activité qui vend de la présence en ligne ne peut pas dépendre d'un formulaire hébergé chez un tiers ni d'une adresse de messagerie gratuite : le premier tombe en panne silencieusement lors d'un changement d'hébergeur, la seconde décrédibilise l'expéditeur. Comment mettre à disposition un chemin de contact fiable, maîtrisé de bout en bout, dont on puisse prouver le bon fonctionnement, et qui survive à un changement de nom de domaine ?
Objectifs
- Diffuser un site statique en HTTPS depuis un serveur administré personnellement.
- Recevoir et émettre du courrier depuis une adresse du domaine, aujourd'hui bonjour@kanyro.fr.
- Faire accepter les messages sortants par les grands fournisseurs (SPF, DKIM, DMARC, reverse DNS).
- Garantir que le contenu reste lisible sans JavaScript et sans dépendance à un domaine tiers.
- Changer le domaine de production sans perdre une demande de devis ni casser un lien déjà publié.
- Encadrer les données personnelles collectées par le formulaire : finalité, base légale, durée de conservation réellement appliquée et exercice des droits.
Comment ? Démarche et réalisation
Architecture
Le VPS héberge deux services distincts sur la même machine. Caddy sert le site statique en HTTPS sur les ports 80/443, obtient les certificats Let's Encrypt et redirige l'ancien domaine vers le nouveau. À côté, la chaîne de messagerie : un message entrant suit le trajet Internet → Postfix (port 25) → OpenDKIM (vérification) → LMTP → Dovecot → Maildir de la boîte bonjour@kanyro.fr ; un message sortant suit Postfix → OpenDKIM (signature) → Internet. Dovecot expose la boîte en IMAP (143) et IMAPS (993), Postfix accepte l'envoi authentifié sur les ports 465 et 587. Les deux domaines sont des domaines virtuels de Postfix et signent chacun avec sa propre clé DKIM. Un script déclenché par cron recopie les certificats obtenus par Caddy vers Postfix et Dovecot, qui présentent à chaque client le certificat du nom qu'il a demandé, par SNI.
Étapes de réalisation
1. Site statique et périmètre initial
Développement du site en Astro avec sortie entièrement statique : le contenu ne dépend jamais de l'exécution d'un script côté client. Le périmètre a d'abord été limité à cinq pages : accueil, contact, mentions légales, remerciement et 404. Les pages « métier × commune » prévues pour le référencement local étaient écrites mais éteintes par deux booléens de configuration, en attendant d'avoir de quoi les remplir.
2. Première mise en ligne sur hébergement mutualisé
Le site a d'abord été déployé sur un hébergement mutualisé OVH, avec un fichier .htaccess portant la redirection HTTPS, les en-têtes de sécurité, la compression et le cache des ressources, et un formulaire de contact en PHP utilisant la fonction mail() du serveur.
3. Migration vers un VPS administré
Le mutualisé ne permettait ni d'héberger la messagerie du domaine, ni de maîtriser la configuration du serveur web. Migration vers un VPS Hostinger : installation de Caddy, bascule du domaine de production sur kanyro.tech, mise à jour des mentions légales et des données structurées pour identifier le nouvel hébergeur, comme l'impose la LCEN.
4. Installation du serveur de messagerie
Installation et configuration de Postfix en domaine virtuel, de Dovecot pour la livraison locale en Maildir et l'accès IMAP, et d'OpenDKIM branché en milter sur Postfix pour signer les messages sortants. Création de la première boîte, contact@kanyro.tech, et mise en place du partage de certificat entre Caddy, Postfix et Dovecot.
5. Configuration DNS de la messagerie
Publication des enregistrements qui rendent un serveur de messagerie crédible : un enregistrement A pour l'hôte mail, SPF pour autoriser le serveur à émettre pour le domaine, DKIM pour publier la clé publique de signature, DMARC pour déclarer la politique, et le reverse DNS de l'adresse IP pointant vers le nom du serveur. L'audit décrit plus bas a montré que trois d'entre eux manquaient ou étaient incomplets ; ils ont été corrigés.
6. Audit externe du site et correction — 11 septembre 2026
Le site a été audité comme le ferait un prestataire extérieur : rendu de chaque page à cinq largeurs dans un navigateur sans interface, mesure des contrastes, des tailles de texte et des cibles tactiles, relevé des Web Vitals en profil « 4G lente », lecture des en-têtes HTTP et des enregistrements DNS. Verdict : 42/100, avec une page d'accueil chargeant 10 Mo pour un LCP de 22,6 secondes. Les corrections ont porté sur le poids des médias, la hiérarchie typographique, les contrastes, la taille des cibles et les en-têtes du serveur. Le même protocole de mesure, rejoué après correction, sert de recette.
7. Cadre juridique et durée de conservation appliquée
Rédaction et publication de trois pages légales : mentions légales conformes à la LCEN, conditions générales de vente entre professionnels avec formulaire de rétractation en annexe, et politique de confidentialité recensant six traitements de données avec leur base légale et leur durée. Mise en place, côté serveur, du service de purge sans lequel la durée de trois ans annoncée sur le site n'aurait été qu'une phrase. Le build du site refuse désormais de produire une page légale incomplète.
8. Bascule vers kanyro.fr — 20 septembre 2026
Le service est passé de kanyro.tech à kanyro.fr, un domaine en .fr étant plus crédible auprès d'artisans locaux. La bascule s'est faite dans un ordre imposé : le DNS d'abord, puis le site et les redirections, et le courrier en dernier. kanyro.tech redirige désormais en 301 vers kanyro.fr, la boîte est devenue bonjour@kanyro.fr, et l'ancienne adresse subsiste en renvoi pour que les devis et les liens déjà publiés continuent d'arriver.
Configurations
OpenDKIM : identité du processus et fichier PID
Le démon redémarrait en boucle avec le message « key data is not secure » : il s'exécutait sous root alors que les clés appartiennent à l'utilisateur opendkim. La correction tient en trois directives : UserID opendkim dans /etc/opendkim.conf (le paramètre s'appelle UserID et non User, ce qui est une source d'erreur classique), une directive PidFile, et un drop-in systemd déclarant RuntimeDirectory pour que le répertoire du socket existe au démarrage.
Postfix : transport LMTP vers Dovecot
Postfix ne délivre pas lui-même dans les boîtes : il passe le message à Dovecot par LMTP, qui écrit dans le Maildir. Les deux domaines sont déclarés en domaines virtuels et la liste des boîtes tenue dans /etc/postfix/vmailbox.
Deux domaines sur le même serveur, deux clés DKIM et un renvoi
Depuis la bascule, kanyro.fr et kanyro.tech sont tous deux des domaines virtuels de Postfix. Chacun a sa propre paire de clés dans /etc/opendkim/keys, déclarée dans le KeyTable et le SigningTable : une clé unique aurait obligé les deux zones à publier le même enregistrement, et un domaine ne signe correctement qu'avec une clé publiée sous son propre nom. contact@kanyro.tech n'est plus une boîte mais un renvoi posé dans /etc/postfix/virtual vers bonjour@kanyro.fr ; le Maildir d'origine est conservé, les messages reçus avant la bascule restent consultables.
Un certificat par nom, présenté par SNI
Caddy délivre un certificat par nom : celui de mail.kanyro.fr ne couvre pas mail.kanyro.tech. Comme les appareils configurés avant la bascule continuent de se connecter à l'ancien nom, le serveur doit présenter à chacun le certificat qu'il attend. C'est le rôle de l'extension SNI, gérée par Postfix (tls_server_sni_maps) et par Dovecot (local_name) : le client annonce le nom demandé pendant la poignée de main, le serveur répond avec le certificat correspondant. Sans elle, il aurait fallu choisir lequel des deux noms afficherait une alerte de sécurité à chaque relève de courrier.
Partage du certificat TLS entre trois services
Caddy renouvelle seul les certificats Let's Encrypt, mais Postfix et Dovecot lisent les leurs dans un autre répertoire et sous un autre utilisateur. Un script recopie les certificats vers /etc/mail-certs et alimente les tables SNI ; il lit le nom du serveur dans la configuration de Postfix au lieu de le connaître en dur, si bien qu'ajouter un nom au Caddyfile suffit. Il est déclenché toutes les quinze minutes par cron. Sans lui, les clients de messagerie afficheraient un avertissement de sécurité au premier renouvellement.
En-têtes de sécurité et politique de sécurité de contenu
La configuration de Caddy est versionnée dans le dépôt et validée avant rechargement. Elle pose HSTS pour un an, sans preload ni includeSubDomains pour ne pas couper un futur sous-domaine servi en HTTP, une politique de sécurité de contenu identique à celle de la balise meta du site mais portant en plus frame-ancestors et upgrade-insecure-requests, une Permissions-Policy qui refuse huit API du navigateur, et retire la signature du serveur. La page 404 reçoit les mêmes en-têtes que les autres, ce qui n'était pas le cas au départ.
Traitement des données personnelles et durée réellement appliquée
Le formulaire de contact est le premier traitement de données à caractère personnel du site : il collecte un nom, une entreprise, une adresse électronique, un téléphone et un message. La politique de confidentialité recense six traitements, chacun avec sa base légale, sa durée et les personnes qui y ont accès ; celui du formulaire relève des mesures précontractuelles prises à la demande de la personne, article 6.1.b du RGPD. Le site ne dépose aucun cookie et n'utilise aucun outil de mesure d'audience tiers. La durée de conservation de trois ans est appliquée par un service de purge déclenché par un timer systemd, qui supprime les messages au-delà du délai dans les deux boîtes, brouillons, envoyés, corbeilles et indésirables compris : une durée annoncée que rien n'applique est exactement ce qu'un contrôle relève en premier.
Procédures
Politique anti-abus du formulaire de devis
Le formulaire renvoie un accusé de réception au visiteur, ce qui en fait une arme si on ne le borde pas : il suffit de soumettre l'adresse d'un tiers en boucle pour la noyer, et c'est le domaine expéditeur qui finit sur les listes noires. L'envoi est donc limité à cinq soumissions par heure et par adresse IP, l'accusé de réception est générique et le compteur est salé par un secret qui ne vit pas dans le dépôt. En cas d'échec, le visiteur est renvoyé sur une URL portant le motif (saisie, limite ou envoi), et le message correspondant est affiché avec restitution de ce qu'il avait tapé.
Ordre d'une bascule de nom de domaine
La bascule suit un ordre qui ne se prend pas à l'envers. Le DNS d'abord : tant que le nouveau nom ne pointe pas sur le serveur, Caddy ne peut pas obtenir son certificat. Le site ensuite, adresses canoniques, plan de site, données structurées et pages légales basculant ensemble, l'ancien domaine se mettant à rediriger au même moment. Le courrier en dernier, et jamais en même temps que le reste : une migration de messagerie ratée, ce sont des demandes de devis perdues sans que personne ne s'en aperçoive. L'ancienne adresse reste en renvoi.
Reverse DNS et nom annoncé, dans cet ordre
Le reverse DNS de l'adresse IP se change chez l'hébergeur, pas dans la zone du domaine : il reste donc à faire après la bascule. Tant qu'il n'a pas changé, le nom annoncé par Postfix ne doit pas changer non plus. Gmail et Outlook comparent trois choses : le nom annoncé à la connexion, le reverse DNS de l'adresse, et le domaine de l'expéditeur. Annoncer le nouveau nom avec un reverse qui désigne encore l'ancien casserait l'accord entre les deux premiers pour préparer celui du troisième : on y perd plus qu'on n'y gagne.
Protection du domaine de production pendant la phase de test
Pendant la période où le site tournait sur un sous-domaine de test, un unique objet de configuration basculait ensemble l'URL canonique, les balises og:url, le sitemap, le noindex de toutes les pages et le contenu du robots.txt. Si le moteur de recherche avait indexé la version de test, c'est elle qui serait ressortie dans les résultats, et le domaine définitif aurait publié un contenu déjà connu ailleurs. C'est le même objet qui a porté la bascule vers kanyro.fr.
Avec quoi ? Environnement technique
Environnement
- VPS Hostinger sous Linux, administré en SSH
- Deux noms de domaine : kanyro.fr chez OVH, domaine de production, et kanyro.tech chez Hostinger, redirigé
- Astro 7 en sortie statique, Tailwind 4, Node 22+
- Postfix, Dovecot et OpenDKIM pour la messagerie, en domaines virtuels
- Caddy pour la diffusion HTTPS et les certificats Let's Encrypt
- PHP-FPM 8.3 pour le formulaire de demande de devis
Technologies
Quel résultat ? Tests et validation
Tests réalisés
Chaîne de messagerie de bout en bout
Envoi d'un message vers la boîte puis vérification de son arrivée dans le Maildir ; lecture des en-têtes du message pour vérifier la présence de la signature DKIM ; connexion IMAP avec STARTTLS et lecture de la boîte de réception depuis un client de messagerie. Vérification de la publication de la clé DKIM avec opendkim-testkey, qui doit répondre « record found » pour chacun des deux domaines.
Écoute effective des ports de service
Le port 587 était déclaré dans master.cf mais n'apparaissait pas dans les ports en écoute. Le contrôle a consisté à lister les sockets ouverts sur la machine plutôt qu'à se fier au fichier de configuration : un service configuré et un service en écoute sont deux choses différentes.
Audit de la zone DNS depuis l'extérieur
Interrogation de chaque enregistrement de messagerie depuis trois résolveurs publics indépendants, plutôt que depuis le serveur lui-même : un serveur se croit toujours joignable. Vérification de la concordance entre clé privée locale et clé publiée avec opendkim-testkey, et lecture du certificat réellement présenté par Postfix et Dovecot avec openssl. C'est cet audit qui a révélé l'absence d'enregistrement MX, puis la couverture IPv6 incomplète du SPF.
Validation de bout en bout par un opérateur tiers
Un serveur qui se déclare conforme ne prouve rien : le seul juge utile est le destinataire. Envoi d'un message depuis la boîte du domaine vers une boîte Gmail, puis relecture des en-têtes ajoutés par Google via « Afficher l'original ». Les trois mécanismes sont constatés en réussite, et l'en-tête Received montre que le message est parti en IPv6, soit exactement le cas qui échouait avant l'ajout de l'enregistrement AAAA.
Contrôle de la bascule depuis l'extérieur
Le jour de la bascule, le même protocole a été rejoué depuis une autre machine que le serveur : en-têtes HTTP de kanyro.fr et code de redirection de kanyro.tech, enregistrements MX, SPF, DKIM et DMARC de la nouvelle zone interrogés sur trois résolveurs publics, et certificat présenté sur le port 993 pour chacun des deux noms de serveur, chaque connexion annonçant le nom qu'elle demande. Les deux répondent « does match certificate », ce qui vérifie la configuration SNI autrement qu'en relisant le fichier.
Répétition de la purge avant de l'armer
Un service qui supprime des messages se regarde tourner à vide avant d'être laissé seul. La commande de recherche de Dovecot liste les messages qui seraient supprimés sans rien toucher : elle a été passée sur chaque dossier des deux boîtes, avant d'armer le timer, puis le service a été déclenché à la main et ses journaux relus.
Recette du site sur le build de production
Contrôles passés sur le site généré, politique de sécurité de contenu active : une seule balise h1 par page, aucun script ni style en ligne, aucun lien mort, contenu intégralement lisible sans exécuter de JavaScript, URL canoniques alignées sur le sitemap, aucun débordement horizontal, contrastes conformes au niveau AA de 360 à 2 560 px, cibles tactiles d'au moins 44 px, et aucune violation de la politique de sécurité de contenu au chargement des polices, images et vidéo.
Résultats obtenus
- Site en production sur https://kanyro.fr, diffusé en HTTPS par un serveur administré personnellement ; kanyro.tech redirige vers lui, en 308 sur les envois de formulaire pour qu'une demande de devis ne soit jamais rejouée à vide.
- Boîte bonjour@kanyro.fr fonctionnelle : réception vérifiée, lecture en IMAP sur TLS, messages sortants signés par la clé DKIM du domaine.
- Continuité assurée sur l'ancienne adresse : contact@kanyro.tech est devenue un renvoi, et les messages reçus avant la bascule restent consultables sur leur compte d'origine.
- Deux noms de serveur servis par la même machine, chacun avec son certificat : vérifié depuis l'extérieur, mail.kanyro.fr et mail.kanyro.tech répondent tous deux « does match certificate » sur le port 993.
- MX, SPF, DKIM et DMARC de kanyro.fr publiés et concordants, vérifiés depuis trois résolveurs publics indépendants.
- Audit DNS d'août 2026 : trois défauts identifiés puis corrigés, à savoir un MX absent, un hôte mail sans AAAA et un reverse IPv6 incohérent avec le HELO.
- Chaîne validée par un tiers : Gmail constate dkim=pass, spf=pass et dmarc=pass sur un message réel parti en IPv6, en TLS 1.3.
- Durée de conservation de trois ans réellement appliquée : un service de purge la fait respecter dans les deux boîtes, corbeilles et brouillons compris, et a été répété à vide avant d'être armé.
- Audit externe du site noté 42/100 le 11 septembre 2026, puis corrigé : page d'accueil passée de 10 Mo à 164 Ko au chargement, LCP de 22,6 s à 2,1 s en 4G lente simulée, décalage cumulé nul.
- Contrastes AA sur les quatorze pages générées à cette date, de 360 à 2 560 px, aucun texte sous 12 px, cibles tactiles d'au moins 44 px, aucun débordement horizontal.
- Configuration Caddy versionnée dans le dépôt : HSTS, politique de sécurité de contenu en en-tête, Permissions-Policy fermant huit API, signature du serveur retirée, mêmes en-têtes sur la page 404.
- Trois pages légales publiées, dont la génération échoue si l'une est incomplète : mentions légales, conditions générales de vente entre professionnels et politique de confidentialité recensant six traitements avec leur base légale.
- Site entièrement lisible sans JavaScript, sans cookie, sans outil de mesure d'audience tiers et sans requête vers un domaine tiers.
- Documentation d'exploitation rédigée : architecture de la messagerie, fichiers de configuration, enregistrements DNS, procédure de bascule de domaine et procédures de vérification.
Difficultés et bilan
Difficultés rencontrées et solutions apportées
Le service tourne mais rien n'est livré
Postfix acceptait les messages sans que rien n'arrive dans la boîte. Le socket LMTP de Dovecot n'existait pas : le service avait été configuré mais pas redémarré depuis. La leçon retenue est de vérifier l'existence du socket côté récepteur avant de chercher l'erreur côté émetteur, en remontant le trajet du message brique par brique plutôt qu'en relisant les fichiers de configuration.
Aucune connexion possible à la boîte
Le fichier d'utilisateurs référencé dans la configuration de Dovecot n'existait tout simplement pas : la configuration pointait vers un chemin valide en apparence, sans que rien ne signale son absence. Le compte a été créé avec un mot de passe chiffré, et la lecture des journaux du service s'est révélée plus rapide que la relecture de la configuration.
Un formulaire qui postait dans le vide
Le formulaire reposait au départ sur le service de formulaires de la plateforme d'hébergement d'origine, dont la détection se fait au moment du déploiement chez cet hébergeur. Déployé ailleurs, le formulaire s'affichait normalement, acceptait la saisie, et ne transmettait rien, sans la moindre erreur. Il a été réécrit en PHP autonome. Une panne silencieuse sur l'unique chemin de contact est le pire des scénarios : elle ne se voit pas.
Ce qui marche en développement et casse en production
Deux pièges de même nature ont été rencontrés. Le script d'effets, inséré en ligne par le générateur, était bloqué par la politique de sécurité de contenu, absente en développement, et les pages sortaient vides ; il est désormais servi comme fichier séparé. De même, la directive upgrade-insecure-requests est portée par l'en-tête HTTP et jamais par une balise meta : dans le HTML, elle s'appliquerait aussi aux environnements sans HTTPS, où la page se chargerait sans style. Dans les deux cas, le symptôme n'apparaît qu'une fois déployé.
Deux enregistrements SPF valent moins qu'un seul
La zone du nouveau domaine était déjà servie par son registraire, avec ses propres enregistrements de messagerie. Pendant une heure, elle a porté deux SPF : le nouveau et celui du registraire. Deux SPF sur le même nom ne se cumulent pas, ils produisent une erreur permanente que beaucoup de serveurs traitent comme un échec, donc un résultat pire qu'un SPF unique et faux. Celui du registraire refusait de surcroît tout envoi venant d'ailleurs, ce qui aurait fait rejeter chaque message parti du VPS. Même piège du côté des MX : les trois du registraire, en priorité 1, 5 et 100, passaient avant celui du serveur en priorité 10 et captaient donc la totalité du courrier entrant. Migrer une zone, c'est retirer autant qu'ajouter.
Une purge qui s'arrêtait à la deuxième ligne
Le service de purge parcourt les dossiers un par un. Hors boîte de réception, les dossiers sont créés par le client de messagerie et non par le serveur : sur une boîte neuve, ils n'existent pas, et la commande sort en erreur. Sans tolérance sur ces lignes, le service s'arrêtait au deuxième dossier et la corbeille, dernière de la liste, n'était jamais vidée. Le problème est apparu le jour de la création de la nouvelle boîte. Une purge qui échoue à mi-parcours ne se voit pas : elle rend simplement fausse, en silence, la durée annoncée sur le site.
Un client cherche un dossier par son rôle, pas par son nom
La boîte a été créée depuis un client qui nomme ses dossiers « Deleted Messages » et « Sent Messages », quand la configuration livrée par Dovecot déclarait « Trash » et « Sent ». Un client de messagerie ne cherche pas un dossier par son nom mais par son rôle : ne trouvant pas de corbeille déclarée comme telle, le premier autre client à se connecter s'en serait créé une seconde, que la purge n'aurait pas vue. Les rôles ont donc été attribués aux dossiers existants et les noms concurrents désarmés, la purge couvrant malgré tout les deux conventions.
Bilan
Ce projet est celui où j'ai le plus appris sur l'exploitation, parce que rien n'y est simulé : un serveur mal configuré ne délivre pas de courrier, et un enregistrement DNS oublié envoie les messages en indésirables. Il m'a surtout appris à distinguer « configuré » de « fonctionnel ». Les quatre pannes levées sur la messagerie l'ont toutes été en lisant les journaux et en vérifiant l'état réel des services, jamais en relisant les fichiers de configuration. La partie DNS a été la plus instructive, parce que c'est là que l'audit a trouvé ce que le fonctionnement apparent cachait : le domaine ne publiait aucun enregistrement MX. Le courrier entrant arrivait quand même, par le repli sur l'enregistrement A prévu par la norme, si bien que rien ne signalait le manque. L'effet réel était ailleurs. Le SPF publié, « v=spf1 mx ~all », autorise les hôtes listés dans les MX : sans MX, il n'autorisait personne, et les messages sortants échouaient au SPF depuis le serveur légitime lui-même. Une fois le MX posé, le même raisonnement a fait apparaître un second trou : l'hôte mail n'avait pas d'enregistrement AAAA, alors que Postfix émet indifféremment en IPv4 et en IPv6, et le SPF ne couvrait donc qu'une famille d'adresses sur deux. Après correction, le SPF est évalué PASS dans les deux familles et le reverse IPv6 se confirme. La vérification finale ne vient pas de moi : un message envoyé vers Gmail revient avec dkim=pass, spf=pass et dmarc=pass, et l'en-tête de Google montre qu'il est parti en IPv6, le cas même qui échouait avant la correction. La bascule vers kanyro.fr a prolongé cette leçon sur un autre terrain. Changer de domaine ne consiste pas à remplacer un nom dans des fichiers : il faut décider dans quel ordre les morceaux bougent, garder l'ancien chemin ouvert pour ceux qui l'ont déjà noté, et accepter qu'une partie de la chaîne, le reverse DNS, ne se change pas depuis le serveur et impose donc d'attendre avant de modifier ce qui en dépend. Je retiens de ce projet qu'un service peut fonctionner tout en ayant perdu ses garanties, que seule une vérification menée depuis l'extérieur le montre, et qu'un serveur qui se déclare conforme ne prouve rien tant qu'un destinataire réel ne l'a pas confirmé.
Quelles compétences ?
B1.3
Développer la présence en ligne de l'organisation
E5
Voir dans la matriceB1.4
Travailler en mode projet
E5
Voir dans la matriceB1.5
Mettre à disposition des utilisateurs un service informatique
E5
Voir dans la matriceB2.1
Concevoir une solution d'infrastructure réseau
E6
Voir dans la matriceB2.2
Installer, tester et déployer une solution d'infrastructure réseau
E6
Voir dans la matriceB2.3
Exploiter, dépanner et superviser une solution d'infrastructure réseau
E6
Voir dans la matriceB3.1
Protéger les données à caractère personnel
E7
Voir dans la matriceB3.2
Préserver l'identité numérique de l'organisation
E7
Voir dans la matrice
Quelles preuves ?
- DémonstrationSite en production : kanyro.frDisponible
Service réellement mis à disposition, diffusé en HTTPS depuis le serveur administré.
- B1.3
- B1.5
- DémonstrationRedirection de l'ancien domaine vers le nouveauDisponible
Continuité de service après la bascule : l'ancienne adresse répond toujours et renvoie vers kanyro.fr, sans page d'erreur ni lien mort.
- B1.5
- B2.3
- DémonstrationPolitique de confidentialité : six traitements, leur base légale et leur duréeDisponible
Recensement des traitements de données personnelles du site, base légale de chacun, durée de conservation appliquée par un service de purge, personnes y ayant accès, absence de cookie et de mesure d'audience tierce, exercice des droits.
- B3.1
- DémonstrationMentions légales : éditeur, hébergeur et propriété intellectuelleDisponible
Identification de l'éditeur et de l'hébergeur telle que l'impose la LCEN, y compris la mention d'attente pendant l'immatriculation.
- B3.1
- B3.2
- DépôtDépôt Git du projetDisponible
Historique du projet, de la mise en production et de la bascule de domaine. Dépôt privé, ouvrable pendant la soutenance.
- B1.4
- ConfigurationDocumentation du serveur de messagerie et de la basculeDisponible
Architecture des services, ports, trajet d'un message, fichiers de configuration, enregistrements DNS requis, ordre de bascule d'un domaine et procédure de purge.
- B2.1
- B2.2
Déposer le fichier dans
public/documents/, puis renseignerhrefetstatus: "disponible". - SchémaSchéma du trajet d'un messageDisponible
Flux de réception et d'émission, position du milter OpenDKIM, socket LMTP, ports exposés et partage du certificat entre Caddy, Postfix et Dovecot.
- B2.1
- RapportRelevé de vérification de la chaîne de messagerieDisponible
Sorties réelles et reproductibles : état des services, ports en écoute, enregistrements DNS interrogés sur trois résolveurs, évaluation SPF par famille d'adresses, confirmation du reverse, opendkim-testkey, certificats TLS, journaux de la panne et de sa résolution, historique des trois défauts DNS corrigés, et le contrôle externe de la bascule du 20 septembre 2026.
- B2.1
- B2.2
- B2.3
- B3.2
- Capture d'écranEn-têtes d'un message validé par Gmail (DKIM, SPF et DMARC)Disponible
Verdict des serveurs de Google sur un message réel : dkim=pass, spf=pass et dmarc=pass. Le message est parti en IPv6, ce qui valide en production la correction de l'enregistrement AAAA. Section 9 du relevé de vérification.
- B2.2
- B2.3
- B3.2
Documents rattachés
- Schéma du trajet d'un message (kanyro.fr) : disponible
- Relevé de vérification de la chaîne de messagerie (kanyro.fr) : disponible
Fiche détaillée
Pourquoi ce projet figure dans ce portfolio
Kanyro est un service en ligne, avec un nom de domaine, un serveur et une boîte de réception qui doivent fonctionner sans surveillance. C’est ce qui le rend utile dans ce portfolio. Une maquette pardonne une erreur de configuration, un serveur de messagerie beaucoup moins : le message part en indésirables, ou ne part pas.
Le choix du statique, et ce qu’il impose
Le site vend de la visibilité en ligne. Il ne peut donc pas dépendre du navigateur du visiteur pour afficher son contenu : un moteur de recherche qui n’exécuterait pas le script trouverait une page vide. La sortie est entièrement statique et le seul script du site ne gère que des effets d’apparition.
Ce choix a une conséquence que je n’avais pas anticipée : les règles qui masquent les éléments avant leur apparition ne s’appliquent que si le navigateur exécute effectivement des scripts. Sans cette précaution, un visiteur sans JavaScript, ou dont le script échoue, se retrouve devant une page dont tout le contenu est resté invisible. La dégradation doit être prévue au moment où l’on écrit l’effet, pas après.
Ce que la messagerie m’a appris
Monter Postfix, Dovecot et OpenDKIM est la partie la plus proche du métier visé, et celle où l’écart entre « installé » et « qui marche » est le plus grand. Les quatre pannes rencontrées se ressemblent : dans chaque cas, la configuration était correcte et le service ne rendait pas le service attendu. Un démon qui redémarre en boucle faute des bons droits sur ses clés, un socket qui n’existe pas parce que le service n’a pas été relancé, un fichier d’utilisateurs référencé mais absent, un port déclaré mais muet.
J’en retiens une méthode plus qu’une liste de commandes : suivre le trajet réel du message, brique par brique, et vérifier à chaque étape l’état effectif du service (journaux, sockets en écoute, droits sur les fichiers) plutôt que de relire le fichier de configuration en espérant y voir l’erreur.
La partie invisible : le DNS
Un serveur de messagerie techniquement fonctionnel n’est pas pour autant un serveur crédible. Sans enregistrement SPF, sans clé DKIM publiée, sans politique DMARC et sans reverse DNS cohérent avec le nom annoncé, les grands fournisseurs classent les messages en indésirables ou les refusent. Cette partie ne se voit pas, ne produit aucune interface, et conditionne pourtant que le service serve à quelque chose.
En auditant la zone depuis trois résolveurs externes, j’ai trouvé une anomalie que je n’avais pas vue en travaillant depuis le serveur : le domaine ne publiait aucun enregistrement MX. La réception fonctionnait quand même, parce que la norme prévoit qu’un expéditeur sans MX se rabatte sur l’enregistrement A du domaine, qui pointe justement sur ce serveur. Le courrier arrivait donc, et rien ne signalait le manque.
L’effet réel était ailleurs. L’enregistrement SPF publié est v=spf1 mx ~all,
et le mécanisme mx autorise les hôtes déclarés dans les MX du domaine. Sans
aucun MX, il n’autorisait aucune adresse : tout message sortant, y compris
depuis le serveur légitime, retombait sur ~all et obtenait un SPF en échec.
Si les messages passaient malgré tout, c’est que DMARC se contente de SPF ou de
DKIM, et que la signature DKIM, elle, était valide et alignée.
Le MX posé, le même raisonnement a fait apparaître un second trou. Le mécanisme
mx résout les hôtes MX puis leurs adresses, mais la norme ne compare que les
adresses de la même famille que celle de l’expéditeur. Or l’hôte de messagerie
n’avait qu’un enregistrement A, quand Postfix émet indifféremment en IPv4 et en
IPv6 : le SPF ne couvrait donc qu’une famille sur deux, et le résultat dépendait
du protocole tiré au sort à chaque envoi. Ajouter l’AAAA de l’hôte a fermé le
trou, et aligner le reverse IPv6 sur ce même nom a rendu l’aller-retour
PTR → AAAA cohérent avec le nom annoncé en HELO.
C’est l’enseignement que je retiens de cet audit : une chaîne peut fonctionner en apparence tout en ayant perdu une de ses garanties, et seul un contrôle mené depuis l’extérieur le montre. Un serveur se croit toujours joignable.
La bascule vers kanyro.fr
Le 20 septembre 2026, le service est passé de kanyro.tech à kanyro.fr. La
raison n’est pas technique : un artisan du Pas-de-Calais fait davantage
confiance à un .fr qu’à une extension qu’il ne connaît pas. L’intérêt, pour ce
portfolio, est qu’une bascule de domaine touche à tout en même temps, le site,
les certificats, la messagerie et les deux zones DNS, et que chaque morceau
dépend des autres.
L’ordre s’impose de lui-même dès qu’on écrit les dépendances. Le DNS d’abord, parce que Caddy ne peut obtenir un certificat que pour un nom qui pointe déjà sur lui. Le site ensuite, adresses canoniques, plan de site, données structurées, mentions légales et conditions de vente basculant d’un seul geste, puisqu’ils lisent tous la même configuration, et l’ancien domaine se mettant à rediriger au même moment. Le courrier en dernier, et jamais en même temps que le reste : une messagerie mal migrée perd des demandes de devis sans que rien ne le signale, et ce sont les seuls messages qui rapportent quelque chose.
Trois décisions méritent d’être défendues à l’oral. L’ancienne adresse de messagerie n’a pas été supprimée mais transformée en renvoi : elle figure dans des devis déjà envoyés, et une adresse imprimée quelque part ne se rappelle pas. La redirection du site répond en 308 et non en 301 sur les envois de formulaire, parce qu’un 301 autorise le navigateur à rejouer un POST en GET, et qu’une demande de devis partie d’une page encore en cache serait arrivée vide. Enfin le serveur continue d’annoncer son ancien nom tant que le reverse DNS de son adresse IP, qui se change chez l’hébergeur et non dans la zone, n’a pas été modifié : annoncer le nouveau nom avant que le reverse ne le confirme casserait un accord existant pour en préparer un autre.
Les deux noms de serveur coexistent donc, et chacun présente son propre certificat grâce à SNI : les appareils configurés avant la bascule continuent de relever le courrier sans alerte de sécurité, ceux configurés après utilisent le nouveau nom. Vérification faite depuis l’extérieur, en annonçant explicitement chaque nom pendant la poignée de main.
Le piège du jour n’était pas sur le serveur mais dans la zone du nouveau domaine, qui servait déjà la messagerie du registraire. Ajouter les enregistrements sans retirer les anciens laissait deux SPF sur le même nom, ce qui ne se cumule pas mais produit une erreur permanente, et laissait surtout trois MX prioritaires sur celui du serveur, qui auraient capté la totalité du courrier entrant. Migrer une zone consiste autant à retirer qu’à ajouter.
Ce qu’un audit extérieur a changé
Le 11 septembre, le site a été audité comme le ferait un prestataire : chaque page rendue à cinq largeurs dans un navigateur sans interface, contrastes, tailles de texte et cibles tactiles mesurés, Web Vitals relevés en profil « 4G lente », en-têtes HTTP et zone DNS lus depuis l’extérieur. La note est tombée à 42 sur 100, et le constat le plus embarrassant tenait en une phrase : un site qui vend des pages rapides et lisibles sur téléphone chargeait 10 Mo pour un affichage du contenu principal en 22,6 secondes.
Les corrections ont porté sur le poids des médias, les contrastes, la taille des cibles tactiles et les en-têtes du serveur. Le même protocole, rejoué après correction, donne 164 Ko chargés et 2,1 secondes dans les mêmes conditions. Je retiens surtout la méthode : ce qui n’est pas mesuré depuis l’extérieur, dans les conditions du visiteur et non dans celles du développeur, n’est pas connu. C’est exactement la leçon de l’audit DNS, appliquée à l’autre moitié du projet.
Périmètre, et ce qui reste éteint
Le site compte aujourd’hui dix-sept adresses au plan du site : l’accueil, le contact, la réalisation livrée et sa fiche, six pages métier, trois guides et les trois pages légales. Les pages « métier × commune » prévues pour le référencement local restent éteintes par configuration. La raison est autant technique que commerciale : générer des dizaines de pages qui ne diffèrent que par un nom de commune correspond à la définition d’une page satellite, que les moteurs de recherche sanctionnent à l’échelle du domaine entier. La règle que je me suis fixée est de n’ajouter une commune qu’accompagnée d’un contexte écrit à la main, et le générateur ignore toute commune qui n’en a pas.
Ce qui reste à faire
Le reverse DNS de l’adresse IP du serveur désigne encore l’ancien nom : il se change chez l’hébergeur, et le nom annoncé par Postfix attend ce changement. Par ailleurs, le contrôle externe mené le jour de la bascule montre que l’hôte de messagerie du nouveau domaine ne publie qu’un enregistrement A, alors que le serveur dispose d’une adresse IPv6 et émet indifféremment dans les deux familles : c’est exactement le trou refermé en août sur l’ancien domaine, et le SPF du nouveau ne couvre donc à nouveau qu’une famille d’adresses sur deux. La correction est la même, un enregistrement AAAA sur l’hôte de messagerie, à poser avant de faire basculer le reverse.