6d4aeb4377
GitOrigin-RevId: 0f213d0fee84280d8c3a97f7469b988d6fe5fcdf
124 lines
4.1 KiB
XML
124 lines
4.1 KiB
XML
<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-parsedmarc">
|
||
<title>parsedmarc</title>
|
||
<para>
|
||
<link xlink:href="https://domainaware.github.io/parsedmarc/">parsedmarc</link>
|
||
is a service which parses incoming
|
||
<link xlink:href="https://dmarc.org/">DMARC</link> reports and
|
||
stores or sends them to a downstream service for further analysis.
|
||
In combination with Elasticsearch, Grafana and the included Grafana
|
||
dashboard, it provides a handy overview of DMARC reports over time.
|
||
</para>
|
||
<section xml:id="module-services-parsedmarc-basic-usage">
|
||
<title>Basic usage</title>
|
||
<para>
|
||
A very minimal setup which reads incoming reports from an external
|
||
email address and saves them to a local Elasticsearch instance
|
||
looks like this:
|
||
</para>
|
||
<programlisting>
|
||
services.parsedmarc = {
|
||
enable = true;
|
||
settings.imap = {
|
||
host = "imap.example.com";
|
||
user = "alice@example.com";
|
||
password = "/path/to/imap_password_file";
|
||
};
|
||
provision.geoIp = false; # Not recommended!
|
||
};
|
||
</programlisting>
|
||
<para>
|
||
Note that GeoIP provisioning is disabled in the example for
|
||
simplicity, but should be turned on for fully functional reports.
|
||
</para>
|
||
</section>
|
||
<section xml:id="local-mail">
|
||
<title>Local mail</title>
|
||
<para>
|
||
Instead of watching an external inbox, a local inbox can be
|
||
automatically provisioned. The recipient’s name is by default set
|
||
to <literal>dmarc</literal>, but can be configured in
|
||
<link xlink:href="options.html#opt-services.parsedmarc.provision.localMail.recipientName">services.parsedmarc.provision.localMail.recipientName</link>.
|
||
You need to add an MX record pointing to the host. More
|
||
concretely: for the example to work, an MX record needs to be set
|
||
up for <literal>monitoring.example.com</literal> and the complete
|
||
email address that should be configured in the domain’s dmarc
|
||
policy is <literal>dmarc@monitoring.example.com</literal>.
|
||
</para>
|
||
<programlisting>
|
||
services.parsedmarc = {
|
||
enable = true;
|
||
provision = {
|
||
localMail = {
|
||
enable = true;
|
||
hostname = monitoring.example.com;
|
||
};
|
||
geoIp = false; # Not recommended!
|
||
};
|
||
};
|
||
</programlisting>
|
||
</section>
|
||
<section xml:id="grafana-and-geoip">
|
||
<title>Grafana and GeoIP</title>
|
||
<para>
|
||
The reports can be visualized and summarized with parsedmarc’s
|
||
official Grafana dashboard. For all views to work, and for the
|
||
data to be complete, GeoIP databases are also required. The
|
||
following example shows a basic deployment where the provisioned
|
||
Elasticsearch instance is automatically added as a Grafana
|
||
datasource, and the dashboard is added to Grafana as well.
|
||
</para>
|
||
<programlisting>
|
||
services.parsedmarc = {
|
||
enable = true;
|
||
provision = {
|
||
localMail = {
|
||
enable = true;
|
||
hostname = url;
|
||
};
|
||
grafana = {
|
||
datasource = true;
|
||
dashboard = true;
|
||
};
|
||
};
|
||
};
|
||
|
||
# Not required, but recommended for full functionality
|
||
services.geoipupdate = {
|
||
settings = {
|
||
AccountID = 000000;
|
||
LicenseKey = "/path/to/license_key_file";
|
||
};
|
||
};
|
||
|
||
services.grafana = {
|
||
enable = true;
|
||
addr = "0.0.0.0";
|
||
domain = url;
|
||
rootUrl = "https://" + url;
|
||
protocol = "socket";
|
||
security = {
|
||
adminUser = "admin";
|
||
adminPasswordFile = "/path/to/admin_password_file";
|
||
secretKeyFile = "/path/to/secret_key_file";
|
||
};
|
||
};
|
||
|
||
services.nginx = {
|
||
enable = true;
|
||
recommendedTlsSettings = true;
|
||
recommendedOptimisation = true;
|
||
recommendedGzipSettings = true;
|
||
recommendedProxySettings = true;
|
||
upstreams.grafana.servers."unix:/${config.services.grafana.socket}" = {};
|
||
virtualHosts.${url} = {
|
||
root = config.services.grafana.staticRootPath;
|
||
enableACME = true;
|
||
forceSSL = true;
|
||
locations."/".tryFiles = "$uri @grafana";
|
||
locations."@grafana".proxyPass = "http://grafana";
|
||
};
|
||
};
|
||
users.users.nginx.extraGroups = [ "grafana" ];
|
||
</programlisting>
|
||
</section>
|
||
</chapter>
|