[pmg-devel] [PATCH pmg-api/pmg-gui/pmg-docs v3] add initial DKIM-Signing Support

Stoiko Ivanov s.ivanov at proxmox.com
Fri Oct 18 16:53:47 CEST 2019

This patchset adds initial support for signing outbound e-mails with DKIM.

Changes v2 -> v3:
* fixed the points where I oversaw Dominik's feedback on v1 (sorry!)
* incorporated feedback on v2 - Thanks!
* added initial documentation patch
* tested it on a freshly setup container as well..

Changes v1 -> v2:
* mostly incorporated Dominik's feedback
* instead of saving the config-options affecting pmg-smtp-filter inside
  the PMG::Config object, the code now writes a 'config-file' into /run when
  pmg-smtp-filter starts, or when the relevant settings change. This makes for
  a simpler and cleaner handling of config-updates. It also removed the need
  for the original patch 3 (reloading the config in all cluster-synchronization
* PMG::DKIMSign::sign_entity got added giving all points where mail should
  get signed a single method to call
* the key-size restrictions were changed (only a lower bound of 1024 is now
  enforced (since I just found out that you can very well create RSA-keys
  with e.g. 1077 bits...)
* synchronization of directories in a cluster was changed to use `rsync -aq`
  instead of looping over all files and symlinks inside a directory.
  This makes for a change of semantics, but I think the regression risk
  is rather small (it would affect users who have put a large directory
  hierarchy below '/etc/pmg/templates' (and even then they already sync
  it across nodes -now it gets additionally copied from
  '/etc/pmg/master/templates' to '/etc/pmg/templates'
* the patch for proxmox-widget-toolkit was dropped since it was already

Design choices:
While initially planning to implement this by rendering the config for one
of the available dkim-signing milters and hooking it into the outbound postfix
instance via the templating system (master.cf.in) a few reasons changed my mind
in favor of using perl's Mail::DKIM::Signer inside pmg-smtp-filter instead:
* both milter-options considered had a few drawbacks for our use-case
  - opendkim seems a bit behind on the latest changes to DKIM (2 new RFCs w.r.t.
    DKIM have come out recently [0,1] and it seems the debian maintainer might
    not have the time/energy to keep on maintaining it [2]
  - dkimpy-milter (a rather recent reimplementation of opendkim's feature set)
    is still lacking 2-3 crucial features (SigningTable/KeyTable support),
    which, while not needed for the current feature set, might become a burden
    further down the road. Also the logging and configuration were a bit terse
    (even for my taste) - The upside of dkimpy-milter is that it implements
    rfc8463 (ed25519+sha256 - making for much shorter public-keys), something
    that I only found in rspamd otherwise
* adding yet another moving part and running service also has its drawback

* OTOH Mail::DKIM integrates quite straight-forward into pmg-smtp-filter
  (by using SpamAssassin most of it's dependencies are already loaded into
  memory anyways).
* Additionally inside pmg-smtp-filter we have quite good knowledge of a mail
  (e.g. knowing if it arrived on the internal or external port, or a direct
  view of all domains for which the PMG is relaying).
* Last but not least Mail::DKIM seems quite active (it's last release is
  on 08.10.2019 :)

The current implementation should give most users enough for their needs:
* It can either sign all mails sent by users in a certain list of domains
  (/etc/dkim/domains) with a fall-back to the RelayDomains (the one PMG
  receives mail for seem like a good default choice for the domains PMG
  can sign mails for)
* Alternatively it can sign all incoming mails (with the sender's domain taken
  for the signature's d= flag (the domain in which a verifier looks for the
  public key to verify the signature)
* The user can create a new selector (meaning the selector name, which is part
  of the DNS-record and also inside the signature header, and the private key
  used for signing), which is then used to sign all mails. (when generating
  a new private key all domains signed by it need to create/update the fitting
  DNS-record anyways).
* the signature algorithm is fixed to rsa-sha256 (see [1], and sadly Mail::DKIM
  has no support yet for ed25519+sha256).
* the key-size can be (1024|2048|4096) bits (the 1024 is still there for
  compatibility with DNS-providers not having support for TXT records >255

The first 2 patches address also #2371, since I needed to reload pmg-smtp-filter
for config changes anyways.

I did some preliminary testing - the generated signatures get verified by
opendkim and rspamd.

Thanks to Dominik for supporting me with the GUI-part and for the very
thorough code-review of v1 and v2 and the valuable suggestions!

Feedback appreciated!

[0] https://tools.ietf.org/html/rfc8301
[1] https://tools.ietf.org/html/rfc8463
[2] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=900774;msg=5

Stoiko Ivanov (11):
  refactor reload_rule_db
  fix #2371: reload pmg-smtp-filter on config change
  add DKIM options to PMG::Config
  add PMG::DKIMSign module
  DKIM sign outbound mail if configured
  refactor API2::Domains for reuse in DKIMSign
  add API2/DKIMSignDomains endpoints
  add DKIM API paths
  pmgconfig: add dkim commands
  add /etc/pmg/dkim to cluster-sync
  pmgproxy: add proxmox-widget-toolkit css path

 debian/dirs                     |   1 +
 src/Makefile                    |   3 +
 src/PMG/API2/Config.pm          |   7 +
 src/PMG/API2/DKIMSign.pm        | 127 +++++++++++
 src/PMG/API2/DKIMSignDomains.pm |  19 ++
 src/PMG/API2/Domains.pm         | 359 +++++++++++++++++---------------
 src/PMG/CLI/pmgconfig.pm        |   7 +
 src/PMG/Cluster.pm              |  41 ++--
 src/PMG/Config.pm               |  94 +++++++++
 src/PMG/DBTools.pm              |  11 +-
 src/PMG/DKIMSign.pm             | 177 ++++++++++++++++
 src/PMG/RuleDB/Accept.pm        |  14 +-
 src/PMG/RuleDB/BCC.pm           |  11 +
 src/PMG/Service/pmgproxy.pm     |   2 +
 src/PMG/Utils.pm                |  13 ++
 src/bin/pmg-smtp-filter         |   8 +
 16 files changed, 688 insertions(+), 206 deletions(-)
 create mode 100644 src/PMG/API2/DKIMSign.pm
 create mode 100644 src/PMG/API2/DKIMSignDomains.pm
 create mode 100644 src/PMG/DKIMSign.pm

Stoiko Ivanov (11):
  refactor RelayDomains:
  MailProxyConfiguration.js: whitespace cleanup
  Add DKIM Tab to MailProxy configuration

 js/DKIMSettings.js           | 200 +++++++++++++++++++++++++++++++++++
 js/MailProxyConfiguration.js |  13 ++-
 js/MailProxyDKIMPanel.js     |  43 ++++++++
 js/Makefile                  |   2 +
 js/RelayDomains.js           |  27 ++---
 pmg-index.html.tt            |   1 +
 6 files changed, 270 insertions(+), 16 deletions(-)
 create mode 100644 js/DKIMSettings.js
 create mode 100644 js/MailProxyDKIMPanel.js

Stoiko Ivanov (1):
  Add DKIM documentation

 asciidoc/asciidoc-pmg.conf |  1 +
 gen-pmg.conf.5-opts.pl     |  6 ++++
 pmgconfig.adoc             | 56 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 63 insertions(+)


More information about the pmg-devel mailing list