Skip to content

Commit

Permalink
Adds DKIM support for multiple domains (huan#89)
Browse files Browse the repository at this point in the history
* generating a DKIM key for all virtualDomains

* including HOSTNAME in folder of domains for DKIM

* KeyTable, SigningTable, TrustedHosts for HOSTNAME and all virtualDomain

* Generate new DKIM data only if keys do not exist yet

* disabled opendkim.conf settings for single domain, added KeyTable,SigningTable,ExternalIgnoreList,InternalHosts

* Correct permissions of DKIM files regardless of prior creation

* Added test for multiple domains and DKIM. Ready for huan#88

* Updated README on DKIM for multiple domains

* Fixed indentation on entrypoint

* Fixed wrong indentation (style)

* Cleaner handling of multiple DKIM keys. No settings required. Renders huan#83 redundant

* Making sure we never insert the same config twice huan#89

* Forgot one last mention of SMF_DKIM_ALL

* Better tld naming for DKIM in README

Co-authored-by: Peeter N <[email protected]>

* DKIM test no longer changes working directory

Co-authored-by: Peeter N <[email protected]>

* More elegant generation of DKIM entries for HOSTNAME and virtual domains

* Correct switch to suppress grep complains when files miss

Co-authored-by: Peeter N <[email protected]>
  • Loading branch information
huan and petslane authored Feb 13, 2021
2 parents 1b7b051 + 4d96a5f commit 6f1cad7
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 16 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,14 @@ If you do not have a certificate and don't have the budget to afford one, you ca
DKIM
--------------------
SMF generates private/public keypair for `$SMF_DOMAIN` and stores them in `/var/db/dkim/`. Public key must be set as TXT record in DNS under `default._domainkey` name.
`default._domainkey` can be found in `/var/db/dkim/default.txt`.
SMF will generate private/public keypairs for `$SMF_DOMAIN` and for all source domains contained in `SMF_CONFIG`. All keys will be stored in `/var/db/dkim/<domain.tld>/`.
This will enable DKIM for multiple domains and test for their validity on SMF startup.
Public key must be set as TXT record in DNS under `default._domainkey` name. `default._domainkey` can be found in `/var/db/dkim/<domain.tld>/default.txt`.
It is highly advised to mount `/var/db/dkim/` folder to host, so generated keypair would not get lost/regenerated:
```
docker run -e SMF_CONFIG="$SMF_CONFIG" -p 25:25 -v $(pwd)/dkim:/var/db/dkim/ zixia/simple-mail-forwarder
```
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.3.2
1.4.0
67 changes: 56 additions & 11 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -190,21 +190,66 @@ function start_postfix {

postfix start

# migrating older single-domain DKIM (/var/db/dkim/default.*) to /var/db/dkim/$HOSTNAME/default.*
if [ -f /var/db/dkim/default.private ]; then
echo "Migrating ${HOSTNAME} keys to /var/db/dkim/$HOSTNAME/"
mkdir -p /var/db/dkim/$HOSTNAME
mv /var/db/dkim/default.* /var/db/dkim/$HOSTNAME
chmod 400 /var/db/dkim/$HOSTNAME/default.private
chown opendkim:opendkim /var/db/dkim/$HOSTNAME/default.private
fi

allDomains="$virtualDomains"
[[ $allDomains =~ $HOSTNAME ]] || {
allDomains="$allDomains $HOSTNAME"
}

for virtualDomain in $allDomains; do
# generates new keys only if they are not already present
if [ ! -f /var/db/dkim/${virtualDomain}/default.private ]; then
mkdir -p /var/db/dkim/${virtualDomain}
echo "OpenDKIM: Keys for ${virtualDomain} not found, generating..."
opendkim-genkey -b 2048 -d ${virtualDomain} -D /var/db/dkim/${virtualDomain} -s default -v
fi

chmod 400 /var/db/dkim/${virtualDomain}/default.private
chown opendkim:opendkim /var/db/dkim/${virtualDomain}/default.private

echo "Inserting ${virtualDomain} data to /etc/opendkim/{KeyTable, SigningTable, TrustedHosts}"

if ! grep -q -s "default._domainkey.${virtualDomain}" /etc/opendkim/KeyTable; then
echo "default._domainkey.${virtualDomain} ${virtualDomain}:default:/var/db/dkim/${virtualDomain}/default.private" >> /etc/opendkim/KeyTable
fi
if ! grep -q -s "default._domainkey.${virtualDomain}" /etc/opendkim/SigningTable; then
echo "${virtualDomain} default._domainkey.${virtualDomain}" >> /etc/opendkim/SigningTable
fi
if ! grep -q -s "${virtualDomain}" /etc/opendkim/TrustedHosts; then
echo "${virtualDomain}" >> /etc/opendkim/TrustedHosts
fi

# DKIM
if [ ! -f /var/db/dkim/default.private ]; then
mkdir -p /var/db/dkim
echo "OpenDKIM: Keys not found, generating..."
opendkim-genkey -b 2048 -d $HOSTNAME -D /var/db/dkim/ -s default -v
echo "OpenDKIM: this TXT record for ${virtualDomain} should be present:"
cat /var/db/dkim/${virtualDomain}/default.txt

done

chmod 400 /var/db/dkim/default.private
chown opendkim:opendkim /var/db/dkim/default.private
echo "Configuring DKIM key settings in /etc/opendkim/opendkim.conf"
sed -e '/KeyFile/ s/^#*/#/' -i /etc/opendkim/opendkim.conf
sed -e '/Selector/ s/^#*/#/' -i /etc/opendkim/opendkim.conf
sed -e '/Domain/ s/^#*/#/' -i /etc/opendkim/opendkim.conf

echo "OpenDKIM: Add TXT record to DNS:"
cat /var/db/dkim/default.txt
if ! grep -q -s "KeyTable" /etc/opendkim/opendkim.conf; then
echo "KeyTable /etc/opendkim/KeyTable" >> /etc/opendkim/opendkim.conf;
fi

sed -n -e '/^Domain\s/!p' -e '$aDomain '$HOSTNAME -i /etc/opendkim/opendkim.conf
if ! grep -q -s "SigningTable" /etc/opendkim/opendkim.conf; then
echo "SigningTable /etc/opendkim/SigningTable" >> /etc/opendkim/opendkim.conf;
fi
if ! grep -q -s "ExternalIgnoreList" /etc/opendkim/opendkim.conf; then
echo "ExternalIgnoreList /etc/opendkim/TrustedHosts" >> /etc/opendkim/opendkim.conf;
fi
if ! grep -q -s "InternalHosts" /etc/opendkim/opendkim.conf; then
echo "InternalHosts /etc/opendkim/TrustedHosts" >> /etc/opendkim/opendkim.conf
fi

}

#
Expand Down
6 changes: 4 additions & 2 deletions test/simple-mail-forwarder.bats
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,9 @@
if [[ "$SKIP_TEST" == *"DKIM"* ]]; then
skip "This test will fail on docker build workflow"
fi
opendkim-testkey -d $SMF_DOMAIN -s default -vvv

for domain in /var/db/dkim/*/ ; do
echo "Validating DKIM for ${domain:13:-1}"
opendkim-testkey -d ${domain:13:-1} -s default -vvv
done
[ $? -eq 0 ]
}

0 comments on commit 6f1cad7

Please sign in to comment.