Tags: Docker »»»» Self Hosting
DMARC is an important tool for websites that send e-mails to do so legitimately. Implementation requires catching e-mails containing DMARC reports then using a tool to parse/summarize/report on their content. We look at a simple DMARC reporting tool that is easily deployable using Docker.
In the olden days of the Internet, email inboxes were flooded with SPAM e-mails and other kinds of junquemail. Early e-mail development on the Internet had no thought for security or authentication. But, over the last 25+ years, several tools have come along which add in security and authentication.
One of these tools is DMARC, or Domain-based Message Authentication, Reporting and Conformance. It requires that an e-mail domain owner publish a DNS record giving instructions on authenticating e-mails. Part of those instructions include an e-mail address to which to send DMARC reports. These reports are XML files containing data about e-mails sent by a domain.
Those reports are the subject of todays tutorial. While there are commercial services to process DMARC reports, there are open source tools for that purpose.
One such tool is this pair of projects:
- https://github.com/techsneeze/dmarcts-report-parser -- DMARC Parser
- https://github.com/techsneeze/dmarcts-report-viewer -- DMARC report viewer
To deploy these, I used the following:
This workspace includes a Docker Compose file to describe deployment of these services along with a database. The system is easy to setup, free to use, and is fully open source. The result is an easy-to-view DMARC report.
Deployment infrastructure for DMARC report
I have a virtual private server (VPS) on which I run two websites deployed with Docker. A couple of the websites send emails that must be safely delivered to website users. This means jumping through all the hoops of authenticating the emails to avoid being marked as SPAM.
I use NGINX Proxy Manager in front of the websites primarily because that's the easiest way to manage SSL certificates. It has built-in support for deploying and maintaining certificates from Lets Encrypt.
I also use Portainer to assist with monitoring and managing Docker services. Docker Swarm Mode is enabled - and no Kubernetes.
While I normally put Docker Compose files in the filesystem, and deploy using the docker-compose
command, this time I pasted the Compose file into Portainer.
Preparing your e-mail domain to receive DMARC reports
Before deploying the server in the next section, we must implement DMARC on one or more domains.
The first step is setting up a DMARC record in the DNS for your configuration. In my case, email from the domain is distributed using both the main domain name (thereikipage.com
) and a subdomain (lists.thereikipage.com
). That meant configuring two DNS entries:
_dmarc.thereikipage.com
_dmarc.lists.thereikipage.com
Each of these DNS entries must be a TXT
record, and in my case they contain:
v=DMARC1; p=none; fo=1; rua=mailto:dmarc_agg@EXAMPLE-DOMAIN-NAME.com;ruf=mailto:dmarc_forensic@EXAMPLE-DOMAIN-NAME.com;pct=100
All of this is public record on my domain name, so I'm not revealing anything sensitive. Obviously you substitute your domain in place of thereikipage.com
as appropriate.
There are two email addresses, dmarc_agg
and dmarc_forensic
. In my case, and I don't remember why I did this, I configured both of these as aliases which forward to dmarc
.
I then configured an email address, dmarc
, with my web hosting provider that in turn provides an IMAP mailbox. After a few days DMARC reports started showing up in that IMAP mailbox.
It is important to keep DMARC reports out of your normal email inbox. These reports are meant for software to read, and are not meant for human consumption. An application like what we discuss in the next section is designed for reading and digesting DMARC reports.
Docker Compose file for deploying DMARC reporting system
The Compose file I used is modified a little from the example in gutmensch/docker-dmarc-report
.
version: "3.6"
services:
dmarc-report:
image: "gutmensch/dmarc-report:latest"
hostname: dmarc-report
container_name: dmarc-report
depends_on:
- dmarcdb
ports:
- "1080:80"
networks:
- servernet
- dmarcdbnet
environment:
- "REPORT_DB_HOST=dmarcdb"
- "REPORT_DB_PORT=3306"
- "REPORT_DB_NAME=dmarc_report"
- "REPORT_DB_USER=dmarc_report"
- "REPORT_DB_PASS=DATABASE PASSWORD"
- "PARSER_IMAP_SERVER=mail.DOMAIN NAME.com"
- "PARSER_IMAP_PORT=143"
- "PARSER_IMAP_USER=dmarc@DOMAIN NAME.com"
- "PARSER_IMAP_PASS=IMAP PASSWORD"
- "PARSER_IMAP_READ_FOLDER=Inbox"
- "PARSER_IMAP_MOVE_FOLDER=processed"
- "PARSER_IMAP_MOVE_FOLDER_ERR=error"
dmarcdb:
image: mariadb:10
command: --skip-innodb-read-only-compressed
volumes:
- /opt/dmarc/db:/var/lib/mysql
- /opt/dmarc:/db
networks:
- dmarcdbnet
restart: always
environment:
- "MYSQL_ROOT_PASSWORD=ROOT PASSWORD"
- "MYSQL_DATABASE=dmarc_report"
- "MYSQL_USER=dmarc_report"
- "MYSQL_PASSWORD=DATABASE PASSWORD"
networks:
servernet:
external:
name: servernet
dmarcdbnet:
external:
name: dmarcdbnet
The gutmensch/dmarc-report:latest
container includes the two services mentioned earlier, and everything else required to make a working service. The GitHub repository contains a Dockerfile and instructions.
Within my Docker Swarm, the servernet
virtual network connects between NGINX Proxy Manager and the individual services. That means the dmarc-report
container is registered as the hostname dmarc-report
on the servernet
network.
That means NGINX Proxy Manager must be configured to proxy the public domain name for this DMARC report viewer to http://dmarc-report:1080
.
The database, on the other hand, must not be visible to NGINX Proxy Manager, and must not be visible to the public. For this purpose, I used Portainer to create a new network, dmarcdbnet
, making sure to use the Overlay driver because this is a Docker Swarm. The network is therefore declared here as external
, and is used to connect the two services.
For dmarcdb
the volumes
mounts are there to ensure the data is persistently saved. Otherwise the database is stored within the container storage, and will be deleted any time the container is rebuilt. The /opt/dmarc
path is on the host server.
In the dmarc
service some of the environment variables begin with PARSER_IMAP
. These control access to an IMAP server. In the previous section I outlined how to configure DMARC records in the DNS, and to setup an email address. The DMARC DNS records designate this email address as the recipient of DMARC reports.
Simply put the IMAP configuration settings into these environment variables.
The REPORT_DB
variables in turn correspond to the environment variables for the database.
Launching the DMARC Report stack on Docker
Now that you have the docker-compose.yaml
configured, head to the command line and run this:
$ docker compose up
In older Docker implementations it was required to install a second package, docker-compose
. If this is what you hve installed, use docker-compose up
instead. But, the new way of launching Compose files is with the docker compose
feature built-in to the the docker
command. Notice that the two commands differ by the -
which is missing in the new version. Docker Compose is now bundled with Docker.
Launching it this way lets you see the logging output to diagnose any issues.
Once you're satisfied it's working right add -d
to the command line.
In my case, I instead pasted the Compose file into a Stack in Portainer. Afterward I clicked the button to deploy the stack.
MariaDB and MySQL containers have a behavior where the first time they're launched takes awhile to initialize the database. Be patient the first time around. The dmarc-report
service will likewise take awhile to get going.
After The DMARC reporting service is launched, you can paste the corresponding URL into your browser.
Viewing DMARC reports
There is no authentication to access the DMARC report viewer. Immediately when visiting the URL in your browser you'll see something like this:
The buttons along the top allow you to select specific reports. The hamburger menu button at the far right opens a settings window letting you further customize the user experience.
Clicking on one of the rows causes details to show up at the bottom:
The raw XML shows up by making a setting in the settings area.
I don't know yet how to interpret these results. Whatever DKIM Align means is currently a failure for my site.
Securing access to the DMARC reports
Since there is no authentication, anyone who comes across your DMARC report server can view the data. Isn't it a good idea to have a password or something? But, this specific service has no such protection.
It is deployed behind NGINX Proxy Manager, and that tool has an Access Lists feature. Simply create an access list, then enable it for the domain where the report service is deployed.
Your deployment scenario may have a different way to control access.
Summary
This DMARC report viewer seems to be limited to handling reports for one domain name per instance. For example, there is no method to configure multiple DMARC IMAP mailboxes.
That means you may be deploying multiple instances of this tool. Does it make sense to deploy multiple databases?
It's probably best to follow this approach:
- Create one Compose file for the database, attaching it to the
dmarcdb
network as shown here. - Create another Compose file to house one or more instances of the
dmarc-report
service. - Also deploy PHPMyAdmin so you can create additional databases in the
dmarcdb
server
I have a pair of previous articles discussing the setup of multiple databases in a Docker-hosted MySQL instance:
- Using multiple databases and PHPMyAdmin in a single MySQL Docker instance
- Set up PHPMyAdmin and Wordpress Docker containers using existing MySQL
Bottom line is that this particular tool is an easy way to digest DMARC reports. There are 3rd party services for this purpose, but I was reluctant to hand them my data. This tool makes sure that my data stays in my hands, while avoiding the service fees required by the 3rd party tools.
It is a little finnicky to set this up. And it's troubling that there's no authentication required to view the reports. That means you must take some measures outside the DMARC service to control access.
Remember that the purpose of this exercise is to do your part to stop the spread of SPAM emails. It is important to learn what the reports mean, and to take action.