Nodemailer supports DKIM signing, which adds a digital signature to all outgoing messages. This signature is calculated and added as an additional header (or multiple headers, if using multiple keys).
One drawback of DKIM signing is that Nodemailer needs to cache the entire message before it can be sent. Normally, message output is streamed directly to SMTP without caching. For small messages, this difference is negligible, but for larger messages, Nodemailer offers the option to cache messages on disk instead of in memory. In this scenario, Nodemailer buffers the message in memory up to a certain size and then switches to disk caching. After the signature is calculated and sent to SMTP, the cached message is streamed from disk to SMTP.
In general, DKIM signing is fast and effective for most use cases.
DKIM signing can be configured at the transport level (where all messages are signed with the same keys) or at the message level (where different keys can be used for each message). If both are configured, the message-level DKIM settings will take precedence.
To set up DKIM signing, you need to provide a dkim
object with the following structure:
message-id:date:from:to
).Assumes a public key is available for 2017._domainkey.example.com. You can check if the key exists using the dig tool:
dig TXT 2017._domainkey.example.com
let transporter = nodemailer.createTransport({
host: "smtp.example.com",
port: 465,
secure: true,
dkim: {
domainName: "example.com",
keySelector: "2017",
privateKey: "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBg...",
},
});
Assumes public keys are available for 2017._domainkey.example.com and 2016._domainkey.example.com.
let transporter = nodemailer.createTransport({
host: "smtp.example.com",
port: 465,
secure: true,
dkim: {
keys: [
{
domainName: "example.com",
keySelector: "2017",
privateKey: "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBg...",
},
{
domainName: "example.com",
keySelector: "2016",
privateKey: "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBg...",
},
],
cacheDir: false,
},
});
This example shows how to sign a specific message without signing all messages by default.
let transporter = nodemailer.createTransport({
host: "smtp.example.com",
port: 465,
secure: true,
});
let message = {
from: "sender@example.com",
to: "recipient@example.com",
subject: "Message",
text: "I hope this message gets read!",
dkim: {
domainName: "example.com",
keySelector: "2017",
privateKey: "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBg...",
},
};
Messages larger than 100kB are cached to disk before signing.
let transporter = nodemailer.createTransport({
host: "smtp.example.com",
port: 465,
secure: true,
dkim: {
domainName: "example.com",
keySelector: "2017",
privateKey: "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBg...",
cacheDir: "/tmp",
cacheTreshold: 100 * 1024, // 100kB
},
});
Useful when sending mail through SES, which generates its own Message-ID and Date.
let transporter = nodemailer.createTransport({
host: "smtp.example.com",
port: 465,
secure: true,
dkim: {
domainName: "example.com",
keySelector: "2017",
privateKey: "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBg...",
skipFields: "message-id:date",
},
});