-
-
Notifications
You must be signed in to change notification settings - Fork 103
DKIM Signing Example
This example shows how to enable native DKIM signing in go-mail.
go-mail v0.8.0 added native DKIM signing, so you no longer need the go-mail-middleware
package to DKIM-sign your messages. The signer key can be loaded straight from a PEM file
using the newly added mail.PrivKeyFromPEM
function.
Test on play.go.dev
package main
import (
"context"
"log"
"os"
"github.com/wneessen/go-mail"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// Load the DKIM private key from a PEM file and decode it into a crypto.Signer
pemBytes, err := os.ReadFile("dkim-private.pem")
if err != nil {
log.Fatalf("failed to read DKIM private key: %s", err)
}
signerKey, err := mail.PrivKeyFromPEM(pemBytes)
if err != nil {
log.Fatalf("failed to parse DKIM private key: %s", err)
}
message := mail.NewMsg()
if err = message.From("toni.tester@example.com"); err != nil {
log.Fatalf("failed to set FROM address: %s", err)
}
if err = message.To("tina.tester@example.com"); err != nil {
log.Fatalf("failed to set TO address: %s", err)
}
message.Subject("This is my first test mail with go-mail!")
message.SetBodyString(mail.TypeTextPlain, "This will be the content of the mail.")
// Initialize the DKIM signer for our domain and selector, then attach it to the message
dkimSigner := mail.NewDKIMSigner("example.com", "2026a", signerKey)
message.SetDKIM(dkimSigner)
// Deliver the mails via SMTP
client, err := mail.NewClient(os.Getenv("SMTP_HOST"),
mail.WithSMTPAuth(mail.SMTPAuthAutoDiscover), mail.WithTLSPortPolicy(mail.TLSMandatory),
mail.WithUsername(os.Getenv("SMTP_USER")), mail.WithPassword(os.Getenv("SMTP_PASS")),
)
if err != nil {
log.Fatalf("failed to create new mail delivery client: %s", err)
}
if err := client.DialAndSendWithContext(ctx, message); err != nil {
log.Fatalf("failed to deliver mail: %s", err)
}
log.Printf("Test mail successfully delivered.")
}Most of the code is explained in the Simple-Mailer-Example. Check out that page for detailed explanations.
The main differences to the Simple Mailer Example are, that we load our DKIM signer key from a PEM file in the first few lines of code. The mail.PrivKeyFromPEM function decodes a PEM-encoded private key into a crypto.Signer. It accepts both PKCS#1 (RSA PRIVATE KEY) and PKCS#8 (PRIVATE KEY) encodings and supports RSA and Ed25519 keys , which makes the returned signer ready to be passed directly to NewDKIMSigner .
Later, when our message is composed, we create a DKIM signer with mail.NewDKIMSigner, providing three parameters:
-
domain: the signing domain published in DNS (the
d=tag) -
selector: the selector used to locate the public key in DNS (the
s=tag) -
privKey: the
crypto.Signerwe loaded from the PEM file, used to produce the signature
Finally we attach the signer to the message via Msg.SetDKIM , which makes sure that, once the mail is rendered during the delivery process, the mail is DKIM signed before it is sent out.
If you send multiple messages through the same Client and don't want to configure DKIM on each Msg individually, you can register the signer once at the client level with mail.WithAlwaysDKIMSign. Note that a signer configured on the client always takes precedence over any DKIM configuration set on the individual Msg.
client, err := mail.NewClient(os.Getenv("SMTP_HOST"),
mail.WithSMTPAuth(mail.SMTPAuthAutoDiscover), mail.WithTLSPortPolicy(mail.TLSMandatory),
mail.WithUsername(os.Getenv("SMTP_USER")), mail.WithPassword(os.Getenv("SMTP_PASS")),
mail.WithAlwaysDKIMSign(dkimSigner),
)Socials: go-mail on Mastodon | #go-mail on Discord