jogold / cloudstructs

High-level constructs for AWS CDK
Apache License 2.0
155 stars 11 forks source link

Feature Request: DMARC report analyzer #230

Closed andreialecu closed 1 year ago

andreialecu commented 1 year ago

Hey, @jogold, I just stumbled upon this repo. There are a bunch of really cool and helpful things here. Thanks for making them available!

One construct I've been working on is an automated way to parse DMARC report emails via a lambda + SES and notify a Slack channel of any failures. Unfortunately, I got sidetracked and still need to finish it.

I see an EmailReceiver and a bunch of Slack-related constructs here, so perhaps you would also be interested in this.

I'll see if I can finish mine and contribute it here. Is this something that would be interesting to merge?

andreialecu commented 1 year ago

For more context, something like this: https://github.com/domainaware/parsedmarc but simply posts to Slack instead of being a full-fledged dashboard.

jogold commented 1 year ago

Hi @andreialecu,

Thanks for the suggestion. I'm not really familiar with DMARC reports... how would it exactly work in AWS?

andreialecu commented 1 year ago

DMARC (Domain-based Message Authentication, Reporting, and Conformance) is a protocol that helps protect email domains from unauthorized use, such as phishing and email spoofing. DMARC reports are generated by email receivers (like Gmail, Yahoo, etc.) and sent to domain owners to provide insight into the authentication status of emails sent on their behalf.

DMARC is configured in DNS via route 53 as a TXT record that would look something like this:

_dmarc.example.com.  3600 IN TXT "v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com;"

In this example, DMARC reports for the domain example.com will be sent to the email address dmarc-reports@example.com.

Now we'd basically need to intercept emails sent to that address and parse the .xml reports being received. See an example report here: https://support.google.com/a/answer/10032472?hl=en#zippy=%2Cexample-dmarc-report-in-raw-xml-format.

Attaching it below for brevity:

<?xml version="1.0" encoding="UTF-8" ?>
<feedback>
  <report_metadata>
    <org_name>solarmora.com</org_name>
    <email>noreply-dmarc-support@solarmora.com</email>
   <extra_contact_info>http://solarmora.com/dmarc/support</extra_contact_info>
    <report_id>9391651994964116463</report_id>
    <date_range>
      <begin>1335571200</begin>
      <end>1335657599</end>
    </date_range>
  </report_metadata>
  <policy_published>
    <domain>bix-business.com</domain>
    <adkim>r</adkim>
    <aspf>r</aspf>
    <p>none</p>
    <sp>none</sp>
    <pct>100</pct>
  </policy_published>
  <record>
    <row>
      <source_ip>203.0.113.209</source_ip>
      <count>2</count>
      <policy_evaluated>
        <disposition>none</disposition>
        <dkim>fail</dkim>
        <spf>pass</spf>
      </policy_evaluated>
    </row>
    <identifiers>
      <header_from>bix-business.com</header_from>
    </identifiers>
    <auth_results>
      <dkim>
        <domain>bix-business.com</domain>
        <result>fail</result>
        <human_result></human_result>
      </dkim>
      <spf>
        <domain>bix-business.com</domain>
        <result>pass</result>
      </spf>
    </auth_results>
  </record>
</feedback>

Notice how there's a dkim fail somewhere in this one. We can use xml2js to parse it.

The slightly tricky thing is that Google sends these reports compressed in .zip format, while most others send it in .gz format. So we'd need to extract the attachment before parsing it.

Everything else should be relatively straight forward.

jogold commented 1 year ago

Hey @andreialecu!

Thanks for the explanation.

I'm not sure I want to have the parsing of the xml of the DMARC report in here. Maybe we can have a construct that creates the DNS entry and the email receiving part?

const dmarcReporter = new DmarcReporter(this, 'DmarcReporter', {
  hostedZone: myHostedZone,
  bucket: myBucket, // optional, defaults to creating a new bucket
});

// now my XML reports are saved to
dmarcReporter.bucket

// create here infra to process my XML reports

WDYT?

andreialecu commented 1 year ago

That sounds like a good start! I sent a connection request on LinkedIn (not sure where else to find you 😃) where I could share a bit more info on this if you'd like, for a jumpstart.

andreialecu commented 1 year ago

I started something in #232 - not much yet, but I hope it helps.

andreialecu commented 1 year ago

Note that I also made a library to parse DMARC report emails, which has passed its tests so far. I'll start testing it in production within a few days:

https://github.com/andreialecu/dmarc-report-parser