From c21b92d9b79a80a27607618666b56fbc5cd26ac8 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Mon, 3 Dec 2018 23:13:04 +0100 Subject: Upgrade DKIM keys to rsa2048, and allow for multiple keys. --- certs/dkim/8f00fb94ec6c37aacb48bd43e073f9b7.pub | 9 +++++++++ certs/dkim/9df9cdc7e101629b5003b587945afa70.pub | 9 +++++++++ certs/dkim/README | 11 +++++++++++ group_vars/all.yml | 12 ++++++++++++ roles/amavis/handlers/main.yml | 4 ---- roles/amavis/tasks/main.yml | 19 +++++++++++++++---- roles/amavis/templates/etc/amavis/conf.d/50-user.j2 | 18 +++++++++++++----- 7 files changed, 69 insertions(+), 13 deletions(-) create mode 100644 certs/dkim/8f00fb94ec6c37aacb48bd43e073f9b7.pub create mode 100644 certs/dkim/9df9cdc7e101629b5003b587945afa70.pub create mode 100644 certs/dkim/README diff --git a/certs/dkim/8f00fb94ec6c37aacb48bd43e073f9b7.pub b/certs/dkim/8f00fb94ec6c37aacb48bd43e073f9b7.pub new file mode 100644 index 0000000..ef400f4 --- /dev/null +++ b/certs/dkim/8f00fb94ec6c37aacb48bd43e073f9b7.pub @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApmCWIVZt+L/bJ5+abvdm +Fm6Er/9g6e4WX2HKyeIfC5eDaPbUyHqHSY7xzWNiU+cbBvny8BASkdWsclLdoiuM +J6Yes5VSzkH6j2gp9Uuy7d6p61Jbrizi7/CQzCZfhi5uGKiGtV2g+V/sIuXekm9Q ++Q2eqjj/6hUHGDPTTKEFlgruyaS6y+Kes+sJYjMG62lbTOKL5TjY6z0Gr2AMfglB +Uj9QWD5jm+bH0clE1HZq51mxXQbV2v/7JEHjznR0nSB+jY2EV7g/MXM8DwJCDH4Z +cknoH0NrcJRjuRt8ndufnx4Qh0t7qqWwmGF0jZOcZxHeODfkUlLxQ4SCMVeqV/SS +TwIDAQAB +-----END PUBLIC KEY----- diff --git a/certs/dkim/9df9cdc7e101629b5003b587945afa70.pub b/certs/dkim/9df9cdc7e101629b5003b587945afa70.pub new file mode 100644 index 0000000..2574f71 --- /dev/null +++ b/certs/dkim/9df9cdc7e101629b5003b587945afa70.pub @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyN6rMmDzZ0MtN6e+T3lS +wny1qs0djjXJMJi5gfCXl9ZW4v5LT098EtpEQsDfY8NY3PvuBTD74Xsvy9jRh71/ +q0iZHHwOffQlP8BVi2uelO9brVBr9nHWvycbEp/PXMVPOSBRuXyrvIYPnWjmaPZc +xT4L3OB5BtZPsGElxAzZMbTDzRr8K0yIY/HtVTXD5JJsKb3GIXiyHY7GCvV6tKeP +eI2L0vJOJ2LLHHX962ykWHAfS12izkfBxGkMVn4AQZIPQ4iGwAPZ9z5DIsz11Riw ++3ysWWdmz2yV8HtoDKfOB4/vyFyWFlyaMkdvblDjgQv0m6bHwvXlxAGSWcZirmEM +pQIDAQAB +-----END PUBLIC KEY----- diff --git a/certs/dkim/README b/certs/dkim/README new file mode 100644 index 0000000..e5addf9 --- /dev/null +++ b/certs/dkim/README @@ -0,0 +1,11 @@ +To convert a PEM-encoded public key to a TXT record, run + + $ SELECTOR="8f00fb94ec6c37aacb48bd43e073f9b7" + $ DOMAIN="fripost.org" + $ printf "%s._domainkey%s IN TXT (\n" "$SELECTOR" "${DOMAIN:+.$DOMAIN.}"; \ + { printf "v=DKIM1; k=rsa; t=s; s=email; p="; + sed '/^--.*--$/d' <"./certs/dkim/$SELECTOR.pub" | tr -d '\n'; + } | fold -w64 | sed 's/.*/ "&"/; $s/$/ )\n/' + +Remove the "t=s" tag if subdomaining or third-party signature (hosted +domain) is required, cf. RFC 6376 sec. 3.6.1. diff --git a/group_vars/all.yml b/group_vars/all.yml index 49cf935..f222b56 100644 --- a/group_vars/all.yml +++ b/group_vars/all.yml @@ -46,3 +46,15 @@ postfix_instance: , port: 2527 } imapsvr_addr: "{{ postfix_instance.IMAP.addr | ipaddr }}" + +dkim_keys: + giraff: + # match key + "fripost.org": + # domain of the entity signing the message (should be unique accross match keys) + d: fripost.org + # selector (should be globally unique and random) + s: 8f00fb94ec6c37aacb48bd43e073f9b7 + "~": # catch-all, for our virtual domains + d: x.fripost.org + s: 9df9cdc7e101629b5003b587945afa70 diff --git a/roles/amavis/handlers/main.yml b/roles/amavis/handlers/main.yml index 62cc6fc..684be0f 100644 --- a/roles/amavis/handlers/main.yml +++ b/roles/amavis/handlers/main.yml @@ -2,10 +2,6 @@ - name: Restart ClamAV service: name=clamav-daemon state=restarted -- name: Publish the public key to the DNS zone - # See the output of 'genkeypair.sh dkim --privkey=/path/to/key' - fail: "msg={{ dkim.stdout }}" - - name: Restart Amavis service: name=amavis state=restarted diff --git a/roles/amavis/tasks/main.yml b/roles/amavis/tasks/main.yml index 936703a..92a0e81 100644 --- a/roles/amavis/tasks/main.yml +++ b/roles/amavis/tasks/main.yml @@ -41,26 +41,37 @@ owner=root group=root mode=0644 -- name: Create directory /var/lib/dkim - file: path=/var/lib/dkim +- name: Create directory /etc/amavis/dkim + file: path=/etc/amavis/dkim state=directory owner=root group=root mode=0755 when: "'out' in group_names" tags: - genkey + - dkim - name: Generate a private key for DKIM signing - command: genkeypair.sh dkim --privkey=/var/lib/dkim/20140703.fripost.org.key -t rsa -b 1024 + command: genkeypair.sh dkim --privkey=/etc/amavis/dkim/{{ item }}.pem -t rsa -b 2048 + with_items: "{{ (dkim_keys[inventory_hostname_short] | default({})).values() | map(attribute='s') | list }}" register: dkim changed_when: dkim.rc == 0 failed_when: dkim.rc > 1 when: "'out' in group_names" notify: - Restart Amavis - - Publish the public key to the DNS zone tags: - genkey + - dkim + +- name: Fetch DKIM keys + fetch_cmd: cmd="openssl pkey -pubout -outform PEM" + stdin=/etc/amavis/dkim/{{ item }}.pem + dest=certs/dkim/{{ item }}.pub + with_items: "{{ (dkim_keys[inventory_hostname_short] | default({})).values() | map(attribute='s') | list }}" + tags: + - genkey + - dkim - name: Configure Amavis template: src=etc/amavis/conf.d/50-user.j2 diff --git a/roles/amavis/templates/etc/amavis/conf.d/50-user.j2 b/roles/amavis/templates/etc/amavis/conf.d/50-user.j2 index 26bcdb9..f3ff416 100644 --- a/roles/amavis/templates/etc/amavis/conf.d/50-user.j2 +++ b/roles/amavis/templates/etc/amavis/conf.d/50-user.j2 @@ -32,12 +32,20 @@ undef $enable_dkim_signing; $enable_dkim_signing = 1; # Sign *all* outgoing mails with *our* key (yes, amavis complains, but this is # safe as we force our domain with the 'd' tag). -dkim_key(qr/./, '20140703', '/var/lib/dkim/20140703.'.$mydomain.'.key'); +{% for x,k in dkim_keys[inventory_hostname_short] | default({}) | dictsort() -%} +dkim_key({{ (x == "~") | ternary('qr/./', "'"+x+"'") }}, '{{ k.s }}', '/etc/amavis/dkim/{{ k.s }}.pem'); +{% endfor -%} @dkim_signature_options_bysender_maps = ( - { '.' => { d => $mydomain - , a => 'rsa-sha256' - , ttl => 21*24*3600 - , c => 'relaxed/simple' } } ); +{% for x,k in dkim_keys[inventory_hostname_short] | default({}) | dictsort() %} + { '{{ (x == "~") | ternary('.', x) }}' => { + d => '{{ k.d }}' + , a => 'rsa-sha256' + , ttl => 21*24*3600 + , c => 'relaxed/simple' } + }{% if not loop.last %}, +{% endif %} +{% endfor %} +); # Conform to RFC 4871 and don't sign Received: headers. $signed_header_fields{received} = 0; {% endif %} -- cgit v1.2.3