§2027-10-02
WildDuck uses ZoneMTA as its outbound mail relay, and ZoneMTA is responsible for handling the DKIM (DomainKeys Identified Mail) signing of the outgoing emails.
Here's a breakdown of the process:
-
WildDuck handles email generation and stores the message in the database.
-
ZoneMTA picks up the outbound email from WildDuck.
-
DKIM Signing: ZoneMTA, being responsible for email delivery, uses the DKIM key to sign outgoing emails. The DKIM signature is applied to ensure the authenticity and integrity of the message. ZoneMTA integrates with different signing modules, including DKIM, to sign the message headers and body before sending it out to the recipient's mail server.
-
SPF and DMARC: In addition to DKIM, ZoneMTA may also ensure proper SPF (Sender Policy Framework) and DMARC (Domain-based Message Authentication, Reporting, and Conformance) compliance, but this would require the proper setup in your DNS records and ZoneMTA configuration.
-
So, in essence, ZoneMTA is responsible for encoding the DKIM signature for outbound emails. WildDuck manages the email itself, while ZoneMTA handles the delivery and DKIM signing.
-
it was installed by
09_install_zone_mta.sh
#! /bin/bash
OURNAME=09_install_zone_mta.sh
# ${ORANGE} is Orange color
echo -e "\n-- Executing ${ORANGE}${OURNAME}${NC} subscript --"
#### ZoneMTA ####
# $ grep -r 'SYSTEMCTL_PATH=' . --> to find where it was defined
# It is defined in 06_install_enable_services.sh byt the following line
# SYSTEMCTL_PATH=`command -v systemctl`
# ./06_install_enable_services.sh:SYSTEMCTL_PATH=`command -v systemctl`
# clear previous install
if [ -f "/etc/systemd/system/zone-mta.service" ]
then
# grep -r SYSTEMCTL_PATH . --> to find out where it is defined
$SYSTEMCTL_PATH stop zone-mta || true
# ||: This operator is a logical OR. It means "execute the next command only if the previous command fails." I
# true: This is a command that always succeeds (returns an exit status of 0)
# even it fails to stop, keeps on going
$SYSTEMCTL_PATH disable zone-mta || true
rm -rf /etc/systemd/system/zone-mta.service
fi
rm -rf /var/opt/zone-mta.git
rm -rf /var/opt/zonemta-wildduck.git
rm -rf /opt/zone-mta
rm -rf /etc/zone-mta
# fresh install
cd /var/opt
git clone --bare https://github.com/zone-eu/zone-mta-template.git zone-mta.git
git clone --bare https://github.com/nodemailer/zonemta-wildduck.git
# create update hooks so we can later deploy to this location
# hook_script defined in 00_install_global_functions_variables.sh
echo "#!/bin/bash
git --git-dir=/var/opt/zonemta-wildduck.git --work-tree=/opt/zone-mta/plugins/wildduck checkout "\$3" -f
cd /opt/zone-mta/plugins/wildduck
rm -rf package-lock.json
npm install --production --no-optional --no-package-lock --no-audit --ignore-scripts --no-shrinkwrap --progress=false
sudo $SYSTEMCTL_PATH restart zone-mta || echo \"Failed restarting service\"" > "/var/opt/zonemta-wildduck.git/hooks/update"
chmod +x "/var/opt/zonemta-wildduck.git/hooks/update"
# allow deploy user to restart zone-mta service
echo "deploy ALL = (root) NOPASSWD: $SYSTEMCTL_PATH restart zone-mta" >> /etc/sudoers.d/zone-mta
# checkout files from git to working directory
mkdir -p /opt/zone-mta
git --git-dir=/var/opt/zone-mta.git --work-tree=/opt/zone-mta checkout "$ZONEMTA_COMMIT"
mkdir -p /opt/zone-mta/plugins/wildduck
git --git-dir=/var/opt/zonemta-wildduck.git --work-tree=/opt/zone-mta/plugins/wildduck checkout "$WILDDUCK_ZONEMTA_COMMIT"
cp -r /opt/zone-mta/config /etc/zone-mta
sed -i -e 's/port=2525/port=587/g;s/host="127.0.0.1"/host="0.0.0.0"/g;s/authentication=false/authentication=true/g' /etc/zone-mta/interfaces/feeder.toml
rm -rf /etc/zone-mta/plugins/dkim.toml
echo '# @include "/etc/wildduck/dbs.toml"' > /etc/zone-mta/dbs-production.toml
echo 'user="wildduck"
echo "[[default]]
address=\"0.0.0.0\"
name=\"$HOSTNAME\"" > /etc/zone-mta/pools.toml
echo "[\"modules/zonemta-loop-breaker\"]
enabled=\"sender\"
secret=\"$ZONEMTA_SECRET\"
algo=\"md5\"" > /etc/zone-mta/plugins/loop-breaker.toml
echo "[wildduck]
enabled=[\"receiver\", \"sender\"]
# which interfaces this plugin applies to
interfaces=[\"feeder\"]
# optional hostname to be used in headers
# defaults to os.hostname()
hostname=\"$HOSTNAME\"
# SRS settings for forwarded emails
[wildduck.srs]
# Handle rewriting of forwarded emails
enabled=true
# SRS secret value. Must be the same as in the MX side
secret=\"$SRS_SECRET\"
# SRS domain, must resolve back to MX
rewriteDomain=\"$MAILDOMAIN\"
[wildduck.dkim]
# share config with WildDuck installation
# @include \"/etc/wildduck/dkim.toml\"
" > /etc/zone-mta/plugins/wildduck.toml
cd /opt/zone-mta/keys
# Many registrar limits dns TXT fields to 255 char. 1024bit is almost too long:-\
openssl genrsa -out "$MAILDOMAIN-dkim.pem" 1024
chmod 400 "$MAILDOMAIN-dkim.pem"
openssl rsa -in "$MAILDOMAIN-dkim.pem" -out "$MAILDOMAIN-dkim.cert" -pubout
DKIM_DNS="v=DKIM1;k=rsa;p=$(grep -v -e '^-' $MAILDOMAIN-dkim.cert | tr -d "\n")"
DKIM_JSON=`DOMAIN="$MAILDOMAIN" SELECTOR="$DKIM_SELECTOR" node -e 'console.log(JSON.stringify({
domain: process.env.DOMAIN,
selector: process.env.SELECTOR,
description: "Default DKIM key for "+process.env.DOMAIN,
privateKey: fs.readFileSync("/opt/zone-mta/keys/"+process.env.DOMAIN+"-dkim.pem", "UTF-8")
}))'`
cd /opt/zone-mta
npm install --production --no-optional --no-package-lock --no-audit --ignore-scripts --no-shrinkwrap --unsafe-perm
cd /opt/zone-mta/plugins/wildduck
npm install --production --no-optional --no-package-lock --no-audit --ignore-scripts --no-shrinkwrap --unsafe-perm
chown -R deploy:deploy /var/opt/zone-mta.git
chown -R deploy:deploy /var/opt/zonemta-wildduck.git
chown -R deploy:deploy /opt/zone-mta
chown -R wildduck:wildduck /etc/zone-mta
# Ensure required files and permissions
echo "d /opt/zone-mta 0755 deploy deploy
d /etc/zone-mta 0755 wildduck wildduck" > /etc/tmpfiles.d/zone-mta.conf
log_script "zone-mta"
echo '[Unit]
Description=Zone Mail Transport Agent
Conflicts=sendmail.service exim.service postfix.service
After=mongod.service redis.service
[Service]
Environment="NODE_ENV=production"
WorkingDirectory=/opt/zone-mta
ExecStart=/usr/bin/node index.js --config="/etc/zone-mta/zonemta.toml"
ExecReload=/bin/kill -HUP $MAINPID
Type=simple
Restart=always
SyslogIdentifier=zone-mta
[Install]
WantedBy=multi-user.target' > /etc/systemd/system/zone-mta.service
$SYSTEMCTL_PATH enable zone-mta.service
$ sudo systemctl cat zone-mta.service
# /etc/systemd/system/zone-mta.service
[Unit]
Description=Zone Mail Transport Agent
Conflicts=sendmail.service exim.service postfix.service
After=mongod.service redis.service
[Service]
Environment="NODE_ENV=production"
WorkingDirectory=/opt/zone-mta
ExecStart=/usr/bin/node index.js --config="/etc/zone-mta/zonemta.toml"
ExecReload=/bin/kill -HUP $MAINPID
Type=simple
Restart=always
SyslogIdentifier=zone-mta
[Install]
WantedBy=multi-user.target
$ cat /etc/zone-mta/zonemta.toml
user="wildduck"
group="wildduck"
# This is the main config file
name="ZoneMTA"
# Process identifier
ident="zone-mta"
# Run as the following user. Only use this if the application starts up as root
#user="zonemta"
#group="zonemta"
[log]
# Logging options
# @include "log.toml"
[dbs]
# MongoDB and Redis connection options
@include "dbs-{env}.toml"
[queue]
# @include "queue.toml"
[dns]
# @include "dns.toml"
[api]
port=12080
[smtpInterfaces]
# @include "interfaces/*.toml"
[plugins]
# @include "plugins/*.toml"
[pools]
# @include "pools.toml"
[zones]
# @include "zones/*.toml"
[domainConfig]
# @include "domains.toml"
alexlai@mail:/etc/zone-mta$ cat dbs-production.toml
# @include "/etc/wildduck/dbs.toml"
@include "/etc/wildduck/dbs.toml"
$ cat /etc/wildduck/dbs.toml
# mongodb connection string for the main database
# mongo="mongodb://127.0.0.1:27017/wildduck"
mongo="mongodb://siteRootAdmin:b23258585@redisMongo03.yushei.com.tw:27017,redisMongo04.yushei.com.tw:27017,redisMongo05.yushei.com.tw:27017/YuSheiWildduck?authSource=admin&replicaSet=ys20220318"
# redis connection string to connect to a single master (see below for Sentinel example)
#redis="redis://127.0.0.1:6379/3"
# WildDuck allows using different kind of data in different databases
# If you do not provide a database config value, then main database connection
# is used for everything
# You can either use a database name (uses shared connection) or a configutaion
# url (creates a separate connection) for each databases
# Optional database name or connection url for GridFS if you do not want to
# use the main db for storing attachments. Useful if you want
# to use a different mount folder or storage engine
#gridfs="wildduck"
# Optional database name or connection url for users collection if you do not want to
# use the main db for storing user/address data. Useful if you want
# to use a different mount folder or storage engine
#users="wildduck"
# Optional database name or connection url for ZoneMTA queue database. This is
# used to push outbound emails to the sending queue
sender="zone-mta"
#queued="mail"
[redis]
host="127.0.0.1"
port=6379
db=3
## Connect to Redis Sentinel instead of single master
# [redis]
# name="mymaster"
# password=""
# db=3
# [[redis.sentinels]]
# host="54.36.85.113"
# port=26379
# [[redis.sentinels]]
# host="54.36.85.114"
# port=26379
# [[redis.sentinels]]
# host="54.36.85.115"
# port=26379
And sudo systemctl restart zonemta.service
error message
░ The job identifier is 9325.
Oct 28 11:02:10 mail zone-mta[7130]: [/etc/zone-mta/zonemta.toml] /etc/zone-mta/zonemta.toml: /etc/zone-mta/dbs-production.toml: Expected "#", "'", "[", "\"", "\n", "\r", [ \t], [A-Za-z0-9_\-] or end of input but "@" found.
Oct 28 11:02:10 mail systemd[1]: zone-mta.service: Main process exited, code=exited, status=1/FAILURE