1

I am after suggestions on how to implement email sending of OpenDMARC-Reports. The problem I am having, is that (for obvious reasons), I have implemented SASL authentication on the smtpd server for all accounts. I have had a look at the OpenDMARC-Reports source code, and from what I can tell, the only authentication to the SMTP server it does is finding out the FQDN of the host it resides on. FYI, I have implemented SASL authentication via Dovecot, which in turn accesses MySQL for the email/user/password information.

Ideally, I would like to be able to either : a) use a linux service account (say OpenDMARC) to locally send out emails via a separate smtp route, or b) have OpenDMARC-Reports send resulting files to a file, then have an email client (say mutt) to handle the email transfers. (OpenDMARC-Reports does this, but it does not set the 'email sent' flag on the domains - only when it is emailing the report.)

Any suggestions welcome.

Tom Thorp
  • 11
  • 1
  • Did you possibly remove `permit_mynetworks` from your Postfix configuration when you were still using that to allow locally submitted messages without authentication? As long as your `ReportCommand` is unset or behaves like the default (`sendmail -t`), opendmarc can send mail without credentials just fine. – anx Sep 13 '22 at 16:01
  • permit_mynetworks is definitely in smtpd_sender_restrictions, smtpd_helo_restrictions, smtpd_recipient_restrictions and smtpd_relay_restrictions. The email gets as far as being submitted to the smtpd queue, where it promptly bounces because there is no authentication header to authenticate to an account on dovecot. Incidently, I can receive scheduled OpenDMARC reports from one of the domains I use for sending emails, as it doesn't have to tranverse via smtp. – Tom Thorp Sep 14 '22 at 13:11
  • For those interested, I have re-written OpenDMARC-Reports so that you have the option of SMTP authentication. I have written a blogpost on my website should anyone be interested in doing the same. https://tomthorp.me/blog/add-smtp-auth-opendmarc-reports – Tom Thorp Sep 23 '22 at 15:45

1 Answers1

2

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,

  1. 127.0.0.1:10025

    • makes it listen on localhost
    • the port 10025 should be used in the opendmarc-reports --smtp-port=10025
  2. smtpd_sender_restrictions = 
        check_sender_access pcre:/etc/postfix/access/sender_dmarc,
        reject
    
    • limits envelope sender addresses that can use this service
    • the file contais PCRE table of the allowed addresses, e.g.,
      /^dmarc-noreply@example\.com$/ OK
      
  3. 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
  4. 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.
  5. A separate cleanup service dmarc-cleanup is used to additional content checks.

    • The header_checks=pcre:/etc/postfix/access/header_dmarc limits the allowed headers.
    • the file contais PCRE table of the allowed headers, e.g.,
      if /^From:/
      !/^From: .*dmarc-noreply@example\.com/ REJECT Only DMARC reports allowed. F
      endif
      
      if /^Subject:/
      !/^Subject: Report Domain:/ REJECT Only DMARC reports allowed. S
      endif
      

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.

Esa Jokinen
  • 46,944
  • 3
  • 83
  • 129