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