This commit is contained in:
Sean Whalen
2019-02-10 13:15:55 -05:00
parent 8c593a2b22
commit 71d2581c35
13 changed files with 169 additions and 48 deletions
+2 -2
View File
@@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Overview: module code &mdash; parsedmarc 6.0.1 documentation</title>
<title>Overview: module code &mdash; parsedmarc 6.0.2 documentation</title>
@@ -56,7 +56,7 @@
<div class="version">
6.0.1
6.0.2
</div>
+7 -10
View File
@@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>parsedmarc &mdash; parsedmarc 6.0.1 documentation</title>
<title>parsedmarc &mdash; parsedmarc 6.0.2 documentation</title>
@@ -56,7 +56,7 @@
<div class="version">
6.0.1
6.0.2
</div>
@@ -183,7 +183,7 @@
<span class="kn">from</span> <span class="nn">parsedmarc.utils</span> <span class="k">import</span> <span class="n">timestamp_to_human</span><span class="p">,</span> <span class="n">human_timestamp_to_datetime</span>
<span class="kn">from</span> <span class="nn">parsedmarc.utils</span> <span class="k">import</span> <span class="n">parse_email</span>
<span class="n">__version__</span> <span class="o">=</span> <span class="s2">&quot;6.0.1&quot;</span>
<span class="n">__version__</span> <span class="o">=</span> <span class="s2">&quot;6.0.2&quot;</span>
<span class="n">logging</span><span class="o">.</span><span class="n">basicConfig</span><span class="p">(</span>
<span class="nb">format</span><span class="o">=</span><span class="s1">&#39;</span><span class="si">%(levelname)8s</span><span class="s1">:</span><span class="si">%(filename)s</span><span class="s1">:</span><span class="si">%(lineno)d</span><span class="s1">:&#39;</span>
@@ -1140,7 +1140,10 @@
<span class="n">raw_msg</span> <span class="o">=</span> <span class="n">raw_msg</span><span class="p">[</span><span class="n">msg_key</span><span class="p">]</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">ConnectionResetError</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">error</span><span class="p">,</span>
<span class="ne">TimeoutError</span><span class="p">)</span> <span class="k">as</span> <span class="n">error</span><span class="p">:</span>
<span class="ne">TimeoutError</span><span class="p">,</span>
<span class="n">imapclient</span><span class="o">.</span><span class="n">exceptions</span><span class="o">.</span><span class="n">IMAPClientError</span><span class="p">)</span> <span class="k">as</span> <span class="n">error</span><span class="p">:</span>
<span class="n">error</span> <span class="o">=</span> <span class="n">error</span><span class="o">.</span><span class="fm">__str__</span><span class="p">()</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s2">&quot;b&#39;&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">rstrip</span><span class="p">(</span><span class="s2">&quot;&#39;&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">rstrip</span><span class="p">(</span>
<span class="s2">&quot;.&quot;</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;IMAP error: </span><span class="si">{0}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">error</span><span class="o">.</span><span class="fm">__str__</span><span class="p">()))</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Reconnecting to IMAP&quot;</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
@@ -1172,12 +1175,6 @@
<span class="k">elif</span> <span class="n">parsed_email</span><span class="p">[</span><span class="s2">&quot;report_type&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;forensic&quot;</span><span class="p">:</span>
<span class="n">forensic_reports</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">parsed_email</span><span class="p">[</span><span class="s2">&quot;report&quot;</span><span class="p">])</span>
<span class="n">forensic_report_msg_uids</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">msg_uid</span><span class="p">)</span>
<span class="k">except</span> <span class="n">imapclient</span><span class="o">.</span><span class="n">exceptions</span><span class="o">.</span><span class="n">IMAPClientError</span> <span class="k">as</span> <span class="n">error</span><span class="p">:</span>
<span class="n">error</span> <span class="o">=</span> <span class="n">error</span><span class="o">.</span><span class="fm">__str__</span><span class="p">()</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s2">&quot;b&#39;&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">rstrip</span><span class="p">(</span><span class="s2">&quot;&#39;&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">rstrip</span><span class="p">(</span><span class="s2">&quot;.&quot;</span><span class="p">)</span>
<span class="n">error</span> <span class="o">=</span> <span class="s2">&quot;IMAP error: Skipping message UID </span><span class="si">{0}</span><span class="s2">: </span><span class="si">{1}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">msg_uid</span><span class="p">,</span> <span class="n">error</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;IMAP error: </span><span class="si">{0}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">error</span><span class="p">))</span>
<span class="k">except</span> <span class="n">InvalidDMARCReport</span> <span class="k">as</span> <span class="n">error</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="n">error</span><span class="o">.</span><span class="fm">__str__</span><span class="p">())</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">test</span><span class="p">:</span>
+2 -2
View File
@@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>parsedmarc.elastic &mdash; parsedmarc 6.0.1 documentation</title>
<title>parsedmarc.elastic &mdash; parsedmarc 6.0.2 documentation</title>
@@ -56,7 +56,7 @@
<div class="version">
6.0.1
6.0.2
</div>
+2 -2
View File
@@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>parsedmarc.splunk &mdash; parsedmarc 6.0.1 documentation</title>
<title>parsedmarc.splunk &mdash; parsedmarc 6.0.2 documentation</title>
@@ -56,7 +56,7 @@
<div class="version">
6.0.1
6.0.2
</div>
+22 -12
View File
@@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>parsedmarc.utils &mdash; parsedmarc 6.0.1 documentation</title>
<title>parsedmarc.utils &mdash; parsedmarc 6.0.2 documentation</title>
@@ -56,7 +56,7 @@
<div class="version">
6.0.1
6.0.2
</div>
@@ -162,6 +162,7 @@
<span class="kn">import</span> <span class="nn">hashlib</span>
<span class="kn">import</span> <span class="nn">base64</span>
<span class="kn">import</span> <span class="nn">platform</span>
<span class="kn">import</span> <span class="nn">atexit</span>
<span class="kn">import</span> <span class="nn">dateparser</span>
<span class="kn">import</span> <span class="nn">dns.reversename</span>
@@ -172,7 +173,7 @@
<span class="kn">import</span> <span class="nn">requests</span>
<span class="kn">import</span> <span class="nn">publicsuffix</span>
<span class="n">__version__</span> <span class="o">=</span> <span class="s2">&quot;5.0.2&quot;</span>
<span class="n">__version__</span> <span class="o">=</span> <span class="s2">&quot;6.0.2&quot;</span>
<span class="n">USER_AGENT</span> <span class="o">=</span> <span class="s2">&quot;Mozilla/5.0 ((0 </span><span class="si">{1}</span><span class="s2">)) parsedmarc/</span><span class="si">{2}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">platform</span><span class="o">.</span><span class="n">system</span><span class="p">(),</span>
@@ -183,6 +184,16 @@
<span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s2">&quot;parsedmarc&quot;</span><span class="p">)</span>
<span class="n">tempdir</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mkdtemp</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">_cleanup</span><span class="p">():</span>
<span class="sd">&quot;&quot;&quot;Remove temporary files&quot;&quot;&quot;</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">rmtree</span><span class="p">(</span><span class="n">tempdir</span><span class="p">)</span>
<span class="n">atexit</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">_cleanup</span><span class="p">)</span>
<div class="viewcode-block" id="EmailParserError"><a class="viewcode-back" href="../../index.html#parsedmarc.utils.EmailParserError">[docs]</a><span class="k">class</span> <span class="nc">EmailParserError</span><span class="p">(</span><span class="ne">RuntimeError</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Raised when an error parsing the email occurs&quot;&quot;&quot;</span></div>
@@ -224,7 +235,7 @@
<span class="sd"> str: The base domain of the given domain</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">psl_path</span> <span class="o">=</span> <span class="s2">&quot;.public_suffix_list.dat&quot;</span>
<span class="n">psl_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">tempdir</span><span class="p">,</span> <span class="s2">&quot;public_suffix_list.dat&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">download_psl</span><span class="p">():</span>
<span class="n">url</span> <span class="o">=</span> <span class="s2">&quot;https://publicsuffix.org/list/public_suffix_list.dat&quot;</span>
@@ -399,8 +410,6 @@
<span class="sd"> Returns:</span>
<span class="sd"> str: And ISO country code associated with the given IP address</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">db_filename</span> <span class="o">=</span> <span class="s2">&quot;.GeoLite2-Country.mmdb&quot;</span>
<span class="k">def</span> <span class="nf">download_country_database</span><span class="p">(</span><span class="n">location</span><span class="o">=</span><span class="s2">&quot;.GeoLite2-Country.mmdb&quot;</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Downloads the MaxMind Geolite2 Country database</span>
@@ -422,22 +431,23 @@
<span class="n">system_paths</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;/usr/local/share/GeoIP/GeoLite2-Country.mmdb&quot;</span><span class="p">,</span>
<span class="s2">&quot;/usr/share/GeoIP/GeoLite2-Country.mmdb&quot;</span><span class="p">]</span>
<span class="n">db_path</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">db_path</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">for</span> <span class="n">system_path</span> <span class="ow">in</span> <span class="n">system_paths</span><span class="p">:</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">system_path</span><span class="p">):</span>
<span class="n">db_path</span> <span class="o">=</span> <span class="n">system_path</span>
<span class="k">break</span>
<span class="k">if</span> <span class="n">db_path</span> <span class="o">==</span> <span class="s2">&quot;&quot;</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">db_filename</span><span class="p">):</span>
<span class="n">download_country_database</span><span class="p">(</span><span class="n">db_filename</span><span class="p">)</span>
<span class="k">if</span> <span class="n">db_path</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">db_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">tempdir</span><span class="p">,</span> <span class="s2">&quot;GeoLite2-Country.mmdb&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">db_path</span><span class="p">):</span>
<span class="n">download_country_database</span><span class="p">(</span><span class="n">db_path</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">db_age</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span> <span class="o">-</span> <span class="n">datetime</span><span class="o">.</span><span class="n">fromtimestamp</span><span class="p">(</span>
<span class="n">os</span><span class="o">.</span><span class="n">stat</span><span class="p">(</span><span class="n">db_filename</span><span class="p">)</span><span class="o">.</span><span class="n">st_mtime</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">stat</span><span class="p">(</span><span class="n">db_path</span><span class="p">)</span><span class="o">.</span><span class="n">st_mtime</span><span class="p">)</span>
<span class="k">if</span> <span class="n">db_age</span> <span class="o">&gt;</span> <span class="n">timedelta</span><span class="p">(</span><span class="n">days</span><span class="o">=</span><span class="mi">60</span><span class="p">):</span>
<span class="n">download_country_database</span><span class="p">()</span>
<span class="n">db_path</span> <span class="o">=</span> <span class="n">db_filename</span>
<span class="n">db_path</span> <span class="o">=</span> <span class="n">db_path</span>
<span class="n">db_reader</span> <span class="o">=</span> <span class="n">geoip2</span><span class="o">.</span><span class="n">database</span><span class="o">.</span><span class="n">Reader</span><span class="p">(</span><span class="n">db_path</span><span class="p">)</span>
+63 -5
View File
@@ -137,7 +137,7 @@ The full set of configuration options are:
- ``save_forensic`` - bool: Save forensic report data to the Elasticsearch and/or Splunk
- ``strip_attachments_payloads`` - bool: Remove attachment payloads from results
- ``output`` - str: Directory to place JSON and CSV files in
- ``nameservers`` - str: A comma separated list of DNS resolvers (Default: Cloudflare's public resolvers)
- ``nameservers`` - str: A comma separated list of DNS resolvers (Default: `Cloudflare's public resolvers`_)
- ``dns_timeout`` - float: DNS timeout period
- ``debug`` - bool: Print debugging messages
- ``silent`` - bool: Only print errors (Default: True)
@@ -185,6 +185,16 @@ The full set of configuration options are:
- ``message`` - str: The email message (Default: Please see the attached parsedmarc report.)
.. warning::
It is **strongly recommended** to **not** use the ``nameservers`` setting.
By default, ``parsedmarc`` uses `Cloudflare's public resolvers`_,
which are much faster and more reliable than Google, Cisco OpenDNS, or
even most local resolvers.
The ``nameservers`` option should only be used if your network blocks DNS
requests to outside resolvers.
.. warning::
``save_aggregate`` and ``save_forensic`` are separate options because
@@ -203,10 +213,10 @@ The full set of configuration options are:
it is normal to receive very few forensic reports.
An alternative approach is to still collect forensic/failure/ruf reports
in your DMARC inbox, but run ``parsedmarc`` with ``save_forensic = True`` manually on a
separate IMAP folder (using the ``reports_folder`` option), after you have manually
moved known samples you want to save to that folder (e.g. malicious
samples and non-sensitive legitimate samples).
in your DMARC inbox, but run ``parsedmarc`` with ``save_forensic = True``
manually on a separate IMAP folder (using the ``reports_folder`` option),
after you have manually moved known samples you want to save to that
folder (e.g. malicious samples and non-sensitive legitimate samples).
Sample aggregate report output
==============================
@@ -1164,6 +1174,46 @@ What if a sender won't support DKIM/DMARC?
Top-Level Domain (TLD) that would leave you vulnerable to spoofing of
your TLD and/or any subdomain.
What about mailing lists?
=========================
When you deploy DMARC on your domain, you might find that messages relayed by
mailing lists are failing DMARC. This has two causes:
#. You are not DKIM signing your mail like you should be
#. The mailing list is altering emails in ways that are not DMARC compliant
before sending them
`Joe Nelson`_ does a fantastic job of explaining exactly what mailing lists
should and shouldn't do to be DMARC compliant. Rather than repeat his fine
work, here's a TL;DR:
If you run a mailing list
-------------------------
**Do**
- Retain headers from the original message
- Add `RFC 2369`_ List-Unsubscribe headers to outgoing messages, instead of
adding unsubscribe links to the body
::
List-Unsubscribe: <https://list.example.com/unsubscribe-link>
- Add `RFC 2919`_ List-Id headers instead of modifying the subject
::
List-Id: Example Mailing List <list.example.com>
**Do not**
* Remove or modify any existing headers from the original message, including
From, Date, Subject, etc.
* Add to or remove content from the message body, **including traditional
disclaimers and unsubscribe footers**
API
===
@@ -1217,6 +1267,8 @@ Indices and tables
.. _Demystifying DMARC: https://seanthegeek.net/459/demystifying-dmarc/
.. _Cloudflare's public resolvers: https://1.1.1.1/
.. _download the latest portable Linux version of pypy3: https://github.com/squeaky-pl/portable-pypy#portable-pypy-distribution-for-linux
.. _Elasticsearch: https://www.elastic.co/guide/en/elasticsearch/reference/current/rpm.html
@@ -1232,3 +1284,9 @@ Indices and tables
.. _HTTP Event collector (HEC): http://docs.splunk.com/Documentation/Splunk/latest/Data/AboutHEC
.. _XML files: https://github.com/domainaware/parsedmarc/tree/master/splunk
.. _Joe Nelson: https://begriffs.com/posts/2018-09-18-dmarc-mailing-list.html
.. _RFC 2369: https://tools.ietf.org/html/rfc2369
.. _RFC 2919: https://tools.ietf.org/html/rfc2919
+1 -1
View File
@@ -1,6 +1,6 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '6.0.1',
VERSION: '6.0.2',
LANGUAGE: 'None',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
+2 -2
View File
@@ -9,7 +9,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Index &mdash; parsedmarc 6.0.1 documentation</title>
<title>Index &mdash; parsedmarc 6.0.2 documentation</title>
@@ -57,7 +57,7 @@
<div class="version">
6.0.1
6.0.2
</div>
+63 -7
View File
@@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>parsedmarc documentation - Open source DMARC report analyzer and visualizer &mdash; parsedmarc 6.0.1 documentation</title>
<title>parsedmarc documentation - Open source DMARC report analyzer and visualizer &mdash; parsedmarc 6.0.2 documentation</title>
@@ -56,7 +56,7 @@
<div class="version">
6.0.1
6.0.2
</div>
@@ -125,6 +125,10 @@
</li>
<li><a class="reference internal" href="#dmarc-alignment-guide">DMARC Alignment Guide</a></li>
<li><a class="reference internal" href="#what-if-a-sender-won-t-support-dkim-dmarc">What if a sender wont support DKIM/DMARC?</a></li>
<li><a class="reference internal" href="#what-about-mailing-lists">What about mailing lists?</a><ul>
<li><a class="reference internal" href="#if-you-run-a-mailing-list">If you run a mailing list</a></li>
</ul>
</li>
<li><a class="reference internal" href="#module-parsedmarc">API</a><ul>
<li><a class="reference internal" href="#module-parsedmarc.elastic">parsedmarc.elastic</a></li>
<li><a class="reference internal" href="#parsedmarc-splunk">parsedmarc.splunk</a><ul>
@@ -320,7 +324,7 @@ lookalike domain monitoring, check out <a class="reference external" href="https
<li><code class="docutils literal notranslate"><span class="pre">save_forensic</span></code> - bool: Save forensic report data to the Elasticsearch and/or Splunk</li>
<li><code class="docutils literal notranslate"><span class="pre">strip_attachments_payloads</span></code> - bool: Remove attachment payloads from results</li>
<li><code class="docutils literal notranslate"><span class="pre">output</span></code> - str: Directory to place JSON and CSV files in</li>
<li><code class="docutils literal notranslate"><span class="pre">nameservers</span></code> - str: A comma separated list of DNS resolvers (Default: Cloudflares public resolvers)</li>
<li><code class="docutils literal notranslate"><span class="pre">nameservers</span></code> - str: A comma separated list of DNS resolvers (Default: <a class="reference external" href="https://1.1.1.1/">Cloudflares public resolvers</a>)</li>
<li><code class="docutils literal notranslate"><span class="pre">dns_timeout</span></code> - float: DNS timeout period</li>
<li><code class="docutils literal notranslate"><span class="pre">debug</span></code> - bool: Print debugging messages</li>
<li><code class="docutils literal notranslate"><span class="pre">silent</span></code> - bool: Only print errors (Default: True)</li>
@@ -403,6 +407,15 @@ lookalike domain monitoring, check out <a class="reference external" href="https
</ul>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p>It is <strong>strongly recommended</strong> to <strong>not</strong> use the <code class="docutils literal notranslate"><span class="pre">nameservers</span></code> setting.
By default, <code class="docutils literal notranslate"><span class="pre">parsedmarc</span></code> uses <a class="reference external" href="https://1.1.1.1/">Cloudflares public resolvers</a>,
which are much faster and more reliable than Google, Cisco OpenDNS, or
even most local resolvers.</p>
<p class="last">The <code class="docutils literal notranslate"><span class="pre">nameservers</span></code> option should only be used if your network blocks DNS
requests to outside resolvers.</p>
</div>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<blockquote>
<div><p><code class="docutils literal notranslate"><span class="pre">save_aggregate</span></code> and <code class="docutils literal notranslate"><span class="pre">save_forensic</span></code> are separate options because
you may not want to save forensic reports (also known as failure reports)
@@ -418,10 +431,10 @@ privacy reasons. While aggregate DMARC reports are sent at least daily,
it is normal to receive very few forensic reports.</p>
</div></blockquote>
<p class="last">An alternative approach is to still collect forensic/failure/ruf reports
in your DMARC inbox, but run <code class="docutils literal notranslate"><span class="pre">parsedmarc</span></code> with <code class="docutils literal notranslate"><span class="pre">save_forensic</span> <span class="pre">=</span> <span class="pre">True</span></code> manually on a
separate IMAP folder (using the <code class="docutils literal notranslate"><span class="pre">reports_folder</span></code> option), after you have manually
moved known samples you want to save to that folder (e.g. malicious
samples and non-sensitive legitimate samples).</p>
in your DMARC inbox, but run <code class="docutils literal notranslate"><span class="pre">parsedmarc</span></code> with <code class="docutils literal notranslate"><span class="pre">save_forensic</span> <span class="pre">=</span> <span class="pre">True</span></code>
manually on a separate IMAP folder (using the <code class="docutils literal notranslate"><span class="pre">reports_folder</span></code> option),
after you have manually moved known samples you want to save to that
folder (e.g. malicious samples and non-sensitive legitimate samples).</p>
</div>
</div>
<div class="section" id="sample-aggregate-report-output">
@@ -1245,6 +1258,49 @@ your TLD and/or any subdomain.</p>
</div>
</div></blockquote>
</div>
<div class="section" id="what-about-mailing-lists">
<h2>What about mailing lists?<a class="headerlink" href="#what-about-mailing-lists" title="Permalink to this headline"></a></h2>
<p>When you deploy DMARC on your domain, you might find that messages relayed by
mailing lists are failing DMARC. This has two causes:</p>
<ol class="arabic simple">
<li>You are not DKIM signing your mail like you should be</li>
<li>The mailing list is altering emails in ways that are not DMARC compliant
before sending them</li>
</ol>
<p><a class="reference external" href="https://begriffs.com/posts/2018-09-18-dmarc-mailing-list.html">Joe Nelson</a> does a fantastic job of explaining exactly what mailing lists
should and shouldnt do to be DMARC compliant. Rather than repeat his fine
work, heres a TL;DR:</p>
<div class="section" id="if-you-run-a-mailing-list">
<h3>If you run a mailing list<a class="headerlink" href="#if-you-run-a-mailing-list" title="Permalink to this headline"></a></h3>
<p><strong>Do</strong></p>
<ul>
<li><p class="first">Retain headers from the original message</p>
</li>
<li><p class="first">Add <a class="reference external" href="https://tools.ietf.org/html/rfc2369">RFC 2369</a> List-Unsubscribe headers to outgoing messages, instead of
adding unsubscribe links to the body</p>
<blockquote>
<div><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">List</span><span class="o">-</span><span class="n">Unsubscribe</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="nb">list</span><span class="o">.</span><span class="n">example</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">unsubscribe</span><span class="o">-</span><span class="n">link</span><span class="o">&gt;</span>
</pre></div>
</div>
</div></blockquote>
</li>
<li><p class="first">Add <a class="reference external" href="https://tools.ietf.org/html/rfc2919">RFC 2919</a> List-Id headers instead of modifying the subject</p>
<blockquote>
<div><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">List</span><span class="o">-</span><span class="n">Id</span><span class="p">:</span> <span class="n">Example</span> <span class="n">Mailing</span> <span class="n">List</span> <span class="o">&lt;</span><span class="nb">list</span><span class="o">.</span><span class="n">example</span><span class="o">.</span><span class="n">com</span><span class="o">&gt;</span>
</pre></div>
</div>
</div></blockquote>
</li>
</ul>
<p><strong>Do not</strong></p>
<ul class="simple">
<li>Remove or modify any existing headers from the original message, including
From, Date, Subject, etc.</li>
<li>Add to or remove content from the message body, <strong>including traditional
disclaimers and unsubscribe footers</strong></li>
</ul>
</div>
</div>
<div class="section" id="module-parsedmarc">
<span id="api"></span><h2>API<a class="headerlink" href="#module-parsedmarc" title="Permalink to this headline"></a></h2>
<p>A Python package for parsing DMARC reports</p>
BIN
View File
Binary file not shown.
+2 -2
View File
@@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Python Module Index &mdash; parsedmarc 6.0.1 documentation</title>
<title>Python Module Index &mdash; parsedmarc 6.0.2 documentation</title>
@@ -59,7 +59,7 @@
<div class="version">
6.0.1
6.0.2
</div>
+2 -2
View File
@@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Search &mdash; parsedmarc 6.0.1 documentation</title>
<title>Search &mdash; parsedmarc 6.0.2 documentation</title>
@@ -56,7 +56,7 @@
<div class="version">
6.0.1
6.0.2
</div>
+1 -1
View File
File diff suppressed because one or more lines are too long