1# parsedmarc {#module-services-parsedmarc}
2[parsedmarc](https://domainaware.github.io/parsedmarc/) is a service
3which parses incoming [DMARC](https://dmarc.org/) reports and stores
4or sends them to a downstream service for further analysis. In
5combination with Elasticsearch, Grafana and the included Grafana
6dashboard, it provides a handy overview of DMARC reports over time.
7
8## Basic usage {#module-services-parsedmarc-basic-usage}
9A very minimal setup which reads incoming reports from an external
10email address and saves them to a local Elasticsearch instance looks
11like this:
12
13```nix
14services.parsedmarc = {
15 enable = true;
16 settings.imap = {
17 host = "imap.example.com";
18 user = "alice@example.com";
19 password = "/path/to/imap_password_file";
20 watch = true;
21 };
22 provision.geoIp = false; # Not recommended!
23};
24```
25
26Note that GeoIP provisioning is disabled in the example for
27simplicity, but should be turned on for fully functional reports.
28
29## Local mail
30Instead of watching an external inbox, a local inbox can be
31automatically provisioned. The recipient's name is by default set to
32`dmarc`, but can be configured in
33[services.parsedmarc.provision.localMail.recipientName](options.html#opt-services.parsedmarc.provision.localMail.recipientName). You
34need to add an MX record pointing to the host. More concretely: for
35the example to work, an MX record needs to be set up for
36`monitoring.example.com` and the complete email address that should be
37configured in the domain's dmarc policy is
38`dmarc@monitoring.example.com`.
39
40```nix
41services.parsedmarc = {
42 enable = true;
43 provision = {
44 localMail = {
45 enable = true;
46 hostname = monitoring.example.com;
47 };
48 geoIp = false; # Not recommended!
49 };
50};
51```
52
53## Grafana and GeoIP
54The reports can be visualized and summarized with parsedmarc's
55official Grafana dashboard. For all views to work, and for the data to
56be complete, GeoIP databases are also required. The following example
57shows a basic deployment where the provisioned Elasticsearch instance
58is automatically added as a Grafana datasource, and the dashboard is
59added to Grafana as well.
60
61```nix
62services.parsedmarc = {
63 enable = true;
64 provision = {
65 localMail = {
66 enable = true;
67 hostname = url;
68 };
69 grafana = {
70 datasource = true;
71 dashboard = true;
72 };
73 };
74};
75
76# Not required, but recommended for full functionality
77services.geoipupdate = {
78 settings = {
79 AccountID = 000000;
80 LicenseKey = "/path/to/license_key_file";
81 };
82};
83
84services.grafana = {
85 enable = true;
86 addr = "0.0.0.0";
87 domain = url;
88 rootUrl = "https://" + url;
89 protocol = "socket";
90 security = {
91 adminUser = "admin";
92 adminPasswordFile = "/path/to/admin_password_file";
93 secretKeyFile = "/path/to/secret_key_file";
94 };
95};
96
97services.nginx = {
98 enable = true;
99 recommendedTlsSettings = true;
100 recommendedOptimisation = true;
101 recommendedGzipSettings = true;
102 recommendedProxySettings = true;
103 upstreams.grafana.servers."unix:/${config.services.grafana.socket}" = {};
104 virtualHosts.${url} = {
105 root = config.services.grafana.staticRootPath;
106 enableACME = true;
107 forceSSL = true;
108 locations."/".tryFiles = "$uri @grafana";
109 locations."@grafana".proxyPass = "http://grafana";
110 };
111};
112users.users.nginx.extraGroups = [ "grafana" ];
113```