diff --git a/postfix/defaults/main.yml b/postfix/defaults/main.yml index 98ec6718fbcc74c1ee2080f9ecb79482ae8e52db..c83309f5ccd74a467436e80ba6638ae320d58905 100644 --- a/postfix/defaults/main.yml +++ b/postfix/defaults/main.yml @@ -75,11 +75,18 @@ postfix_verify_spf_testmode: true postfix_enable_srs: false # Note: This requires at least buster-backports or newer. postfix_enable_mta_sts: false +postfix_enable_dkim: false postfix_my_networks: [] postfix_notify_classes: [] postfix_satellite_only: false +postfix_dkim_internal_hosts: + - "127.0.0.1" + - "::1" + - "localhost." + - "{{ ansible_fqdn }}" + ## sane defaults for postfix satellites # # postfix_satellite_only: true diff --git a/postfix/handlers/main.yml b/postfix/handlers/main.yml index 3e156d74a5f75dcb92afbbb8c65488197d014a05..519529d222e57886bb27b1707fdc0d9c856b590a 100644 --- a/postfix/handlers/main.yml +++ b/postfix/handlers/main.yml @@ -23,3 +23,6 @@ - name: postmap transport command: postmap cdb:/etc/postfix/transport + +- name: restart dkimpy-milter + service: name=dkimpy-milter state=restarted diff --git a/postfix/tasks/dkim.yml b/postfix/tasks/dkim.yml index 50f2fba933c44a2d17cdcd823d55aa5a6a4db827..5b7080d7807edf3dd9093148c98ccae246230904 100644 --- a/postfix/tasks/dkim.yml +++ b/postfix/tasks/dkim.yml @@ -1,55 +1,61 @@ ---- +--- -- name: ensure we have opendkim +- name: ensure we have dkimpy-milter apt: name: - - opendkim - - opendkim-tools - state: present - + - dkimpy-milter + state: "{{ 'present' if postfix_enable_dkim else 'absent' }}" + tags: + - mail + - postfix - name: ensure we have keys for any domain command: - cmd: "opendkim-genkey --directory=/etc/dkimkeys --domain={{ item }} --selector={{ item }}-{{ dkim_selector }} --nosubdomains" - creates: - - "/etc/dkimkeys/{{ item }}-{{ dkim_selector }}.private" - - "/etc/dkimkeys/{{ item }}-{{ dkim_selector }}.txt" - become: yes - become_user: opendkim - loop: "{{ postfix_domains + postfix_virtual_domains }}" - - -- name: ensure we have a folder for systemd overrides - file: - state: directory - path: "/etc/systemd/system/opendkim.service.d/" - mode: '0755' - owner: root - group: root - -- name: ensure we run the service without root - copy: - src: "opendkim-systemd-service-override.conf" - dest: "/etc/systemd/system/opendkim.service.d/override.conf" - + cmd: "dknewkey {{ ansible_hostname }}-{{ item }}-{{ dkim_selector }}" + # yamllint disable-line rule:line-length + creates: "/etc/dkimpy-milter/{{ ansible_hostname }}-{{ item }}-{{ dkim_selector }}.*" + chdir: /etc/dkimpy-milter + loop: "{{ (postfix_domains + postfix_virtual_domains)|unique }}" + when: postfix_enable_dkim + tags: + - mail + - postfix - name: ensure we have our config template: - src: "opendkim.conf.j2" - dest: "/etc/opendkim.conf" + src: "dkimpy-milter.conf.j2" + dest: "/etc/dkimpy-milter/dkimpy-milter.conf" owner: root group: root mode: '0644' + notify: restart dkimpy-milter + when: postfix_enable_dkim + tags: + - mail + - postfix - -- name: ensure we have the key table +- name: ensure we have the key and sigining table template: - src: "opendkim-{{ item }}.j2" - dest: "/etc/dkimkeys/{{ item }}" + src: "dkimpy-milter-{{ item }}.j2" + dest: "/etc/dkimpy-milter/{{ item }}" owner: root group: root mode: '0644' loop: - "keytable" - "signingtable" - - "trustedhosts" + notify: restart dkimpy-milter + when: postfix_enable_dkim + tags: + - mail + - postfix + +- name: ensure service is enabled and running + service: + name: dkimpy-milter + state: started + enabled: true + when: postfix_enable_dkim + tags: + - mail + - postfix diff --git a/postfix/tasks/main.yml b/postfix/tasks/main.yml index cfc6d666514e79bc9e7e250435650b513b2278d6..55255cb5b410e03dbf77b3e810acc6268b4320d7 100644 --- a/postfix/tasks/main.yml +++ b/postfix/tasks/main.yml @@ -106,6 +106,7 @@ - import_tasks: mta-sts.yml - import_tasks: spf.yml - import_tasks: srs.yml +- import_tasks: dkim.yml - name: install rt-mailgate if needed apt: diff --git a/postfix/templates/dkimpy-milter-keytable.j2 b/postfix/templates/dkimpy-milter-keytable.j2 new file mode 100644 index 0000000000000000000000000000000000000000..59afb7196340b5590ddb75e80c73c47449a6cf3c --- /dev/null +++ b/postfix/templates/dkimpy-milter-keytable.j2 @@ -0,0 +1,3 @@ +{% for domain in (postfix_domains + postfix_virtual_domains)|unique %} +{{ domain }} {{ domain }}:{{ ansible_hostname }}-{{ domain }}-{{ dkim_selector }}:/etc/dkimpy-milter/{{ ansible_hostname }}-{{ domain }}-{{ dkim_selector }}.key +{% endfor %} diff --git a/postfix/templates/dkimpy-milter-signingtable.j2 b/postfix/templates/dkimpy-milter-signingtable.j2 new file mode 100644 index 0000000000000000000000000000000000000000..ab52f8a8f266a17b4b24d73a22635b3c6ea71b90 --- /dev/null +++ b/postfix/templates/dkimpy-milter-signingtable.j2 @@ -0,0 +1,3 @@ +{% for domain in (postfix_domains + postfix_virtual_domains)|unique %} +*@{{domain}} {{ domain }} +{% endfor %} diff --git a/postfix/templates/dkimpy-milter.conf.j2 b/postfix/templates/dkimpy-milter.conf.j2 new file mode 100644 index 0000000000000000000000000000000000000000..44aebd4e51552c4126520b5c88fa52493cb5447a --- /dev/null +++ b/postfix/templates/dkimpy-milter.conf.j2 @@ -0,0 +1,49 @@ +# This is a basic configuration that can easily be adapted to suit a standard +# installation. For more advanced options, see dkimpy-milter.conf(5). + +# Log to syslog +Syslog yes + +# Required to use local socket with MTAs that access the socket as a non- +# privileged user (e.g. Postfix) +UMask 007 + +KeyTable /etc/dkimpy-milter/keytable +SigningTable /etc/dkimpy-milter/signingtable +InternalHosts {{ postfix_dkim_internal_hosts | join(',') }} + +# Commonly-used options; the commented-out versions show the defaults. +#Canonicalization relaxed/simple +#Mode sv + +# ## Socket socketspec +# ## +# ## Names the socket where this filter should listen for milter connections +# ## from the MTA. Required. Should be in one of these forms: +# ## +# ## inet:port@address to listen on a specific interface +# ## inet:port to listen on all interfaces +# ## local:/path/to/socket to listen on a UNIX domain socket +# +# +Socket inet:8892@localhost + +## PidFile filename +### default /run/dkimpy-milter/dkimpy-milter.pid +### +### Name of the file where the filter should write its pid before beginning +### normal operations. +# +PidFile /run/dkimpy-milter/dkimpy-milter.pid + +## Userid userid +### default dkimpy-milter +### +### Change to user "userid" before starting normal operation? May include +### a group ID as well, separated from the userid by a colon. +# +UserID dkimpy-milter + +Mode sv +MacroList daemon_name|ORIGINATING +MacroListVerify daemon_name|VERIFYING diff --git a/postfix/templates/master.cf.j2 b/postfix/templates/master.cf.j2 index dbd62667c2a55e6af22a531405949dcbfd170492..397781b0ff971f56db652aca7375f7e906cb3920 100644 --- a/postfix/templates/master.cf.j2 +++ b/postfix/templates/master.cf.j2 @@ -16,6 +16,10 @@ smtp inet n - y - - smtpd {% if postfix_enable_postscreen %} smtp inet n - y - 1 postscreen smtpd pass - - y - - smtpd +{% if postfix_enable_dkim %} + -o milter_macro_daemon_name=VERIFYING + -o smtpd_milters=inet:localhost:8892 +{% endif %} {% if postfix_content_filter %} -o content_filter={{ postfix_content_filter }} {% endif %} @@ -36,6 +40,10 @@ submission inet n - y - - smtpd {% if postfix_content_filter %} -o content_filter={{ postfix_content_filter }} {% endif %} +{% if postfix_enable_dkim %} + -o milter_macro_daemon_name=ORIGINATING + -o smtpd_milters=inet:localhost:8892 +{% endif %} {% endif %} {% if postfix_enable_smtps %} smtps inet n - y - - smtpd diff --git a/postfix/templates/opendkim.conf.j2 b/postfix/templates/opendkim.conf.j2 deleted file mode 100644 index 4d53e4bf3ad3792ff22a88ba6f56d30d7957f64e..0000000000000000000000000000000000000000 --- a/postfix/templates/opendkim.conf.j2 +++ /dev/null @@ -1,52 +0,0 @@ -# This is a basic configuration for signing and verifying. It can easily be -# adapted to suit a basic installation. See opendkim.conf(5) and -# /usr/share/doc/opendkim/examples/opendkim.conf.sample for complete -# documentation of available configuration parameters. - -Syslog yes -SyslogSuccess yes -#LogWhy no - -# Common signing and verification parameters. In Debian, the "From" header is -# oversigned, because it is often the identity key used by reputation systems -# and thus somewhat security sensitive. -Canonicalization relaxed/simple -#Mode sv -#SubDomains no -OversignHeaders From - - -# In Debian, opendkim runs as user "opendkim". A umask of 007 is required when -# using a local socket with MTAs that access the socket as a non-privileged -# user (for example, Postfix). You may need to add user "postfix" to group -# "opendkim" in that case. -UserID opendkim -UMask 007 - -# Socket for the MTA connection (required). If the MTA is inside a chroot jail, -# it must be ensured that the socket is accessible. In Debian, Postfix runs in -# a chroot in /var/spool/postfix, therefore a Unix socket would have to be -# configured as shown on the last line below. -Socket local:/run/opendkim/opendkim.sock -#Socket inet:8891@localhost -#Socket inet:8891 -#Socket local:/var/spool/postfix/opendkim/opendkim.sock - -PidFile /run/opendkim/opendkim.pid - -# Hosts for which to sign rather than verify, default is 127.0.0.1. See the -# OPERATION section of opendkim(8) for more information. -#InternalHosts 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12 - -# The trust anchor enables DNSSEC. In Debian, the trust anchor file is provided -# by the package dns-root-data. -TrustAnchorFile /usr/share/dns/root.key -#Nameservers 127.0.0.1 - - -# Specify the list of keys -KeyTable file:/etc/dkimkeys/keytable -# Match keys and domains. To use regular expressions in the file, use refile: instead of file: -SigningTable refile:/etc/dkimkeys/signingtable -# Match a list of hosts whose messages will be signed. By default, only localhost is considered as internal host. -InternalHosts refile:/etc/dkimkeys/trustedhosts