Que sont les rapports DMARC ?
DMARC est l'acronyme de « Domain-based Message Authentication, Reporting, and Conformance ». Il s'agit d'un protocole d'authentification des e-mails qui contribue à offrir une protection contre les attaques par phishing et par usurpation d'identité véhiculées par e-mail.
Lorsqu'un e-mail est envoyé, DMARC permet au propriétaire du domaine de configurer un enregistrement DNS afin de spécifier quelles méthodes d'authentification, telles que SPF (Sender Policy Framework) et DKIM (DomainKeys Identified Mail), seront utilisées pour vérifier l'authenticité de l'e-mail. En cas d'échec des vérifications d'authentification de l'e-mail, DMARC indique au fournisseur du service de messagerie du destinataire comment traiter le message, en le mettant en quarantaine ou en le rejetant d'emblée.
DMARC a acquis une grande importance sur l'Internet moderne, où les attaques par phishing et par usurpation d'identité deviennent toujours plus sophistiquées et répandues. En mettant en œuvre DMARC, les propriétaires de domaines peuvent protéger leur marque et leurs clients contre les effets délétères de ces attaques, notamment la perte de confiance, l'atteinte à la réputation et les pertes financières.
En plus d'offrir une protection contre les attaques par phishing et par usurpation d'identité, DMARC fournit également des fonctionnalités de création de rapports. Les propriétaires de domaines peuvent ainsi recevoir des rapports détaillant l'activité d'authentification des e-mails, mentionnant notamment les messages acceptés ou refusés à l'issue des contrôles DMARC, ainsi que l'origine de ces messages.
La gestion de DMARC implique d'effectuer la configuration et la maintenance des politiques DMARC pour un domaine. Une gestion efficace de DMARC repose sur le contrôle et l'analyse continus des activités d'authentification des e-mails, ainsi que sur la capacité d'effectuer des ajustements et des mises à jour des politiques DMARC, selon les besoins.
Les éléments essentiels d'une gestion efficace de DMARC incluent notamment :
La configuration de politiques DMARC : il s'agit de configurer l'enregistrement DMARC du domaine, afin de spécifier les méthodes d'authentification appropriées et les politiques de traitement des messages pour lesquels les vérifications de l'authentification ont échoué. Voici à quoi ressemble un enregistrement DNS DMARC :
v=DMARC1; p=reject; rua=mailto:[email protected]
Il précise que nous allons utiliser la version 1 de DMARC, et que notre politique consiste à rejeter les e-mails en cas d'échec des vérifications de DMARC ; il indique également l'adresse e-mail à laquelle les fournisseurs doivent envoyer les rapports DMARC.
La surveillance des activités d'authentification des e-mails : les rapports DMARC sont un outil important pour les propriétaires de domaines ; ils permettent de garantir la sécurité et la distribution des e-mails, ainsi que la conformité aux normes et réglementations sectorielles. En contrôlant et en analysant régulièrement les rapports DMARC, les propriétaires de domaines peuvent identifier les menaces liées aux e-mails, optimiser les campagnes de diffusion d'e-mails et améliorer l'authentification de la messagerie dans son ensemble.
La mise en œuvre des ajustements, selon le besoin : sur la base de l'analyse des rapports DMARC, les propriétaires de domaines peuvent avoir besoin d'ajuster les politiques DMARC ou les méthodes d'authentification, afin de s'assurer que les e-mails sont correctement authentifiés et protégés contre les attaques par phishing et par usurpation d'identité.
La collaboration avec les fournisseurs de services de messagerie et les fournisseurs tiers : une gestion efficace de DMARC peut nécessiter de collaborer avec les fournisseurs de services de messagerie et les fournisseurs tiers afin d'assurer la mise en œuvre et l'application correctes des politiques DMARC.
Aujourd'hui, nous avons lancé DMARC Management. Voici comment nous avons développé cette solution.
Comment nous avons développé la solution
Cloudflare est un éminent principal fournisseur de solutions d'amélioration de la sécurité et des performances dans le cloud, et adopte donc une approche spécifique pour tester ses produits. Nous utilisons nous-mêmes les outils et services que nous proposons dans le cadre de la gestion de nos activités. Cela nous permet d'identifier d'éventuels problèmes ou bugs avant qu'ils n'affectent nos clients.
Nous utilisons nos produits en interne – par exemple, Cloudflare Workers, une plateforme serverless qui permet aux développeurs d'exécuter leur code sur notre réseau mondial. Depuis son lancement en 2017, l'écosystème Workers s'est considérablement développé. Aujourd'hui, des milliers de développeurs créent et déploient des applications sur la plateforme. La puissance de l'écosystème Workers réside dans sa capacité à permettre aux développeurs de créer des applications sophistiquées, qu'il était auparavant impossible ou peu pratique d'exécuter si près des clients. Des instances Workers peuvent être mises en œuvre pour créer des API, générer du contenu dynamique, optimiser des images, exécuter un traitement en temps réel et bien davantage. Les possibilités sont pratiquement infinies. Nous avons utilisé Workers pour exécuter des services tels que Radar 2.0 ou des logiciels tels que Wildebeest.
Récemment, nous avons associé notre solution de routage des e-mails à Workers afin de permettre le traitement des e-mails entrants via des scripts Workers. Comme l'indique la documentation : « Avec Email Workers, vous pouvez tirer parti de la puissance de Cloudflare Workers afin de mettre en œuvre toute logique nécessaire au traitement de vos e-mails et à la création de règles complexes. Ces règles déterminent ce qui se passe lorsque vous recevez un e-mail. » Les règles et les adresses vérifiées peuvent toutes être configurées via notre API.
Voici à quoi ressemble une instance Email Workers simple :
Rien de bien compliqué, n'est-ce pas ?
export default {
async email(message, env, ctx) {
const allowList = ["[email protected]", "[email protected]"];
if (allowList.indexOf(message.headers.get("from")) == -1) {
message.setReject("Address not allowed");
} else {
await message.forward("inbox@corp");
}
}
}
La capacité de traiter de manière programmatique les e-mails entrants semblait offrir un moyen idéal de traiter, de manière évolutive et efficace, les e-mails entrants contenant les rapports DMARC ; elle permettait de laisser la solution de routage des e-mails et Workers effectuer le gros du travail consistant à recevoir un nombre illimité d'e-mails provenant du monde entier. Voici une description de haut niveau des fonctionnalités dont nous avions besoin :
Recevoir des e-mails et extraire un rapport
Publier les détails pertinents sur la plateforme d'analyse des données
Stocker le rapport brut
Les instances Email Workers nous permettent de répondre facilement au premier de ces besoins. Il suffit de créer une instance Workers avec un handler email(). Ce handler reçoit les éléments de l'enveloppe SMTP, une version pré-analysée des en-têtes d'e-mails et un flux permettant de lire l'intégralité de l'e-mail brut.
Pour le deuxième de ces besoins, nous pouvons encore une fois nous tourner vers la plateforme Workers, et plus particulièrement vers Workers Analytics Engine. Il suffit de définir un schéma approprié, qui dépend à la fois des informations présentées dans les rapports et des requêtes que nous prévoyons d'exécuter ultérieurement. Ensuite, nous pouvons interroger les données avec l'API GraphQL ou SQL.
Enfin, pour le troisième de ces besoins, nous n'avons pas besoin de chercher plus loin que notre solution de stockage d'objets R2. Il est extrêmement simple d'accéder à R2 depuis une instance Workers. Après avoir extrait les rapports des e-mails, nous pouvons les stocker dans R2, pour la postérité.
Nous avons conçu cette solution sous la forme d'un service géré que vous pouvez activer pour votre zone, et nous lui avons ajouté une interface de tableau de bord pour plus de praticité. En réalité, toutefois, tous les outils sont disponibles pour vous permettre de déployer votre propre service de traitement de rapports DMARC via Cloudflare Workers, dans votre compte, sans devoir vous préoccuper des serveurs, de l'évolutivité ou des performances.
Architecture
Email Workers est une fonctionnalité de notre solution de routage des e-mails. Le composant de routage des e-mails s'exécute sur tous les nœuds de Cloudflare ; ainsi, n'importe quel nœud est en mesure de traiter les e-mails entrants. C'est important, car Cloudflare annonce le préfixe BGP des e-mails entrants depuis tous ses datacenters. L'envoi d'e-mails à une instance Email Workers est extrêmement simple, puisqu'il suffit de définir une règle sur le tableau de bord de la solution de routage des e-mails.
Lorsque le composant de routage des e-mails reçoit un e-mail qui correspond à une règle de remise à une instance Workers, il contacte la version interne du runtime workerd, récemment publié en open source, qui s'exécute également sur tous les nœuds. Le schéma RPC qui régit cette interaction est défini dans un schéma Capnproto, et permet la diffusion en continu du corps de l'e-mail à Edgeworker au fur et à mesure de sa lecture. Si le script Workers décide de transférer cet e-mail, Edgeworker contacte le composant de routage des e-mails à l'aide d'une fonctionnalité envoyée dans la requête initiale.
Dans le contexte des rapports DMARC, voici comment nous traitons les e-mails entrants :
jsg::Promise<void> ForwardableEmailMessage::forward(kj::String rcptTo, jsg::Optional<jsg::Ref<Headers>> maybeHeaders) {
auto req = emailFwdr->forwardEmailRequest();
req.setRcptTo(rcptTo);
auto sendP = req.send().then(
[](capnp::Response<rpc::EmailMetadata::EmailFwdr::ForwardEmailResults> res) mutable {
auto result = res.getResponse().getResult();
JSG_REQUIRE(result.isOk(), Error, result.getError());
});
auto& context = IoContext::current();
return context.awaitIo(kj::mv(sendP));
}
Récupération du destinataire de l'e-mail en cours de traitement ; il s'agit du RUA utilisé. Le RUA est un paramètre de configuration DMARC, qui indique où doivent être transmises les informations concernant le traitement DMARC pour un domaine donné. Ce destinataire peut être trouvé dans l'attribut « To » (destinataire) du message.
const ruaID = message.to
Puisque nous traitons les rapports DMARC pour un nombre illimité de domaines, nous utilisons Workers KV pour stocker des informations concernant chacun d'eux et nous intégrons ces informations au RUA. Ceci nous permet également de savoir si nous devons recevoir ces rapports.
const accountInfoRaw = await env.KV_DMARC_REPORTS.get(dmarc:${ruaID})
À ce stade, nous voulons lire l'intégralité de l'e-mail dans un arrayBuffer, afin de l'analyser. En fonction de la taille du rapport, il est possible que nous atteignions les limites de l'offre gratuite Workers. Si c'est le cas, nous vous recommandons d'opter pour le modèle de ressources Workers Unbound, qui ne comporte pas cette limitation.
const rawEmail = new Response(message.raw) const arrayBuffer = await rawEmail.arrayBuffer()
L'analyse de l'e-mail brut implique, entre autres, l'analyse de ses composantes MIME ; de nombreuses bibliothèques sont disponibles à cette fin. Vous pouvez, par exemple, utiliser postal-mime:
const parser = new PostalMime.default() const email = await parser.parse(arrayBuffer)
Maintenant que nous avons analysé l'e-mail, nous avons accès à ses pièces jointes. Ces pièces jointes sont les rapports DMARC eux-mêmes, et elles peuvent être compressées. La première chose à faire est de les stocker sous leur forme compressée dans R2, aux fins du stockage à long terme. Elles peuvent être utiles ultérieurement, à des fins de retraitement ou d'examen de rapports intéressants. Pour cela, il suffit d'invoquer put() sur la liaison R2. Pour faciliter une éventuelle récupération ultérieure, nous vous recommandons de placer les fichiers des rapports dans différents répertoires, nommés en fonction de l'heure actuelle.
await env.R2_DMARC_REPORTS.put(
${date.getUTCFullYear()}/${date.getUTCMonth() + 1}/${attachment.filename}
, attachment.content )Nous devons maintenant examiner le type de mime de la pièce jointe. Le format brut des rapports DMARC est XML, mais ces derniers peuvent être compressés ; dans ce cas, nous devons d'abord les décompresser. Les fichiers de l'outil de création de rapports DMARC peuvent utiliser plusieurs algorithmes de compression ; nous utilisons le type MIME pour déterminer lequel utiliser. Pour les rapports compressés au format zlib, nous pouvons utiliser pako, tandis qu' unzipit est un choix intéressant pour les rapports compressés au format zip.
Après avoir extrait le format XML brut du rapport, fast-xml-parser s'est avéré être un outil efficace aux fins de l'analyse. Voici à quoi ressemble le rapport DMARC au format XML :
Nous disposons à présent de toutes les données contenues dans le rapport. Ce que nous allons faire maintenant dépend fortement de la manière dont nous souhaitons présenter les données. Pour nous, l'objectif était d'afficher des données pertinentes extraites du rapport sur notre tableau de bord. C'est pourquoi nous avions besoin d'une plateforme d'analyse de données à laquelle nous pourrions transmettre les données enrichies. C'est ici qu'entre en scène Workers Analytics Engine. Analytics Engine est parfaitement adapté à cette tâche, puisqu'il nous permet de transmettre des données depuis une instance Workers et expose une API GraphQL pour interagir avec les données par la suite. C'est ainsi que nous obtenons les données à afficher sur notre tableau de bord.
À l'avenir, nous envisageons également l'intégration de Queues au flux de travail, afin d'assurer un traitement asynchrone des rapports et d'éviter d'attendre la fin du traitement par le client.
const ruaID = message.to
Nous avons réussi à mettre en œuvre l'intégralité de ce projet en nous appuyant uniquement sur l'infrastructure Workers. Cela démontre qu'il est possible, et même avantageux, de créer des applications non triviales sans devoir se préoccuper des problématiques d'évolutivité, de performance, de stockage et de sécurité.
const accountInfoRaw = await env.KV_DMARC_REPORTS.get(dmarc:${ruaID})
Publication open source
const rawEmail = new Response(message.raw)
const arrayBuffer = await rawEmail.arrayBuffer()
Comme nous l'avons déjà mentionné, nous avons développé un service géré que vous pouvez activer et utiliser, et nous le gérerons pour vous. Cependant, vous pouvez également déployer vous-même tout ce que nous avons créé, dans votre compte, afin de gérer vos propres rapports DMARC. C'est simple et gratuit. Pour vous aider, nous publions une version open source d'une instance Workers permettant le traitement des rapports DMARC conformément à l'approche décrite ci-dessus : https://github.com/cloudflare/dmarc-email-worker
const parser = new PostalMime.default()
const email = await parser.parse(arrayBuffer)
Si vous ne disposez pas d'un tableau de bord dans lequel présenter les données, vous pouvez également interroger Analytics Engine depuis une instance Workers. Ou, si vous souhaitez stocker les données dans une base de données relationnelle, D1 est à votre disposition. Les possibilités sont infinies, et nous sommes impatients de découvrir ce que vous allez créer avec ces outils.
await env.R2_DMARC_REPORTS.put(
`${date.getUTCFullYear()}/${date.getUTCMonth() + 1}/${attachment.filename}`,
attachment.content
)
N'hésitez pas à apporter votre contribution et à développer vos propres solutions ; nous sommes à votre écoute.
<feedback>
<report_metadata>
<org_name>example.com</org_name>
<[email protected]</email>
<extra_contact_info>http://example.com/dmarc/support</extra_contact_info>
<report_id>9391651994964116463</report_id>
<date_range>
<begin>1335521200</begin>
<end>1335652599</end>
</date_range>
</report_metadata>
<policy_published>
<domain>business.example</domain>
<adkim>r</adkim>
<aspf>r</aspf>
<p>none</p>
<sp>none</sp>
<pct>100</pct>
</policy_published>
<record>
<row>
<source_ip>192.0.2.1</source_ip>
<count>2</count>
<policy_evaluated>
<disposition>none</disposition>
<dkim>fail</dkim>
<spf>pass</spf>
</policy_evaluated>
</row>
<identifiers>
<header_from>business.example</header_from>
</identifiers>
<auth_results>
<dkim>
<domain>business.example</domain>
<result>fail</result>
<human_result></human_result>
</dkim>
<spf>
<domain>business.example</domain>
<result>pass</result>
</spf>
</auth_results>
</record>
</feedback>
Conclusions
Nous espérons que cet article vous a permis de mieux comprendre le fonctionnement de la plateforme Workers. Cloudflare utilise aujourd'hui cette plateforme pour développer la plupart de ses services, et nous pensons que vous devriez en faire autant.
N'hésitez pas à contribuer à notre version open source et à nous montrer ce que vous pouvez accomplir avec elle.
La solution de routage des e-mails contribue également à l'extension de l'API Email Workers d'un point de vue plus fonctionnel. Toutefois, cela mérite un autre article de blog, qui lui sera prochainement consacré.