This is indeed a horrible shortcoming in the opendmarc-reports
script. Your solution for patching the script is brilliant, and I wish to see it as a pull request to The Trusted Domain Project, fixing the problem at its root. The man page should be updated accordingly, too.
This answer contains
- an alternative solution compatible with the current reporting tools
- a security warning considering the script used in your current approach.
Separate unauthenticated smtpd
for OpenDMARC reports
An alternative solution compatible with the current script would be adding a separate, unauthenticated smtpd
to the master.cf
. This way, the smtpd
used by your users for email submission can be left SASL authenticated.
Some compromises are made; this is not completely secure against abuse from local users, but can be only used for sending messages from certain addresses with content limitations. Furthermore, abuse of this service is easy to detect from the logs, as it should only be used once a day.
# Allow DMARC reports, as OpenDMARC aggregate report generation tool is a bit limited
127.0.0.1:10025 inet n - - - - smtpd
-o mynetworks=127.0.0.0/8
-o { smtpd_sender_restrictions = check_sender_access pcre:/etc/postfix/access/sender_dmarc, reject }
-o { smtpd_recipient_restrictions = permit_mynetworks, reject }
-o cleanup_service_name=dmarc-cleanup
-o milter_default_action=accept
-o smtpd_milters=inet:localhost:8891
-o non_smtpd_milters=inet:localhost:8891
dmarc-cleanup unix n - y - 0 cleanup
-o header_checks=pcre:/etc/postfix/access/header_dmarc
Here,
127.0.0.1:10025
- makes it listen on localhost
- the port
10025
should be used in the opendmarc-reports --smtp-port=10025
-
smtpd_sender_restrictions =
check_sender_access pcre:/etc/postfix/access/sender_dmarc,
reject
-
smtpd_recipient_restrictions =
permit_mynetworks,
reject
- allows sending from
mynetworks=127.0.0.0/8
only
- in case this parameter in the
main.cf
is less restrictive
An OpenDKIM milter on localhost:8891
is used for DKIM signing.
- The lines containing
milter
can be removed if DKIM signing is not used.
- If your OpenDKIM is listening on a UNIX socket, replace the
inet:
with, e.g., local:opendkim/opendkim.sock
.
A separate cleanup
service dmarc-cleanup
is used to additional content checks.
Security warning: DO NOT leak credentials as command line arguments!
The script used in your solution, copied all over the Internet since 2015, has a security flaw: it passes credentials on the command line. As command line arguments the credentials are visible to all the users (e.g. in ps ax
).
Luckily, the OpenDMARC reporting tools can get these settings from environment variables, too:
Environment variable |
Equivalent command line option |
Default value |
$OPENDMARC_DBHOST |
--dbhost |
localhost |
$OPENDMARC_PORT |
--dbport |
3306 |
$OPENDMARC_DB |
--dbname |
opendmarc |
$OPENDMARC_USER |
--dbuser |
opendmarc |
$OPENDMARC_PASSWORD |
--dbpasswd |
opendmarc |
I have written an improved script solving this security issue; GitHub oh2fih / OpenDMARC-Reports. The example solution contains SystemD units for automating the reporting & stores all the settings as environment variables in a protected file.