mirror of
https://github.com/domainaware/parsedmarc.git
synced 2026-06-08 19:59:44 +00:00
3.7.0
This commit is contained in:
+3
-3
@@ -8,7 +8,7 @@
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>Overview: module code — parsedmarc 3.6.0 documentation</title>
|
||||
<title>Overview: module code — parsedmarc 3.7.0 documentation</title>
|
||||
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
|
||||
<div class="version">
|
||||
3.6.0
|
||||
3.7.0
|
||||
</div>
|
||||
|
||||
|
||||
@@ -177,7 +177,7 @@
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT:'../',
|
||||
VERSION:'3.6.0',
|
||||
VERSION:'3.7.0',
|
||||
LANGUAGE:'None',
|
||||
COLLAPSE_INDEX:false,
|
||||
FILE_SUFFIX:'.html',
|
||||
|
||||
+30
-21
@@ -8,7 +8,7 @@
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>parsedmarc — parsedmarc 3.6.0 documentation</title>
|
||||
<title>parsedmarc — parsedmarc 3.7.0 documentation</title>
|
||||
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
|
||||
<div class="version">
|
||||
3.6.0
|
||||
3.7.0
|
||||
</div>
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@
|
||||
<span class="kn">import</span> <span class="nn">dateparser</span>
|
||||
<span class="kn">import</span> <span class="nn">mailparser</span>
|
||||
|
||||
<span class="n">__version__</span> <span class="o">=</span> <span class="s2">"3.6.0"</span>
|
||||
<span class="n">__version__</span> <span class="o">=</span> <span class="s2">"3.7.0"</span>
|
||||
|
||||
<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="vm">__name__</span><span class="p">)</span>
|
||||
<span class="n">logger</span><span class="o">.</span><span class="n">setLevel</span><span class="p">(</span><span class="n">logging</span><span class="o">.</span><span class="n">INFO</span><span class="p">)</span>
|
||||
@@ -245,22 +245,23 @@
|
||||
<span class="n">psl_path</span> <span class="o">=</span> <span class="s2">".public_suffix_list.dat"</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">download_psl</span><span class="p">():</span>
|
||||
<span class="n">fresh_psl</span> <span class="o">=</span> <span class="n">publicsuffix</span><span class="o">.</span><span class="n">fetch</span><span class="p">()</span>
|
||||
<span class="n">fresh_psl</span> <span class="o">=</span> <span class="n">publicsuffix</span><span class="o">.</span><span class="n">fetch</span><span class="p">()</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
|
||||
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">psl_path</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s2">"utf-8"</span><span class="p">)</span> <span class="k">as</span> <span class="n">fresh_psl_file</span><span class="p">:</span>
|
||||
<span class="n">fresh_psl_file</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">fresh_psl</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
|
||||
|
||||
<span class="k">return</span> <span class="n">publicsuffix</span><span class="o">.</span><span class="n">PublicSuffixList</span><span class="p">(</span><span class="n">fresh_psl</span><span class="p">)</span>
|
||||
<span class="n">fresh_psl_file</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">fresh_psl</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">psl_path</span><span class="p">):</span>
|
||||
<span class="n">psl</span> <span class="o">=</span> <span class="n">download_psl</span><span class="p">()</span>
|
||||
<span class="n">download_psl</span><span class="p">()</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">psl_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">psl_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">psl_age</span> <span class="o">></span> <span class="n">timedelta</span><span class="p">(</span><span class="n">hours</span><span class="o">=</span><span class="mi">24</span><span class="p">):</span>
|
||||
<span class="n">psl</span> <span class="o">=</span> <span class="n">download_psl</span><span class="p">()</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">psl_path</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s2">"utf-8"</span><span class="p">)</span> <span class="k">as</span> <span class="n">psl_file</span><span class="p">:</span>
|
||||
<span class="n">psl</span> <span class="o">=</span> <span class="n">publicsuffix</span><span class="o">.</span><span class="n">PublicSuffixList</span><span class="p">(</span><span class="n">psl_file</span><span class="p">)</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">download_psl</span><span class="p">()</span>
|
||||
<span class="k">except</span> <span class="ne">Exception</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="s2">"Failed to download an updated PSL - </span><span class="se">\</span>
|
||||
<span class="s2"> </span><span class="si">{0}</span><span class="s2">"</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">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">psl_path</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s2">"utf-8"</span><span class="p">)</span> <span class="k">as</span> <span class="n">psl_file</span><span class="p">:</span>
|
||||
<span class="n">psl</span> <span class="o">=</span> <span class="n">publicsuffix</span><span class="o">.</span><span class="n">PublicSuffixList</span><span class="p">(</span><span class="n">psl_file</span><span class="p">)</span>
|
||||
|
||||
<span class="k">return</span> <span class="n">psl</span><span class="o">.</span><span class="n">get_public_suffix</span><span class="p">(</span><span class="n">domain</span><span class="p">)</span>
|
||||
|
||||
@@ -531,11 +532,15 @@
|
||||
<span class="n">new_record</span><span class="p">[</span><span class="s2">"auth_results"</span><span class="p">][</span><span class="s2">"spf"</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">new_result</span><span class="p">)</span>
|
||||
|
||||
<span class="k">if</span> <span class="s2">"envelope_from"</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">new_record</span><span class="p">[</span><span class="s2">"identifiers"</span><span class="p">]:</span>
|
||||
<span class="n">envelope_from</span> <span class="o">=</span> <span class="n">new_record</span><span class="p">[</span><span class="s2">"auth_results"</span><span class="p">][</span><span class="s2">"spf"</span><span class="p">][</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="s2">"domain"</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
||||
<span class="n">envelope_from</span> <span class="o">=</span> <span class="n">new_record</span><span class="p">[</span><span class="s2">"auth_results"</span><span class="p">][</span><span class="s2">"spf"</span><span class="p">][</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="s2">"domain"</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="n">envelope_from</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="n">envelope_from</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">envelope_from</span><span class="p">)</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
||||
<span class="n">new_record</span><span class="p">[</span><span class="s2">"identifiers"</span><span class="p">][</span><span class="s2">"envelope_from"</span><span class="p">]</span> <span class="o">=</span> <span class="n">envelope_from</span>
|
||||
|
||||
<span class="k">elif</span> <span class="n">new_record</span><span class="p">[</span><span class="s2">"identifiers"</span><span class="p">][</span><span class="s2">"envelope_from"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="n">envelope_from</span> <span class="o">=</span> <span class="n">new_record</span><span class="p">[</span><span class="s2">"auth_results"</span><span class="p">][</span><span class="s2">"spf"</span><span class="p">][</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="s2">"domain"</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
||||
<span class="n">envelope_from</span> <span class="o">=</span> <span class="n">new_record</span><span class="p">[</span><span class="s2">"auth_results"</span><span class="p">][</span><span class="s2">"spf"</span><span class="p">][</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="s2">"domain"</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="n">envelope_from</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="n">envelope_from</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">envelope_from</span><span class="p">)</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
||||
<span class="n">new_record</span><span class="p">[</span><span class="s2">"identifiers"</span><span class="p">][</span><span class="s2">"envelope_from"</span><span class="p">]</span> <span class="o">=</span> <span class="n">envelope_from</span>
|
||||
|
||||
<span class="n">envelope_to</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
@@ -728,6 +733,10 @@
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> str: Parsed aggregate report data in flat CSV format, including headers</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">to_str</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
||||
|
||||
<span class="n">fields</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"xml_schema"</span><span class="p">,</span> <span class="s2">"org_name"</span><span class="p">,</span> <span class="s2">"org_email"</span><span class="p">,</span>
|
||||
<span class="s2">"org_extra_contact_info"</span><span class="p">,</span> <span class="s2">"report_id"</span><span class="p">,</span> <span class="s2">"begin_date"</span><span class="p">,</span> <span class="s2">"end_date"</span><span class="p">,</span>
|
||||
<span class="s2">"errors"</span><span class="p">,</span> <span class="s2">"domain"</span><span class="p">,</span> <span class="s2">"adkim"</span><span class="p">,</span> <span class="s2">"aspf"</span><span class="p">,</span> <span class="s2">"p"</span><span class="p">,</span> <span class="s2">"sp"</span><span class="p">,</span> <span class="s2">"pct"</span><span class="p">,</span> <span class="s2">"fo"</span><span class="p">,</span>
|
||||
@@ -801,9 +810,9 @@
|
||||
<span class="k">if</span> <span class="s2">"selector"</span> <span class="ow">in</span> <span class="n">dkim_result</span><span class="p">:</span>
|
||||
<span class="n">dkim_selectors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">dkim_result</span><span class="p">[</span><span class="s2">"selector"</span><span class="p">])</span>
|
||||
<span class="n">dkim_results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">dkim_result</span><span class="p">[</span><span class="s2">"result"</span><span class="p">])</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"dkim_domains"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">","</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">dkim_domains</span><span class="p">)</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"dkim_selectors"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">","</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">dkim_selectors</span><span class="p">)</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"dkim_results"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">","</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">dkim_results</span><span class="p">)</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"dkim_domains"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">","</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">to_str</span><span class="p">,</span> <span class="n">dkim_domains</span><span class="p">))</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"dkim_selectors"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">","</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">to_str</span><span class="p">,</span> <span class="n">dkim_selectors</span><span class="p">))</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"dkim_results"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">","</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">to_str</span><span class="p">,</span> <span class="n">dkim_results</span><span class="p">))</span>
|
||||
<span class="n">spf_domains</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="n">spf_scopes</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="n">spf_results</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
@@ -811,9 +820,9 @@
|
||||
<span class="n">spf_domains</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">spf_result</span><span class="p">[</span><span class="s2">"domain"</span><span class="p">])</span>
|
||||
<span class="n">spf_scopes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">spf_result</span><span class="p">[</span><span class="s2">"scope"</span><span class="p">])</span>
|
||||
<span class="n">spf_results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">spf_result</span><span class="p">[</span><span class="s2">"result"</span><span class="p">])</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"spf_domains"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">","</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">spf_domains</span><span class="p">)</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"spf_scopes"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">","</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">spf_scopes</span><span class="p">)</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"spf_results"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">","</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">spf_results</span><span class="p">)</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"spf_domains"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">","</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">to_str</span><span class="p">,</span> <span class="n">spf_domains</span><span class="p">))</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"spf_scopes"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">","</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">to_str</span><span class="p">,</span> <span class="n">spf_scopes</span><span class="p">))</span>
|
||||
<span class="n">row</span><span class="p">[</span><span class="s2">"spf_results"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">","</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">to_str</span><span class="p">,</span> <span class="n">dkim_results</span><span class="p">))</span>
|
||||
|
||||
<span class="n">writer</span><span class="o">.</span><span class="n">writerow</span><span class="p">(</span><span class="n">row</span><span class="p">)</span>
|
||||
<span class="n">csv_file_object</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
|
||||
@@ -1618,7 +1627,7 @@
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT:'../',
|
||||
VERSION:'3.6.0',
|
||||
VERSION:'3.7.0',
|
||||
LANGUAGE:'None',
|
||||
COLLAPSE_INDEX:false,
|
||||
FILE_SUFFIX:'.html',
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>parsedmarc.elastic — parsedmarc 3.6.0 documentation</title>
|
||||
<title>parsedmarc.elastic — parsedmarc 3.7.0 documentation</title>
|
||||
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
|
||||
<div class="version">
|
||||
3.6.0
|
||||
3.7.0
|
||||
</div>
|
||||
|
||||
|
||||
@@ -545,7 +545,7 @@
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT:'../../',
|
||||
VERSION:'3.6.0',
|
||||
VERSION:'3.7.0',
|
||||
LANGUAGE:'None',
|
||||
COLLAPSE_INDEX:false,
|
||||
FILE_SUFFIX:'.html',
|
||||
|
||||
+194
-19
@@ -16,18 +16,29 @@ Welcome to parsedmarc's documentation!
|
||||
:target: _static/screenshots/dmarc-summary-charts.png
|
||||
|
||||
``parsedmarc`` is a Python module and CLI utility for parsing DMARC reports.
|
||||
When used with Elasticsearch and Kibana, it works as a self-hosted open source
|
||||
alternative to commercial DMARC report processing services such as Agari,
|
||||
Dmarcian, and OnDMARC.
|
||||
|
||||
Features
|
||||
========
|
||||
|
||||
* Parses draft and 1.0 standard aggregate reports
|
||||
* Parses forensic reports
|
||||
* Parses draft and 1.0 standard aggregate/rua reports
|
||||
* Parses forensic/failure/ruf reports
|
||||
* Can parse reports from an inbox over IMAP
|
||||
* Transparently handles gzip or zip compressed reports
|
||||
* Consistent data structures
|
||||
* Simple JSON and/or CSV output
|
||||
* Optionally email the results
|
||||
* Optionally send the results to Elasticsearch, for use with premade Kibana dashboards
|
||||
* Optionally send the results to Elasticsearch, for use with premade Kibana
|
||||
dashboards
|
||||
|
||||
Resources
|
||||
=========
|
||||
|
||||
* `Demystifying DMARC`_
|
||||
|
||||
|
||||
|
||||
CLI help
|
||||
========
|
||||
@@ -102,7 +113,8 @@ SPF and DMARC record validation
|
||||
===============================
|
||||
|
||||
If you are looking for SPF and DMARC record validation and parsing,
|
||||
check out the sister project, `checkdmarc <https://domainaware.github.io/checkdmarc/>`_.
|
||||
check out the sister project,
|
||||
`checkdmarc <https://domainaware.github.io/checkdmarc/>`_.
|
||||
|
||||
Sample aggregate report output
|
||||
==============================
|
||||
@@ -254,6 +266,10 @@ Elasticsearch and Kibana
|
||||
|
||||
To set up visual dashboards of DMARC data, install Elasticsearch and Kibana.
|
||||
|
||||
.. note::
|
||||
|
||||
Elasticsearch/Kibana 6+ is required
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt-get install -y openjdk-8-jre apt-transport-https
|
||||
@@ -398,17 +414,17 @@ Om the same system as Elasticsearch, pass ``--save-aggregate`` and/or
|
||||
.. warning::
|
||||
|
||||
``--save-aggregate`` and ``--save-forensic`` are separate options because
|
||||
you may not want to save forensic reports to your Elasticsearch instance,
|
||||
particularly if you are in a highly-regulated industry that handles
|
||||
sensitive data, such as healthcare or finance. If your legitimate outgoing
|
||||
email fails DMARC, it is possible that email may appear later in a
|
||||
forensic report.
|
||||
you may not want to save forensic reports (also known as failure reports)
|
||||
to your Elasticsearch instance, particularly if you are in a
|
||||
highly-regulated industry that handles sensitive data, such as healthcare
|
||||
or finance. If your legitimate outgoing email fails DMARC, it is possible
|
||||
that email may appear later in a forensic report.
|
||||
|
||||
Forensic reports contain the original headers of an email that failed a
|
||||
DMARC check, and sometimes may also include the full message body,
|
||||
depending on the policy of the reporting organisation.
|
||||
depending on the policy of the reporting organization.
|
||||
|
||||
Most reporting organisations do not send forensic reports of any kind for
|
||||
Most reporting organizations do not send forensic reports of any kind for
|
||||
privacy reasons. While aggregate DMARC reports are sent at least daily,
|
||||
it is normal to receive very few forensic reports.
|
||||
|
||||
@@ -483,14 +499,6 @@ Create the service configuration file
|
||||
|
||||
sudo nano /etc/systemd/system/parsedmarc.service
|
||||
|
||||
Edit the command line options of ``parsedmarc`` in the service's ``ExecStart``
|
||||
setting to suit your needs.
|
||||
|
||||
.. note::
|
||||
|
||||
Always pass the ``--watch`` option to ``parsedmarc`` when running it as a
|
||||
service. Use ``--silent`` to only log errors.
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[Unit]
|
||||
@@ -505,6 +513,23 @@ setting to suit your needs.
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
Edit the command line options of ``parsedmarc`` in the service's ``ExecStart``
|
||||
setting to suit your needs.
|
||||
|
||||
.. note::
|
||||
|
||||
Always pass the ``--watch`` option to ``parsedmarc`` when running it as a
|
||||
service. Use ``--silent`` to only log errors.
|
||||
|
||||
.. warning::
|
||||
|
||||
As mentioned earlier, forensic/failure reports contain copies of emails
|
||||
that failed DMARC, including emails that may be legitimate and contain
|
||||
sensitive customer or business information. For privacy and/or regulatory
|
||||
reasons, you may not want to use the ``--save-forensic`` flag included in
|
||||
the example service configuration ``ExecStart`` setting, which would save
|
||||
these samples to Elasticsearch.
|
||||
|
||||
Then, enable the service
|
||||
|
||||
.. code-block:: bash
|
||||
@@ -518,6 +543,154 @@ Then, enable the service
|
||||
You must also run the above commands whenever you edit
|
||||
``parsedmarc.service``.
|
||||
|
||||
Use this command to check the status of the service:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo service parsedmarc status
|
||||
|
||||
Using the Kibana dashboards
|
||||
===========================
|
||||
|
||||
The Kibana DMARC dashboards are a human-friendly way to understand the results
|
||||
from incoming DMARC reports.
|
||||
|
||||
.. note::
|
||||
|
||||
The default dashboard is DMARC Summary. To switch between dashboards,
|
||||
click on the Dashboard link in the left side menu of Kibana.
|
||||
|
||||
|
||||
DMARC Summary
|
||||
-------------
|
||||
|
||||
As the name suggests, this dashboard is the best place to start reviewing your
|
||||
aggregate DMARC data.
|
||||
|
||||
Across the top of the dashboard, three pie charts display the percentage of
|
||||
alignment pass/fail for SPF, DKIM, and DMARC. Clicking on any chart segment
|
||||
will filter for that value.
|
||||
|
||||
.. note::
|
||||
|
||||
Messages should not be considered malicious just because they failed to pass
|
||||
DMARC; especially if you have just started collecting data. It may be a
|
||||
legitimate service that needs SPF and DKIM configured correctly.
|
||||
|
||||
Start by filtering the results to only show failed DKIM alignment. While DMARC
|
||||
passes if a message passes SPF or DKIM alignment, only DKIM alignment remains
|
||||
valid when a message is forwarded without changing the from address, which is
|
||||
often caused by a mailbox forwarding rule. This is because DKIM signatures are
|
||||
part of the message headers, whereas SPF relies on SMTP session headers.
|
||||
|
||||
Underneath the pie charts. you can see graphs of DMARC passage and message
|
||||
disposition over time.
|
||||
|
||||
Under the graphs you will find the most useful data tables on the dashboard. On
|
||||
the left, there is a list of organizations that are sending you DMARC reports.
|
||||
In the center, there is a list of sending servers grouped by the base domain
|
||||
in their reverse DNS. On the right, there is a list of email from domains,
|
||||
sorted by message volume.
|
||||
|
||||
By hovering your mouse over a data table value and using the magnifying glass
|
||||
icons, you can filter on our filter out different values. Start by looking at
|
||||
the Message Sources by Reverse DNS table. Find a sender that you recognize,
|
||||
such as an email marketing service, hover over it, and click on the plus (+)
|
||||
magnifying glass icon, to add a filter that only shows results for that sender.
|
||||
Now, look at the Message From Header table to the right. That shows you the
|
||||
domains that a sender is sending as, which might tell you which brand/business
|
||||
is using a particular service. With that information, you can contact them and
|
||||
have them set up DKIM.
|
||||
|
||||
.. note::
|
||||
|
||||
If you have a lot of B2C customers, you may see a high volume of emails as
|
||||
your domains coming from consumer email services, such as Google/Gmail and
|
||||
Yahoo! This occurs when customers have mailbox rules in place that forward
|
||||
emails from an old account to a new account, which is why DKIM
|
||||
authentication is so important, as mentioned earlier. Similar patterns may
|
||||
be observed with businesses who send from reverse DNS addressees of
|
||||
parent, subsidiary, and outdated brands.
|
||||
|
||||
|
||||
Further down the dashboard, you can filter by source country or source IP
|
||||
address.
|
||||
|
||||
Tables showing SPF and DKIM alignment details are located under the IP address
|
||||
table.
|
||||
|
||||
.. note::
|
||||
|
||||
Previously, the alignment tables were included in a separate dashboard
|
||||
called DMARC Alignment Failures. That dashboard has been consolidated into
|
||||
the DMARC Summary dashboard. To view failures only, use the pie chart.
|
||||
|
||||
Any other filters work the same way. You can also add your own custom temporary
|
||||
filters by clicking on Add Filter at the upper right of the page.
|
||||
|
||||
DMARC Forensic Samples
|
||||
----------------------
|
||||
|
||||
The DMARC Forensic Samples dashboard contains information on DMARC forensic
|
||||
reports (also known as failure reports or ruf reports). These reports contain
|
||||
samples of emails that have failed to pass DMARC.
|
||||
|
||||
.. note::
|
||||
|
||||
Most recipients do not send forensic/failure/ruf reports at all to avoid
|
||||
privacy leaks. Some recipients (notably Chinese webmail services) will only
|
||||
supply the headers of sample emails. Very few provide the entire email.
|
||||
|
||||
|
||||
DMARC Alignment Guide
|
||||
=====================
|
||||
|
||||
DMARC ensures that SPF and DKM authentication mechanisms actually authenticate
|
||||
against the same domain that the end user sees.
|
||||
|
||||
A message passes a DMARC check by passing DKIM or SPF, **as long as the related
|
||||
indicators are also in alignment**.
|
||||
|
||||
+-----------------------+-----------------------+-----------------------+
|
||||
| | **DKIM** | **SPF** |
|
||||
+-----------------------+-----------------------+-----------------------+
|
||||
| **Passing** | The signature in the | The mail server’s IP |
|
||||
| | DKIM header is | address is listed in |
|
||||
| | validated using a | the SPF record of the |
|
||||
| | public key that is | domain in the SMTP |
|
||||
| | published as a DNS | envelope’s mail from |
|
||||
| | record of the domain | header |
|
||||
| | name specified in the | |
|
||||
| | signature | |
|
||||
+-----------------------+-----------------------+-----------------------+
|
||||
| **Alignment** | The signing domain | The domain in the |
|
||||
| | aligns with the | SMTP envelope’s mail |
|
||||
| | domain in the | from header aligns |
|
||||
| | message’s from header | with the domain in |
|
||||
| | | the message’s from |
|
||||
| | | header |
|
||||
+-----------------------+-----------------------+-----------------------+
|
||||
|
||||
|
||||
What if a sender won't support DKIM/DMARC?
|
||||
==========================================
|
||||
|
||||
#. Some vendors don’t know about DMARC yet; ask about SPF and DKIM/email
|
||||
authentication.
|
||||
#. Check if they can send through your email relays instead of theirs.
|
||||
#. Do they really need to spoof your domain? Why not use the display
|
||||
name instead?
|
||||
#. Worst case, have that vendor send email as a specific subdomain of
|
||||
your domain (e.g. ``noreply@news.example.com``), and then create
|
||||
separate SPF and DMARC records on ``news.example.com``, and set
|
||||
``p=none`` in that DMARC record.
|
||||
|
||||
.. warning ::
|
||||
|
||||
Do not alter the ``p`` or ``sp`` values of the DMARC record on the
|
||||
Top-Level Domain (TLD) – that would leave you vulnerable to spoofing of
|
||||
your TLD and/or any subdomain.
|
||||
|
||||
API
|
||||
===
|
||||
|
||||
@@ -545,6 +718,8 @@ Indices and tables
|
||||
.. |Build Status| image:: https://travis-ci.org/domainaware/parsedmarc.svg?branch=master
|
||||
:target: https://travis-ci.org/domainaware/parsedmarc
|
||||
|
||||
.. _Demystifying DMARC: https://seanthegeek.net/459/demystifying-dmarc/
|
||||
|
||||
.. _X-Pack: https://www.elastic.co/products/x-pack
|
||||
|
||||
.. _kibana_saved_objects.json: https://raw.githubusercontent.com/domainaware/parsedmarc/master/kibana/kibana_saved_objects.json
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
|
||||
VERSION: '3.6.0',
|
||||
VERSION: '3.7.0',
|
||||
LANGUAGE: 'None',
|
||||
COLLAPSE_INDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
|
||||
+3
-3
@@ -9,7 +9,7 @@
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>Index — parsedmarc 3.6.0 documentation</title>
|
||||
<title>Index — parsedmarc 3.7.0 documentation</title>
|
||||
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
|
||||
|
||||
<div class="version">
|
||||
3.6.0
|
||||
3.7.0
|
||||
</div>
|
||||
|
||||
|
||||
@@ -310,7 +310,7 @@
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT:'./',
|
||||
VERSION:'3.6.0',
|
||||
VERSION:'3.7.0',
|
||||
LANGUAGE:'None',
|
||||
COLLAPSE_INDEX:false,
|
||||
FILE_SUFFIX:'.html',
|
||||
|
||||
+207
-22
@@ -8,7 +8,7 @@
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>Welcome to parsedmarc’s documentation! — parsedmarc 3.6.0 documentation</title>
|
||||
<title>Welcome to parsedmarc’s documentation! — parsedmarc 3.7.0 documentation</title>
|
||||
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
|
||||
<div class="version">
|
||||
3.6.0
|
||||
3.7.0
|
||||
</div>
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@
|
||||
<div class="local-toc"><ul>
|
||||
<li><a class="reference internal" href="#">Welcome to parsedmarc’s documentation!</a><ul>
|
||||
<li><a class="reference internal" href="#features">Features</a></li>
|
||||
<li><a class="reference internal" href="#resources">Resources</a></li>
|
||||
<li><a class="reference internal" href="#cli-help">CLI help</a></li>
|
||||
<li><a class="reference internal" href="#spf-and-dmarc-record-validation">SPF and DMARC record validation</a></li>
|
||||
<li><a class="reference internal" href="#sample-aggregate-report-output">Sample aggregate report output</a><ul>
|
||||
@@ -99,6 +100,13 @@
|
||||
<li><a class="reference internal" href="#running-parsedmarc-as-a-systemd-service">Running parsedmarc as a systemd service</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#using-the-kibana-dashboards">Using the Kibana dashboards</a><ul>
|
||||
<li><a class="reference internal" href="#dmarc-summary">DMARC Summary</a></li>
|
||||
<li><a class="reference internal" href="#dmarc-forensic-samples">DMARC Forensic Samples</a></li>
|
||||
</ul>
|
||||
</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 won’t support DKIM/DMARC?</a></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>
|
||||
</ul>
|
||||
@@ -174,18 +182,28 @@
|
||||
<h1>Welcome to parsedmarc’s documentation!<a class="headerlink" href="#welcome-to-parsedmarc-s-documentation" title="Permalink to this headline">¶</a></h1>
|
||||
<p><a class="reference external" href="https://travis-ci.org/domainaware/parsedmarc"><img alt="Build Status" src="https://travis-ci.org/domainaware/parsedmarc.svg?branch=master" /></a></p>
|
||||
<a class="reference external image-reference" href="_static/screenshots/dmarc-summary-charts.png"><img alt="A screenshot of DMARC summary charts in Kibana" class="align-center" src="_images/dmarc-summary-charts.png" style="width: 597.0px; height: 381.0px;" /></a>
|
||||
<p><code class="docutils literal notranslate"><span class="pre">parsedmarc</span></code> is a Python module and CLI utility for parsing DMARC reports.</p>
|
||||
<p><code class="docutils literal notranslate"><span class="pre">parsedmarc</span></code> is a Python module and CLI utility for parsing DMARC reports.
|
||||
When used with Elasticsearch and Kibana, it works as a self-hosted open source
|
||||
alternative to commercial DMARC report processing services such as Agari,
|
||||
Dmarcian, and OnDMARC.</p>
|
||||
<div class="section" id="features">
|
||||
<h2>Features<a class="headerlink" href="#features" title="Permalink to this headline">¶</a></h2>
|
||||
<ul class="simple">
|
||||
<li>Parses draft and 1.0 standard aggregate reports</li>
|
||||
<li>Parses forensic reports</li>
|
||||
<li>Parses draft and 1.0 standard aggregate/rua reports</li>
|
||||
<li>Parses forensic/failure/ruf reports</li>
|
||||
<li>Can parse reports from an inbox over IMAP</li>
|
||||
<li>Transparently handles gzip or zip compressed reports</li>
|
||||
<li>Consistent data structures</li>
|
||||
<li>Simple JSON and/or CSV output</li>
|
||||
<li>Optionally email the results</li>
|
||||
<li>Optionally send the results to Elasticsearch, for use with premade Kibana dashboards</li>
|
||||
<li>Optionally send the results to Elasticsearch, for use with premade Kibana
|
||||
dashboards</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="resources">
|
||||
<h2>Resources<a class="headerlink" href="#resources" title="Permalink to this headline">¶</a></h2>
|
||||
<ul class="simple">
|
||||
<li><a class="reference external" href="https://seanthegeek.net/459/demystifying-dmarc/">Demystifying DMARC</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="cli-help">
|
||||
@@ -259,7 +277,8 @@
|
||||
<div class="section" id="spf-and-dmarc-record-validation">
|
||||
<h2>SPF and DMARC record validation<a class="headerlink" href="#spf-and-dmarc-record-validation" title="Permalink to this headline">¶</a></h2>
|
||||
<p>If you are looking for SPF and DMARC record validation and parsing,
|
||||
check out the sister project, <a class="reference external" href="https://domainaware.github.io/checkdmarc/">checkdmarc</a>.</p>
|
||||
check out the sister project,
|
||||
<a class="reference external" href="https://domainaware.github.io/checkdmarc/">checkdmarc</a>.</p>
|
||||
</div>
|
||||
<div class="section" id="sample-aggregate-report-output">
|
||||
<h2>Sample aggregate report output<a class="headerlink" href="#sample-aggregate-report-output" title="Permalink to this headline">¶</a></h2>
|
||||
@@ -388,6 +407,10 @@ above commands.</p>
|
||||
<div class="section" id="elasticsearch-and-kibana">
|
||||
<h3>Elasticsearch and Kibana<a class="headerlink" href="#elasticsearch-and-kibana" title="Permalink to this headline">¶</a></h3>
|
||||
<p>To set up visual dashboards of DMARC data, install Elasticsearch and Kibana.</p>
|
||||
<div class="admonition note">
|
||||
<p class="first admonition-title">Note</p>
|
||||
<p class="last">Elasticsearch/Kibana 6+ is required</p>
|
||||
</div>
|
||||
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>sudo apt-get install -y openjdk-8-jre apt-transport-https
|
||||
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch <span class="p">|</span> sudo apt-key add -
|
||||
<span class="nb">echo</span> <span class="s2">"deb https://artifacts.elastic.co/packages/6.x/apt stable main"</span> <span class="p">|</span> sudo tee -a /etc/apt/sources.list.d/elastic-6.x.list
|
||||
@@ -499,15 +522,15 @@ it.</p>
|
||||
<div class="admonition warning">
|
||||
<p class="first admonition-title">Warning</p>
|
||||
<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 to your Elasticsearch instance,
|
||||
particularly if you are in a highly-regulated industry that handles
|
||||
sensitive data, such as healthcare or finance. If your legitimate outgoing
|
||||
email fails DMARC, it is possible that email may appear later in a
|
||||
forensic report.</p>
|
||||
you may not want to save forensic reports (also known as failure reports)
|
||||
to your Elasticsearch instance, particularly if you are in a
|
||||
highly-regulated industry that handles sensitive data, such as healthcare
|
||||
or finance. If your legitimate outgoing email fails DMARC, it is possible
|
||||
that email may appear later in a forensic report.</p>
|
||||
<p>Forensic reports contain the original headers of an email that failed a
|
||||
DMARC check, and sometimes may also include the full message body,
|
||||
depending on the policy of the reporting organisation.</p>
|
||||
<p class="last">Most reporting organisations do not send forensic reports of any kind for
|
||||
depending on the policy of the reporting organization.</p>
|
||||
<p class="last">Most reporting organizations do not send forensic reports of any kind for
|
||||
privacy reasons. While aggregate DMARC reports are sent at least daily,
|
||||
it is normal to receive very few forensic reports.</p>
|
||||
</div>
|
||||
@@ -543,13 +566,6 @@ arrive.</p>
|
||||
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>sudo nano /etc/systemd/system/parsedmarc.service
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Edit the command line options of <code class="docutils literal notranslate"><span class="pre">parsedmarc</span></code> in the service’s <code class="docutils literal notranslate"><span class="pre">ExecStart</span></code>
|
||||
setting to suit your needs.</p>
|
||||
<div class="admonition note">
|
||||
<p class="first admonition-title">Note</p>
|
||||
<p class="last">Always pass the <code class="docutils literal notranslate"><span class="pre">--watch</span></code> option to <code class="docutils literal notranslate"><span class="pre">parsedmarc</span></code> when running it as a
|
||||
service. Use <code class="docutils literal notranslate"><span class="pre">--silent</span></code> to only log errors.</p>
|
||||
</div>
|
||||
<div class="highlight-ini notranslate"><div class="highlight"><pre><span></span><span class="k">[Unit]</span>
|
||||
<span class="na">Description</span><span class="o">=</span><span class="s">parsedmarc mailbox watcher</span>
|
||||
<span class="na">Documentation</span><span class="o">=</span><span class="s">https://domainaware.github.io/parsedmarc/</span>
|
||||
@@ -563,6 +579,22 @@ service. Use <code class="docutils literal notranslate"><span class="pre">--sile
|
||||
<span class="na">WantedBy</span><span class="o">=</span><span class="s">multi-user.target</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Edit the command line options of <code class="docutils literal notranslate"><span class="pre">parsedmarc</span></code> in the service’s <code class="docutils literal notranslate"><span class="pre">ExecStart</span></code>
|
||||
setting to suit your needs.</p>
|
||||
<div class="admonition note">
|
||||
<p class="first admonition-title">Note</p>
|
||||
<p class="last">Always pass the <code class="docutils literal notranslate"><span class="pre">--watch</span></code> option to <code class="docutils literal notranslate"><span class="pre">parsedmarc</span></code> when running it as a
|
||||
service. Use <code class="docutils literal notranslate"><span class="pre">--silent</span></code> to only log errors.</p>
|
||||
</div>
|
||||
<div class="admonition warning">
|
||||
<p class="first admonition-title">Warning</p>
|
||||
<p class="last">As mentioned earlier, forensic/failure reports contain copies of emails
|
||||
that failed DMARC, including emails that may be legitimate and contain
|
||||
sensitive customer or business information. For privacy and/or regulatory
|
||||
reasons, you may not want to use the <code class="docutils literal notranslate"><span class="pre">--save-forensic</span></code> flag included in
|
||||
the example service configuration <code class="docutils literal notranslate"><span class="pre">ExecStart</span></code> setting, which would save
|
||||
these samples to Elasticsearch.</p>
|
||||
</div>
|
||||
<p>Then, enable the service</p>
|
||||
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>sudo systemctl daemon-reload
|
||||
sudo systemctl <span class="nb">enable</span> parsedmarc.service
|
||||
@@ -574,8 +606,161 @@ sudo service parsedmarc restart
|
||||
<p class="last">You must also run the above commands whenever you edit
|
||||
<code class="docutils literal notranslate"><span class="pre">parsedmarc.service</span></code>.</p>
|
||||
</div>
|
||||
<p>Use this command to check the status of the service:</p>
|
||||
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>sudo service parsedmarc status
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="using-the-kibana-dashboards">
|
||||
<h2>Using the Kibana dashboards<a class="headerlink" href="#using-the-kibana-dashboards" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The Kibana DMARC dashboards are a human-friendly way to understand the results
|
||||
from incoming DMARC reports.</p>
|
||||
<div class="admonition note">
|
||||
<p class="first admonition-title">Note</p>
|
||||
<p class="last">The default dashboard is DMARC Summary. To switch between dashboards,
|
||||
click on the Dashboard link in the left side menu of Kibana.</p>
|
||||
</div>
|
||||
<div class="section" id="dmarc-summary">
|
||||
<h3>DMARC Summary<a class="headerlink" href="#dmarc-summary" title="Permalink to this headline">¶</a></h3>
|
||||
<p>As the name suggests, this dashboard is the best place to start reviewing your
|
||||
aggregate DMARC data.</p>
|
||||
<p>Across the top of the dashboard, three pie charts display the percentage of
|
||||
alignment pass/fail for SPF, DKIM, and DMARC. Clicking on any chart segment
|
||||
will filter for that value.</p>
|
||||
<div class="admonition note">
|
||||
<p class="first admonition-title">Note</p>
|
||||
<p class="last">Messages should not be considered malicious just because they failed to pass
|
||||
DMARC; especially if you have just started collecting data. It may be a
|
||||
legitimate service that needs SPF and DKIM configured correctly.</p>
|
||||
</div>
|
||||
<p>Start by filtering the results to only show failed DKIM alignment. While DMARC
|
||||
passes if a message passes SPF or DKIM alignment, only DKIM alignment remains
|
||||
valid when a message is forwarded without changing the from address, which is
|
||||
often caused by a mailbox forwarding rule. This is because DKIM signatures are
|
||||
part of the message headers, whereas SPF relies on SMTP session headers.</p>
|
||||
<p>Underneath the pie charts. you can see graphs of DMARC passage and message
|
||||
disposition over time.</p>
|
||||
<p>Under the graphs you will find the most useful data tables on the dashboard. On
|
||||
the left, there is a list of organizations that are sending you DMARC reports.
|
||||
In the center, there is a list of sending servers grouped by the base domain
|
||||
in their reverse DNS. On the right, there is a list of email from domains,
|
||||
sorted by message volume.</p>
|
||||
<p>By hovering your mouse over a data table value and using the magnifying glass
|
||||
icons, you can filter on our filter out different values. Start by looking at
|
||||
the Message Sources by Reverse DNS table. Find a sender that you recognize,
|
||||
such as an email marketing service, hover over it, and click on the plus (+)
|
||||
magnifying glass icon, to add a filter that only shows results for that sender.
|
||||
Now, look at the Message From Header table to the right. That shows you the
|
||||
domains that a sender is sending as, which might tell you which brand/business
|
||||
is using a particular service. With that information, you can contact them and
|
||||
have them set up DKIM.</p>
|
||||
<div class="admonition note">
|
||||
<p class="first admonition-title">Note</p>
|
||||
<p class="last">If you have a lot of B2C customers, you may see a high volume of emails as
|
||||
your domains coming from consumer email services, such as Google/Gmail and
|
||||
Yahoo! This occurs when customers have mailbox rules in place that forward
|
||||
emails from an old account to a new account, which is why DKIM
|
||||
authentication is so important, as mentioned earlier. Similar patterns may
|
||||
be observed with businesses who send from reverse DNS addressees of
|
||||
parent, subsidiary, and outdated brands.</p>
|
||||
</div>
|
||||
<p>Further down the dashboard, you can filter by source country or source IP
|
||||
address.</p>
|
||||
<p>Tables showing SPF and DKIM alignment details are located under the IP address
|
||||
table.</p>
|
||||
<div class="admonition note">
|
||||
<p class="first admonition-title">Note</p>
|
||||
<p class="last">Previously, the alignment tables were included in a separate dashboard
|
||||
called DMARC Alignment Failures. That dashboard has been consolidated into
|
||||
the DMARC Summary dashboard. To view failures only, use the pie chart.</p>
|
||||
</div>
|
||||
<p>Any other filters work the same way. You can also add your own custom temporary
|
||||
filters by clicking on Add Filter at the upper right of the page.</p>
|
||||
</div>
|
||||
<div class="section" id="dmarc-forensic-samples">
|
||||
<h3>DMARC Forensic Samples<a class="headerlink" href="#dmarc-forensic-samples" title="Permalink to this headline">¶</a></h3>
|
||||
<p>The DMARC Forensic Samples dashboard contains information on DMARC forensic
|
||||
reports (also known as failure reports or ruf reports). These reports contain
|
||||
samples of emails that have failed to pass DMARC.</p>
|
||||
<div class="admonition note">
|
||||
<p class="first admonition-title">Note</p>
|
||||
<p class="last">Most recipients do not send forensic/failure/ruf reports at all to avoid
|
||||
privacy leaks. Some recipients (notably Chinese webmail services) will only
|
||||
supply the headers of sample emails. Very few provide the entire email.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="dmarc-alignment-guide">
|
||||
<h2>DMARC Alignment Guide<a class="headerlink" href="#dmarc-alignment-guide" title="Permalink to this headline">¶</a></h2>
|
||||
<p>DMARC ensures that SPF and DKM authentication mechanisms actually authenticate
|
||||
against the same domain that the end user sees.</p>
|
||||
<p>A message passes a DMARC check by passing DKIM or SPF, <strong>as long as the related
|
||||
indicators are also in alignment</strong>.</p>
|
||||
<table border="1" class="docutils">
|
||||
<colgroup>
|
||||
<col width="33%" />
|
||||
<col width="33%" />
|
||||
<col width="33%" />
|
||||
</colgroup>
|
||||
<tbody valign="top">
|
||||
<tr class="row-odd"><td> </td>
|
||||
<td><strong>DKIM</strong></td>
|
||||
<td><strong>SPF</strong></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><strong>Passing</strong></td>
|
||||
<td>The signature in the
|
||||
DKIM header is
|
||||
validated using a
|
||||
public key that is
|
||||
published as a DNS
|
||||
record of the domain
|
||||
name specified in the
|
||||
signature</td>
|
||||
<td>The mail server’s IP
|
||||
address is listed in
|
||||
the SPF record of the
|
||||
domain in the SMTP
|
||||
envelope’s mail from
|
||||
header</td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><strong>Alignment</strong></td>
|
||||
<td>The signing domain
|
||||
aligns with the
|
||||
domain in the
|
||||
message’s from header</td>
|
||||
<td>The domain in the
|
||||
SMTP envelope’s mail
|
||||
from header aligns
|
||||
with the domain in
|
||||
the message’s from
|
||||
header</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="section" id="what-if-a-sender-won-t-support-dkim-dmarc">
|
||||
<h2>What if a sender won’t support DKIM/DMARC?<a class="headerlink" href="#what-if-a-sender-won-t-support-dkim-dmarc" title="Permalink to this headline">¶</a></h2>
|
||||
<ol class="arabic simple">
|
||||
<li>Some vendors don’t know about DMARC yet; ask about SPF and DKIM/email
|
||||
authentication.</li>
|
||||
<li>Check if they can send through your email relays instead of theirs.</li>
|
||||
<li>Do they really need to spoof your domain? Why not use the display
|
||||
name instead?</li>
|
||||
<li>Worst case, have that vendor send email as a specific subdomain of
|
||||
your domain (e.g. <code class="docutils literal notranslate"><span class="pre">noreply@news.example.com</span></code>), and then create
|
||||
separate SPF and DMARC records on <code class="docutils literal notranslate"><span class="pre">news.example.com</span></code>, and set
|
||||
<code class="docutils literal notranslate"><span class="pre">p=none</span></code> in that DMARC record.</li>
|
||||
</ol>
|
||||
<blockquote>
|
||||
<div><div class="admonition warning">
|
||||
<p class="first admonition-title">Warning</p>
|
||||
<p class="last">Do not alter the <code class="docutils literal notranslate"><span class="pre">p</span></code> or <code class="docutils literal notranslate"><span class="pre">sp</span></code> values of the DMARC record on the
|
||||
Top-Level Domain (TLD) – that would leave you vulnerable to spoofing of
|
||||
your TLD and/or any subdomain.</p>
|
||||
</div>
|
||||
</div></blockquote>
|
||||
</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>
|
||||
@@ -1059,7 +1244,7 @@ to a callback function</p>
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT:'./',
|
||||
VERSION:'3.6.0',
|
||||
VERSION:'3.7.0',
|
||||
LANGUAGE:'None',
|
||||
COLLAPSE_INDEX:false,
|
||||
FILE_SUFFIX:'.html',
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
# Sphinx inventory version 2
|
||||
# Project: parsedmarc
|
||||
# Version: 3.6.0
|
||||
# Version: 3.7.0
|
||||
# The remainder of this file is compressed using zlib.
|
||||
xÚ”KNÃ0†÷=…lSÑmw©‹HU‹ÄÒríibÉŽ-{RRV\ƒëqì$¥¥°ˆ;kòÿx±e΃ÐÌqb÷smD£€ÜYh§juÝDz’Mì—xº(òåƒsÆEZ¥©Éì”<GêSRäeé d+°Æa2_ä«»ÙGã ö’§âËxt‰õ®‹§Ô�beâ(hš+Lì×l"9å”�vBð‘ß65�û�•²Ãh©ëLÑÐAà!¨«Ël·ÃÔþÏ�VÆcB™šIòûF¥P-:Æ‘¶Z�fÊp·î4TëéÖæ²1m’ÉЬWiGcU£YMQjðÈ´��aš10Ú£;þÜ„TöHicoq¶9‰ô�¶›ýehzÕâGÙ>Ž�û]ªÏYíÉ6ݯg´Íø¾½0äÕ˜]-¡î"Ä£˜+¶E²9D;YÄãä(†Gщâ7a7Ñ�ã%>ÞÞ= ÚFC�,¦¿š„‡ó—tvŸ>ô~Eÿæö‰‡·åÑÇzñºÿ¾d%L>%;¤ë
|
||||
+3
-3
@@ -8,7 +8,7 @@
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>Python Module Index — parsedmarc 3.6.0 documentation</title>
|
||||
<title>Python Module Index — parsedmarc 3.7.0 documentation</title>
|
||||
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
|
||||
|
||||
<div class="version">
|
||||
3.6.0
|
||||
3.7.0
|
||||
</div>
|
||||
|
||||
|
||||
@@ -200,7 +200,7 @@
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT:'./',
|
||||
VERSION:'3.6.0',
|
||||
VERSION:'3.7.0',
|
||||
LANGUAGE:'None',
|
||||
COLLAPSE_INDEX:false,
|
||||
FILE_SUFFIX:'.html',
|
||||
|
||||
+3
-3
@@ -8,7 +8,7 @@
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>Search — parsedmarc 3.6.0 documentation</title>
|
||||
<title>Search — parsedmarc 3.7.0 documentation</title>
|
||||
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
|
||||
<div class="version">
|
||||
3.6.0
|
||||
3.7.0
|
||||
</div>
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT:'./',
|
||||
VERSION:'3.6.0',
|
||||
VERSION:'3.7.0',
|
||||
LANGUAGE:'None',
|
||||
COLLAPSE_INDEX:false,
|
||||
FILE_SUFFIX:'.html',
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user