DKIM ("DomainKeys Identified Mail") support has been added in the latest nightly build of ApisCP and scheduled for inclusion in the next release, 3.2.20. DKIM is an often requested feature that provides cryptographic integrity to mail coming from an ApisCP server to protect against forgery.

DKIM overview

DKIM requires rspamd, which can work cooperatively with SpamAssassin or independently.

# Switch exclusively to rspamd
cpcmd scope:set mail.spam-filter rspamd
# or enable rspamd in piggyback mode
cpcmd scope:set mail.rspamd-piggyback true

Once rspamd is activated, hop onto nightly releases to deploy the new code. This can be done on a temporary basis.

cpcmd scope:set cp.update-policy edge-major
upcp

edge-major is a special update policy that keeps ApisCP on edge releases until the next full release, 3.2.20 in this case.

cpcmd scope:set mail.dkim-signing true
sleep 5
# Wait for ansible-playbook to complete
while pgrep -f ansible-playbook ; do sleep 1 ; done
# Enabling debug shows batch operation
env DEBUG=1 cpcmd dkim:roll DKIM2021

Keys may be rolled using dkim:roll($selector = null) to generate a new key for use with signing while retaining old keys. As a rule of thumb, rotate your keys every 6 months at most. Previously assigned keys may be expired using dkim:expire($selector).

# Move all domains over to DKIM record identified by NEWKEY._domainkey
env DEBUG=1 cpcmd dkim:roll NEWKEY
# Remove all DNS TXT records named "DKIM2021._domainkey"
env DEBUG=1 cpcmd dkim:expire DKIM2021

DMARC and SPF records are now extracted to config.ini, which can be easily set using cp.config Scope.

cpcmd scope:set cp.config mail default_spf "v=spf1 include:_spf.myhost.com a mx ~all"
# Set a passive DMARC record
cpcmd scope:set cp.config mail default_dmarc "v=DMARC1; p=none"
# Restart backend. Update configuration.
systemctl restart apiscp

Likewise these records may be retroactively applied to all sites using a boilerplate DNS script also to be featured in 3.2.20.

Create a file named update.php in /usr/local/apnscp with the following content

<?php
    include __DIR__ . '/lib/CLI/cmd.php';

    $handler = new \Opcenter\Dns\Bulk();
    $handler->remove(new \Opcenter\Dns\Record('_dummy_zone.com', [
        'name' => '_dmarc', 
        'rr' => 'TXT', 
        'parameter' => ''
    ]));
    
    $handler->add(new \Opcenter\Dns\Record('_dummy_zone.com', [
        'name' => '_dmarc', 
        'rr' => 'TXT', 
        'parameter' => MAIL_DEFAULT_DMARC
    ]));

Then run env DEBUG=1 apnscp_php update.php to remove all DNS records named _dmarc on all hosted domains. Bulk updates work independent of DNS provider.

Enjoy!

See also