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```