summaryrefslogtreecommitdiffstats
path: root/roles/MX
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2020-05-16 18:26:53 +0200
committerGuilhem Moulin <guilhem@fripost.org>2020-05-16 18:26:55 +0200
commit2f9574850b356a746ee3ff9a8a311c450784b53c (patch)
treeb4da3e9490c148c2ec1a67e7900bc6adaa27ffb9 /roles/MX
parent809a185dca11424cef6220b5314a8b7aed487164 (diff)
MX: Install OpenDMARC to add Authentication-Results headers.
On the infrastructure boundary. We don't reject/quarantine as it would affect members who forward their mail sent to <user@example.com> to <user@fripost.org>. Members can install Sieve rules to send any messages with failed Authentication-Results headers directly in their spambox.
Diffstat (limited to 'roles/MX')
-rw-r--r--roles/MX/files/etc/opendmarc.conf103
-rw-r--r--roles/MX/files/etc/systemd/system/opendmarc.service.d/override.conf17
-rw-r--r--roles/MX/files/etc/systemd/system/opendmarc.socket10
-rw-r--r--roles/MX/handlers/main.yml9
-rw-r--r--roles/MX/tasks/main.yml46
-rw-r--r--roles/MX/templates/etc/postfix/main.cf.j21
6 files changed, 186 insertions, 0 deletions
diff --git a/roles/MX/files/etc/opendmarc.conf b/roles/MX/files/etc/opendmarc.conf
new file mode 100644
index 0000000..4a0b89c
--- /dev/null
+++ b/roles/MX/files/etc/opendmarc.conf
@@ -0,0 +1,103 @@
+# This is a basic configuration that can easily be adapted to suit a standard
+# installation. For more advanced options, see opendkim.conf(5) and/or
+# /usr/share/doc/opendmarc/examples/opendmarc.conf.sample.
+
+## AuthservID (string)
+## defaults to MTA name
+#
+# AuthservID name
+
+## FailureReports { true | false }
+## default "false"
+##
+# FailureReports false
+
+## RejectFailures { true | false }
+## default "false"
+##
+RejectFailures false
+
+## Socket socketspec
+## default (none)
+##
+## Specifies the socket that should be established by the filter to receive
+## connections from sendmail(8) in order to provide service. socketspec is
+## in one of two forms: local:path, which creates a UNIX domain socket at
+## the specified path, or inet:port[@host] or inet6:port[@host] which creates
+## a TCP socket on the specified port for the appropriate protocol family.
+## If the host is not given as either a hostname or an IP address, the
+## socket will be listening on all interfaces. This option is mandatory
+## either in the configuration file or on the command line. If an IP
+## address is used, it must be enclosed in square brackets.
+#
+Socket local:/var/run/opendmarc/opendmarc.sock
+
+## Syslog { true | false }
+## default "false"
+##
+## Log via calls to syslog(3) any interesting activity.
+#
+Syslog true
+
+## SyslogFacility facility-name
+## default "mail"
+##
+## Log via calls to syslog(3) using the named facility. The facility names
+## are the same as the ones allowed in syslog.conf(5).
+#
+# SyslogFacility mail
+
+## TrustedAuthservIDs string
+## default HOSTNAME
+##
+## Specifies one or more "authserv-id" values to trust as relaying true
+## upstream DKIM and SPF results. The default is to use the name of
+## the MTA processing the message. To specify a list, separate each entry
+## with a comma. The key word "HOSTNAME" will be replaced by the name of
+## the host running the filter as reported by the gethostname(3) function.
+#
+# TrustedAuthservIDs HOSTNAME
+
+## SPFIgnoreResults { true | false }
+## default "false"
+##
+## Causes the filter to ignore any SPF results in the header of the message.
+## This is useful if you want the filter to perfrom SPF checks itself, or
+## because you don't trust the arriving header.
+#
+SPFIgnoreResults true
+
+## SPFSelfValidate { true | false }
+## default "false"
+##
+## Causes the filter to perform a fallback SPF check itself when it can
+## find no SPF results in the message header. If SPFIgnoreResults is also
+## set, it never looks for SPF results in headers and always performs the
+## SPF check itself when this is set.
+#
+SPFSelfValidate true
+
+## UMask mask
+## default (none)
+##
+## Requests a specific permissions mask to be used for file creation. This
+## only really applies to creation of the socket when Socket specifies a
+## UNIX domain socket, and to the HistoryFile and PidFile (if any); temporary
+## files are normally created by the mkstemp(3) function that enforces a
+## specific file mode on creation regardless of the process umask. See
+## umask(2) for more information.
+#
+UMask 0007
+
+## UserID user[:group]
+## default (none)
+##
+## Attempts to become the specified userid before starting operations.
+## The process will be assigned all of the groups and primary group ID of
+## the named userid unless an alternate group is specified.
+#
+# UserID opendmarc
+
+## Path to system copy of PSL (needed to determine organizational domain)
+#
+PublicSuffixList /usr/share/publicsuffix/
diff --git a/roles/MX/files/etc/systemd/system/opendmarc.service.d/override.conf b/roles/MX/files/etc/systemd/system/opendmarc.service.d/override.conf
new file mode 100644
index 0000000..1fb5567
--- /dev/null
+++ b/roles/MX/files/etc/systemd/system/opendmarc.service.d/override.conf
@@ -0,0 +1,17 @@
+[Service]
+Type=simple
+User=opendmarc
+ExecStart=
+ExecStart=/usr/sbin/opendmarc -f -p fd:3
+StandardOutput=journal
+SyslogFacility=mail
+RuntimeDirectory=opendmarc
+
+# Hardening
+NoNewPrivileges=yes
+PrivateDevices=yes
+ProtectHome=yes
+ProtectSystem=strict
+ProtectControlGroups=yes
+ProtectKernelModules=yes
+ProtectKernelTunables=yes
diff --git a/roles/MX/files/etc/systemd/system/opendmarc.socket b/roles/MX/files/etc/systemd/system/opendmarc.socket
new file mode 100644
index 0000000..483ef60
--- /dev/null
+++ b/roles/MX/files/etc/systemd/system/opendmarc.socket
@@ -0,0 +1,10 @@
+[Unit]
+Description=OpenDMARC Milter activation socket
+
+[Socket]
+ListenStream=/var/spool/postfix-mx/public/opendmarc
+SocketUser=postfix
+SocketMode=0666
+
+[Install]
+WantedBy=sockets.target
diff --git a/roles/MX/handlers/main.yml b/roles/MX/handlers/main.yml
index 9edf610..00223a5 100644
--- a/roles/MX/handlers/main.yml
+++ b/roles/MX/handlers/main.yml
@@ -1,6 +1,15 @@
---
+- name: systemctl daemon-reload
+ command: /bin/systemctl daemon-reload
+
- name: Reload Postfix
service: name=postfix state=reloaded
- name: Restart munin-node
service: name=munin-node state=restarted
+
+- name: Stop OpenDMARC
+ service: name=opendmarc.service state=stopped
+
+- name: Restart OpenDMARC
+ service: name=opendmarc.socket state=restarted
diff --git a/roles/MX/tasks/main.yml b/roles/MX/tasks/main.yml
index 507a4f2..300dbfb 100644
--- a/roles/MX/tasks/main.yml
+++ b/roles/MX/tasks/main.yml
@@ -137,3 +137,49 @@
- munin-node
notify:
- Restart munin-node
+
+# XXX we probaly want SPF verification for domains without DMARC
+# policies
+- name: Install OpenDMARC
+ apt: pkg=opendmarc
+
+- name: Copy OpenDMARC configuration
+ copy: src=etc/opendmarc.conf
+ dest=/etc/opendmarc.conf
+ owner=root group=root
+ mode=0644
+ notify:
+ - Stop OpenDMARC
+
+- name: Create directory /etc/systemd/system/opendmarc.service.d
+ file: path=/etc/systemd/system/opendmarc.service.d
+ state=directory
+ owner=root group=root
+ mode=0755
+
+- name: Harden OpenDMARC service unit
+ copy: src=etc/systemd/system/opendmarc.service.d/override.conf
+ dest=/etc/systemd/system/opendmarc.service.d/override.conf
+ owner=root group=root
+ mode=0644
+ notify:
+ - systemctl daemon-reload
+ - Stop OpenDMARC
+
+- meta: flush_handlers
+
+- name: Copy OpenDMARC socket unit
+ copy: src=etc/systemd/system/opendmarc.socket
+ dest=/etc/systemd/system/opendmarc.socket
+ owner=root group=root
+ mode=0644
+ register: r
+ notify:
+ - systemctl daemon-reload
+ - Restart OpenDMARC
+
+- name: Disable OpenDMARC service
+ service: name=opendmarc.service enabled=false
+
+- name: Start OpenDMARC socket
+ service: name=opendmarc.socket state=started enabled=true
diff --git a/roles/MX/templates/etc/postfix/main.cf.j2 b/roles/MX/templates/etc/postfix/main.cf.j2
index a2cc2a8..5c2f97b 100644
--- a/roles/MX/templates/etc/postfix/main.cf.j2
+++ b/roles/MX/templates/etc/postfix/main.cf.j2
@@ -123,6 +123,7 @@ postscreen_dnsbl_sites =
postscreen_greet_action = enforce
postscreen_whitelist_interfaces = static:all
+smtpd_milters = { unix:public/opendmarc, protocol=6, default_action=accept }
smtpd_client_restrictions =
permit_mynetworks