瀏覽代碼

Implement OpenDMARC. Resolves #369.

Alex Payne 9 年之前
父節點
當前提交
26d61c68a8

+ 10
- 0
roles/mailserver/files/etc_default_opendmarc 查看文件

@@ -0,0 +1,10 @@
1
+# Command-line options specified here will override the contents of
2
+# /etc/opendmarc.conf. See opendmarc(8) for a complete list of options.
3
+#DAEMON_OPTS=""
4
+#
5
+# Uncomment to specify an alternate socket
6
+# Note that setting this will override any Socket value in opendkim.conf
7
+SOCKET="inet:54321" # listen on all interfaces on port 54321
8
+#SOCKET="local:/var/run/opendmarc/opendmarc.sock" # default
9
+#SOCKET="inet:12345@localhost" # listen on loopback on port 12345
10
+#SOCKET="inet:12345@192.0.2.1" # listen on 192.0.2.1 on port 12345

+ 89
- 0
roles/mailserver/files/etc_opendmarc_import.sql 查看文件

@@ -0,0 +1,89 @@
1
+-- OpenDMARC database schema
2
+--
3
+-- Copyright (c) 2012, The Trusted Domain Project.
4
+--      All rights reserved.
5
+
6
+USE opendmarc;
7
+
8
+-- A table for mapping domain names and their DMARC policies to IDs
9
+CREATE TABLE IF NOT EXISTS domains (
10
+        id INT NOT NULL AUTO_INCREMENT,
11
+        name VARCHAR(255) NOT NULL,
12
+        firstseen TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
13
+
14
+        PRIMARY KEY(id),
15
+        UNIQUE KEY(name)
16
+);
17
+
18
+-- A table for logging reporting requests
19
+CREATE TABLE IF NOT EXISTS requests (
20
+        id INT NOT NULL AUTO_INCREMENT,
21
+        domain INT NOT NULL,
22
+        repuri VARCHAR(255) NOT NULL,
23
+        adkim TINYINT NOT NULL,
24
+        aspf TINYINT NOT NULL,
25
+        policy TINYINT NOT NULL,
26
+        spolicy TINYINT NOT NULL,
27
+        pct TINYINT NOT NULL,
28
+        locked TINYINT NOT NULL,
29
+        firstseen TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
30
+        lastsent TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
31
+
32
+        PRIMARY KEY(id),
33
+        KEY(lastsent),
34
+        UNIQUE KEY(domain)
35
+);
36
+
37
+-- A table for reporting hosts
38
+CREATE TABLE IF NOT EXISTS reporters (
39
+        id INT NOT NULL AUTO_INCREMENT,
40
+        name VARCHAR(255) NOT NULL,
41
+        firstseen TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
42
+
43
+        PRIMARY KEY(id),
44
+        UNIQUE KEY(name)
45
+);
46
+
47
+-- A table for IP addresses
48
+CREATE TABLE IF NOT EXISTS ipaddr (
49
+	id INT NOT NULL AUTO_INCREMENT,
50
+	addr VARCHAR(64) NOT NULL,
51
+	firstseen TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
52
+
53
+	PRIMARY KEY(id),
54
+	UNIQUE KEY(addr)
55
+);
56
+
57
+-- A table for messages
58
+CREATE TABLE IF NOT EXISTS messages (
59
+        id INT NOT NULL AUTO_INCREMENT,
60
+        date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
61
+        jobid VARCHAR(128) NOT NULL,
62
+        reporter INT UNSIGNED NOT NULL,
63
+        policy TINYINT UNSIGNED NOT NULL,
64
+        disp TINYINT UNSIGNED NOT NULL,
65
+        ip INT UNSIGNED NOT NULL,
66
+        env_domain INT UNSIGNED NOT NULL,
67
+        from_domain INT UNSIGNED NOT NULL,
68
+        policy_domain INT UNSIGNED NOT NULL,
69
+        spf TINYINT UNSIGNED NOT NULL,
70
+        align_dkim TINYINT UNSIGNED NOT NULL,
71
+        align_spf TINYINT UNSIGNED NOT NULL,
72
+        sigcount TINYINT UNSIGNED NOT NULL,
73
+
74
+        PRIMARY KEY(id),
75
+        KEY(date),
76
+        UNIQUE KEY(reporter, date, jobid)
77
+);
78
+
79
+-- A table for signatures
80
+CREATE TABLE IF NOT EXISTS signatures (
81
+        id INT NOT NULL AUTO_INCREMENT,
82
+        message INT NOT NULL,
83
+        domain INT NOT NULL,
84
+        pass TINYINT NOT NULL,
85
+        error TINYINT NOT NULL,
86
+
87
+        PRIMARY KEY(id),
88
+        KEY(message)
89
+);

+ 3
- 0
roles/mailserver/handlers/main.yml 查看文件

@@ -13,3 +13,6 @@
13 13
 - name: import sql postfix
14 14
   action: shell PGPASSWORD='{{ mail_db_password }}' psql -h localhost -d {{ mail_db_database }} -U {{ mail_db_username }} -f /etc/postfix/import.sql --set ON_ERROR_STOP=1
15 15
   notify: restart postfix
16
+
17
+- name: restart opendmarc
18
+  service: name=opendmarc state=restarted

+ 38
- 0
roles/mailserver/tasks/dmarc.yml 查看文件

@@ -0,0 +1,38 @@
1
+- name: Install OpenDMARC milter
2
+  apt: pkg=opendmarc state=installed update_cache=yes
3
+
4
+- name: Copy OpenDMARC configuration file into place
5
+  template: src=etc_opendmarc.conf.j2 dest=/etc/opendmarc.conf owner=root group=root
6
+  notify: restart opendmarc
7
+
8
+- name: Create OpenDMARC configuration directory
9
+  file: state=directory path=/etc/opendmarc
10
+
11
+- name: Copy OpenDMARC ignore hosts file into place
12
+  template: src=etc_opendmarc_ignore.hosts.j2 dest=/etc/opendmarc/ignore.hosts owner=root group=root
13
+
14
+- name: Copy OpenDMARC defaults file into place
15
+  copy: src=etc_default_opendmarc dest=/etc/default/opendmarc owner=root group=root
16
+  notify:
17
+    - restart opendmarc
18
+    - restart postfix
19
+
20
+- name: Copy OpenDMARC database schema file into place
21
+  copy: src=etc_opendmarc_import.sql dest=/etc/opendmarc/import.sql owner=root group=root
22
+
23
+- name: Create database user for OpenDMARC reports
24
+  mysql_user: user={{ mail_db_opendmarc_username }} password={{ mail_db_opendmarc_password }} state=present priv="opendmarc.*:ALL"
25
+
26
+- name: Create database for OpenDMARC reports
27
+  mysql_db: name={{ mail_db_opendmarc_database }} state=present
28
+
29
+- name: Import database schema for OpenDMARC reports
30
+  mysql_db: name={{ mail_db_opendmarc_database }} state=import target=/etc/opendmarc/import.sql
31
+  tags: import_mysql_postfix
32
+
33
+- name: Copy nightly OpenDMARC report generation script into place
34
+  template: src=etc_opendmarc_report.sh.j2 dest=/etc/opendmarc/report.sh owner=root group=root mode="755"
35
+
36
+- name: Activate OpenDMARC report cronjob
37
+  cron: name="OpenDMARC report" hour="2" minute="0" job="/bin/bash /etc/opendmarc/report.sh >> /var/log/opendmarc_report.log"
38
+

+ 2
- 0
roles/mailserver/tasks/main.yml 查看文件

@@ -1,8 +1,10 @@
1 1
 - include: postfix.yml tags=postfix
2 2
 - include: dovecot.yml tags=dovecot
3 3
 - include: opendkim.yml tags=opendkim
4
+- include: dmarc.yml tags=dmarc
4 5
 - include: dspam.yml tags=dspam
5 6
 - include: solr.yml tags=solr
6 7
 - include: checkrbl.yml tags=checkrbl
7 8
 - include: z-push.yml tags=zpush
8 9
 - include: autoconfig.yml tags=autoconfig
10
+

+ 85
- 0
roles/mailserver/templates/etc_opendmarc.conf.j2 查看文件

@@ -0,0 +1,85 @@
1
+# This is a basic configuration that can easily be adapted to suit a standard
2
+# installation. For more advanced options, see opendkim.conf(5) and/or
3
+# /usr/share/doc/opendmarc/examples/opendmarc.conf.sample.
4
+
5
+##  AuthservID (string)
6
+##      defaults to MTA name
7
+#
8
+AuthservID {{ mail_server_hostname }}
9
+
10
+##  ForensicReports { true | false }
11
+##      default "false"
12
+##
13
+# ForensicReports false
14
+
15
+PidFile /var/run/opendmarc.pid
16
+
17
+##  RejectFailures { true | false }
18
+##      default "false"
19
+##
20
+RejectFailures false
21
+
22
+##  Syslog { true | false }
23
+##      default "false"
24
+##
25
+##  Log via calls to syslog(3) any interesting activity.
26
+#
27
+Syslog true
28
+
29
+##  SyslogFacility facility-name
30
+##      default "mail"
31
+##
32
+##  Log via calls to syslog(3) using the named facility.  The facility names
33
+##  are the same as the ones allowed in syslog.conf(5).
34
+#
35
+# SyslogFacility mail
36
+
37
+##  TrustedAuthservIDs string
38
+##      default HOSTNAME
39
+##
40
+##  Specifies one or more "authserv-id" values to trust as relaying true
41
+##  upstream DKIM and SPF results.  The default is to use the name of
42
+##  the MTA processing the message.  To specify a list, separate each entry
43
+##  with a comma.  The key word "HOSTNAME" will be replaced by the name of
44
+##  the host running the filter as reported by the gethostname(3) function.
45
+#
46
+TrustedAuthservIDs {{ mail_server_hostname }}
47
+
48
+
49
+##  UMask mask
50
+##      default (none)
51
+##
52
+##  Requests a specific permissions mask to be used for file creation.  This
53
+##  only really applies to creation of the socket when Socket specifies a
54
+##  UNIX domain socket, and to the HistoryFile and PidFile (if any); temporary
55
+##  files are normally created by the mkstemp(3) function that enforces a
56
+##  specific file mode on creation regardless of the process umask.  See
57
+##  umask(2) for more information.
58
+#
59
+UMask 0002
60
+
61
+##  UserID user[:group]
62
+##      default (none)
63
+##
64
+##  Attempts to become the specified userid before starting operations.
65
+##  The process will be assigned all of the groups and primary group ID of
66
+##  the named userid unless an alternate group is specified.
67
+#
68
+UserID opendmarc:opendmarc
69
+
70
+## The path to the Ignored Hosts list. This file should contain a list of
71
+## networks and hosts that you trust. Their mail will not be checked by
72
+## OpenDMARC.
73
+#
74
+IgnoreHosts /etc/opendmarc/ignore.hosts
75
+
76
+## The path under which the History file should be created.
77
+## This file is necessary if you want to be able to create aggregate
78
+## reports to send out to other organizations
79
+#
80
+HistoryFile /var/run/opendmarc/opendmarc.dat
81
+
82
+## Adds a “Dmarc-Filter” header with the opendmarc version in every processed mail.
83
+## This is good to have during testing.
84
+#
85
+SoftwareHeader true

+ 4
- 0
roles/mailserver/templates/etc_opendmarc_ignore.hosts.j2 查看文件

@@ -0,0 +1,4 @@
1
+localhost
2
+10.0.0.0/24
3
+{{ ansible_default_ipv4.address }}
4
+{{ "/n".join(friendly_networks) }}

+ 19
- 0
roles/mailserver/templates/etc_opendmarc_report.sh.j2 查看文件

@@ -0,0 +1,19 @@
1
+#!/bin/bash
2
+
3
+DB_SERVER='localhost'
4
+DB_USER='{{ mail_db_opendmarc_username }}'
5
+DB_PASS='{{ mail_db_opendmarc_password }}'
6
+DB_NAME='{{ mail_db_opendmarc_database }}'
7
+WORK_DIR='/var/run/opendmarc'
8
+REPORT_EMAIL='{{ admin_email }}'
9
+
10
+mv ${WORK_DIR}/opendmarc.dat ${WORK_DIR}/opendmarc_import.dat -f
11
+cat /dev/null > ${WORK_DIR}/opendmarc.dat
12
+
13
+/usr/sbin/opendmarc-import --dbhost=${DB_SERVER} --dbuser=${DB_USER} --dbpasswd=${DB_PASS} --dbname=${DB_NAME} --verbose < ${WORK_DIR}/opendmarc_import.dat
14
+
15
+{% for domain in mail_virtual_domains %}
16
+/usr/sbin/opendmarc-reports --dbhost=${DB_SERVER} --dbuser=${DB_USER} --dbpasswd=${DB_PASS} --dbname=${DB_NAME} --verbose --interval=86400 --report-email $REPORT_EMAIL --report-org '{{ domain.name }}'
17
+{% endfor %}
18
+
19
+/usr/sbin/opendmarc-expire --dbhost=${DB_SERVER} --dbuser=${DB_USER} --dbpasswd=${DB_PASS} --dbname=${DB_NAME} --verbose

+ 2
- 2
roles/mailserver/templates/etc_postfix_main.cf.j2 查看文件

@@ -98,8 +98,8 @@ virtual_mailbox_maps = pgsql:/etc/postfix/pgsql-virtual-mailbox-maps.cf
98 98
 virtual_alias_maps = pgsql:/etc/postfix/pgsql-virtual-alias-maps.cf
99 99
 local_recipient_maps = $virtual_mailbox_maps
100 100
 
101
-# OpenDKIM
102
-smtpd_milters = inet:127.0.0.1:8891
101
+# OpenDKIM and OpenDMARC
102
+smtpd_milters = inet:127.0.0.1:8891,inet:127.0.0.1:54321
103 103
 non_smtpd_milters = $smtpd_milters
104 104
 milter_default_action = accept
105 105
 

+ 3
- 0
vars/defaults.yml 查看文件

@@ -63,6 +63,9 @@ mail_db_database: mailserver
63 63
 # mail_virtual_domains: (required)
64 64
 # mail_virtual_users: (required)
65 65
 # mail_virtual_aliases: (required)
66
+mail_db_opendmarc_username: opendmarc
67
+# mail_db_opendmarc_password: (required)
68
+mail_db_opendmarc_database: opendmarc
66 69
 
67 70
 # z-push
68 71
 zpush_version: 2.1.1-1788

+ 1
- 0
vars/user.yml 查看文件

@@ -24,6 +24,7 @@ irc_timezone: TODO      #Example: "America/New_York"
24 24
 
25 25
 # mailserver
26 26
 mail_db_password: TODO
27
+mail_db_opendmarc_password: TODO
27 28
 mail_virtual_domains:
28 29
   - name: "{{ domain }}"
29 30
     pk_id: 1

Loading…
取消
儲存