OneLinersCommand workbench
Guides
Security / Networking & DNS

Configure DKIM signing in Exim and rotate keys

Generate a protected key, publish and verify DNS, sign only owned outbound domains, test canonicalization and alignment, monitor failures, and rehearse rotation.

70 min8 stepsChanges system stateRevision 2
Save or explore
Save to collectionCreate a collection in the sidebar first.
0 of 8 steps completed
Goal

Produce verifiable DKIM signatures for authorized outbound mail without signing relayed spoofed domains.

Supported environments
  • Exim 4.98+
Prerequisites
  • Authoritative DNS and stable identity Control forward and reverse DNS, choose the canonical mail hostname and domains, and verify the host is not behind an outbound SMTP-blocking network.hostname -f; getent ahosts $(hostname -f); dig +short -x {{publicIp}}
  • Recovery and queue safety Keep console access, back up active configuration, and record queue state before changing routing, authentication, filters, or mailbox delivery.
  • Abuse and deliverability plan Define relay boundaries, account owners, rate limits, bounce handling, postmaster address, monitoring, and how compromised credentials will be revoked.
Operating boundary

OneLiners never runs these steps or stores secrets. Review placeholders, versions, current state, and change-control requirements before using a command.

Full guide

What you will build

System
  • A production Exim implementation of “Configure DKIM signing in Exim and rotate keys” with explicit SMTP/IMAP boundaries, identity, durable state and observable delivery evidence.
  • A read-only baseline, staged candidate and end-to-end canary covering DNS, TLS, authentication, recipient or route policy, queue/mailbox state and logs.
  • A security and rollback procedure that avoids open relay, backscatter, plaintext credentials, world-readable keys/mail and unreviewed bulk queue actions.
Observable outcome
  • Produce verifiable DKIM signatures for authorized outbound mail without signing relayed spoofed domains. The intended success path is visible in native status, protocol transcript, headers or mailbox evidence.
  • Expected unauthorized relay, unknown-recipient, wrong-sender, invalid-authentication or wrong-certificate tests fail at the declared boundary without harming unrelated mail.

Architecture

How the parts fit together

Outbound mail passes through a signing or filtering boundary that evaluates content and adds a DKIM signature using a selector-specific private key. DNS publishes the matching public key and authentication policy. Key files are readable only by the signer, allowed-sender rules prevent unauthorized signing, and headers/logs expose the decision. Rotation overlaps old and new selectors until previously delivered mail and DNS caches no longer require the old public key.

Content/signing filterEvaluates outbound messages and writes authentication headers.
Selector private keySigns mail and remains readable only by the signing service.
DNS public keyAllows receivers to verify the selector/domain signature.
Policy and rotationLimit eligible senders and replace keys without a verification gap.
  1. Inventory hostname/DNS, listeners, certificates, identities, recipient/relay maps, queue/mailbox state, logs and a recoverable configuration/data baseline.
  2. Prepare the dkim filter candidate with official Exim syntax, protected secrets and one explicit service/data boundary at a time.
  3. Run native configuration validation and immediate read-only checkpoint before reload or acceptance of new messages.
  4. Use controlled local and external canaries plus an expected-denial test, preserve message identifiers/headers, and retain the prior configuration for rollback.

Assumptions

  • The public mail hostname, forward/reverse DNS ownership, supported package version and responsibility for ports 25/587/993 are known.
  • A maintenance or canary window, console recovery and current protected backup of configuration, keys, identity mappings and relevant mailbox/queue data exist.
  • Test sender and recipient addresses are owned by the operator; no unsolicited or third-party traffic is generated during verification.
  • Secrets and private keys are delivered outside shell history and have narrowly defined service ownership and rotation plans.

Key concepts

envelope identity
SMTP sender and recipient used for routing, delivery status and SPF; it is distinct from visible message headers.
open relay
An MTA that accepts unauthorized third-party sender-to-recipient forwarding, enabling abuse and reputation damage.
backscatter
A later non-delivery report sent to a forged sender because an invalid recipient was accepted instead of rejected during SMTP.
alignment
DMARC relationship between visible From domain and authenticated SPF or DKIM domain.
Maildir
A mailbox format storing messages as individual files in cur/new/tmp directories with strict ownership.

Before you copy

Values used in this guide

{{allowedSender}}

Operator-reviewed value used by this tutorial for allowedSender; derive it from the target environment and never from untrusted request data.

Example: billing@example.com
{{authoritativeNs}}

Operator-reviewed value used by this tutorial for authoritativeNs; derive it from the target environment and never from untrusted request data.

Example: ns1.example.net
{{canaryAllowed}}

Operator-reviewed value used by this tutorial for canaryAllowed; derive it from the target environment and never from untrusted request data.

Example: allowed-canary@example.com
{{canaryDenied}}

Operator-reviewed value used by this tutorial for canaryDenied; derive it from the target environment and never from untrusted request data.

Example: denied-canary@other.example
{{domain}}

Fully qualified public or internal hostname served by this configuration.

Example: example.com
{{nextSelector}}

Operator-reviewed value used by this tutorial for nextSelector; derive it from the target environment and never from untrusted request data.

Example: mail2027
{{receivedMessageFile}}

Operator-reviewed value used by this tutorial for receivedMessageFile; derive it from the target environment and never from untrusted request data.

Example: /srv/mail-fixtures/received-message.eml
{{rotateBy}}

Operator-reviewed value used by this tutorial for rotateBy; derive it from the target environment and never from untrusted request data.

Example: 2026-10-25
{{selector}}

Operator-reviewed value used by this tutorial for selector; derive it from the target environment and never from untrusted request data.

Example: mail2026
{{testRecipient}}

Operator-reviewed value used by this tutorial for testRecipient; derive it from the target environment and never from untrusted request data.

Example: owned-test@example.net

Security and production boundaries

  • Never weaken relay/recipient checks, publish private DKIM/TLS keys, enable plaintext authentication, or expose web/IMAP administration broadly to make a test pass.
  • Mail content, credentials, queues, logs and backups contain personal or confidential data; restrict, encrypt, minimize and retain them under an explicit policy.
  • Use dedicated service identities and root-readable credential maps; verify logs and configuration output are redacted before sharing.

Stop before continuing if

  • Stop if a test permits unauthorized relay, accepts unknown recipients for later bounce, sends credentials without verified TLS, or exposes private keys/mailbox files.
  • Do not continue when hostname/PTR ownership, package/config version, recipient map, route, queue, mailbox ownership or rollback backup is ambiguous.
  • Immediately quarantine the candidate when unrelated mail is rerouted, deleted, multiply delivered, signed by the wrong domain, or inaccessible after reload.
01

instruction

Choose selector, scope, and rotation dates

read-only

Use a date-based selector, list signing domains, key owner, activation, overlap, revocation, and next-review dates.

Why this step matters

Choose selector, scope, and rotation dates is a separate checkpoint because it establishes one auditable part of produce verifiable dkim signatures for authorized outbound mail without signing relayed spoofed domains. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.

What to understand

Use a date-based selector, list signing domains, key owner, activation, overlap, revocation, and next-review dates. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.

Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.

Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.

System changes

  • This step may affect the files, packages, identities, services, or runtime policy named in “Choose selector, scope, and rotation dates”. The scope must remain limited to the selected application and supported host.

Syntax explained

printf
Invokes the principal tool or configuration operation for “Choose selector, scope, and rotation dates”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
{{…}}
Marks an operator-supplied value. Replace every placeholder deliberately; do not paste untrusted text or leave braces in the production command.
Command
Fill variables0/3 ready

Values stay on this page and are never sent or saved.

printf 'selector=%s domain=%s activated=%s rotate_by=%s\n' '{{selector}}' '{{domain}}' '2026-07-25' '{{rotateBy}}'
Example output / evidence
Selector and lifecycle record are explicit.

Checkpoint: Checkpoint: Choose selector, scope, and rotation dates

Continue whenSelector and lifecycle record are explicit. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.

Stop whenStop before the next step when printf reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.

If this step fails

The command for “Choose selector, scope, and rotation dates” fails, produces no useful evidence, or the expected service/configuration state is absent.

Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.

Safe checks
  • command -v printf 2>/dev/null || true
  • systemctl --failed --no-pager 2>/dev/null || true
  • journalctl -p warning -n 50 --no-pager 2>/dev/null || true

ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.

Security notes

  • Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.

Alternatives

  • When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.

Stop conditions

  • Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
02

command

Generate a protected RSA or supported signing key

caution

Generate with an approved size, store below Exim configuration, and make the private key readable only by root and the Exim group.

Why this step matters

Generate a protected RSA or supported signing key is a separate checkpoint because it establishes one auditable part of produce verifiable dkim signatures for authorized outbound mail without signing relayed spoofed domains. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.

What to understand

Generate with an approved size, store below Exim configuration, and make the private key readable only by root and the Exim group. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.

Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.

Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.

System changes

  • This step may affect the files, packages, identities, services, or runtime policy named in “Generate a protected RSA or supported signing key”. The scope must remain limited to the selected application and supported host.

Syntax explained

install
Invokes the principal tool or configuration operation for “Generate a protected RSA or supported signing key”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
{{…}}
Marks an operator-supplied value. Replace every placeholder deliberately; do not paste untrusted text or leave braces in the production command.
Command
Fill variables0/2 ready

Values stay on this page and are never sent or saved.

sudo install -d -o root -g Debian-exim -m 0750 /etc/exim4/dkim; sudo openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out /etc/exim4/dkim/{{domain}}.{{selector}}.key; sudo chown root:Debian-exim /etc/exim4/dkim/{{domain}}.{{selector}}.key; sudo chmod 0640 /etc/exim4/dkim/{{domain}}.{{selector}}.key
Example output / evidence
A protected 2048-bit private key exists.

Checkpoint: Checkpoint: Generate a protected RSA or supported signing key

Continue whenA protected 2048-bit private key exists. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.

Stop whenStop before the next step when install reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.

If this step fails

The command for “Generate a protected RSA or supported signing key” fails, produces no useful evidence, or the expected service/configuration state is absent.

Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.

Safe checks
  • command -v install 2>/dev/null || true
  • systemctl --failed --no-pager 2>/dev/null || true
  • journalctl -p warning -n 50 --no-pager 2>/dev/null || true

ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.

Security notes

  • Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.

Alternatives

  • When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.

Stop conditions

  • Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
03

instruction

Derive and publish the DKIM DNS record

read-only

Extract the public key, remove PEM armor and whitespace, publish v=DKIM1; k=rsa; p= at selector._domainkey, and respect DNS change control.

Why this step matters

Derive and publish the DKIM DNS record is a separate checkpoint because it establishes one auditable part of produce verifiable dkim signatures for authorized outbound mail without signing relayed spoofed domains. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.

What to understand

Extract the public key, remove PEM armor and whitespace, publish v=DKIM1; k=rsa; p= at selector._domainkey, and respect DNS change control. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.

Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.

Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.

System changes

  • This step may affect the files, packages, identities, services, or runtime policy named in “Derive and publish the DKIM DNS record”. The scope must remain limited to the selected application and supported host.

Syntax explained

openssl
Invokes the principal tool or configuration operation for “Derive and publish the DKIM DNS record”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
{{…}}
Marks an operator-supplied value. Replace every placeholder deliberately; do not paste untrusted text or leave braces in the production command.
|
Passes standard output to the next read-only inspection stage; review each stage separately if the combined result is surprising.
Command
Fill variables0/2 ready

Values stay on this page and are never sent or saved.

openssl pkey -in /etc/exim4/dkim/{{domain}}.{{selector}}.key -pubout -outform PEM | sed '1d;$d' | tr -d '\n'; echo
Example output / evidence
A single-line public key is ready for authoritative DNS.

Checkpoint: Checkpoint: Derive and publish the DKIM DNS record

Continue whenA single-line public key is ready for authoritative DNS. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.

Stop whenStop before the next step when openssl reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.

If this step fails

The command for “Derive and publish the DKIM DNS record” fails, produces no useful evidence, or the expected service/configuration state is absent.

Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.

Safe checks
  • command -v openssl 2>/dev/null || true
  • systemctl --failed --no-pager 2>/dev/null || true
  • journalctl -p warning -n 50 --no-pager 2>/dev/null || true

ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.

Security notes

  • Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.

Alternatives

  • When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.

Stop conditions

  • Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
04

verification

Verify authoritative and recursive DNS

read-only

Wait for the record to appear from authoritative servers and independent resolvers before enabling signing.

Why this step matters

Verify authoritative and recursive DNS is a separate checkpoint because it establishes one auditable part of produce verifiable dkim signatures for authorized outbound mail without signing relayed spoofed domains. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.

What to understand

Wait for the record to appear from authoritative servers and independent resolvers before enabling signing. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.

Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.

Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.

System changes

  • This step may affect the files, packages, identities, services, or runtime policy named in “Verify authoritative and recursive DNS”. The scope must remain limited to the selected application and supported host.

Syntax explained

dig
Invokes the principal tool or configuration operation for “Verify authoritative and recursive DNS”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
{{…}}
Marks an operator-supplied value. Replace every placeholder deliberately; do not paste untrusted text or leave braces in the production command.
Command
Fill variables0/3 ready

Values stay on this page and are never sent or saved.

dig +short TXT {{selector}}._domainkey.{{domain}} @{{authoritativeNs}}; dig +short TXT {{selector}}._domainkey.{{domain}} @1.1.1.1
Example output / evidence
Both paths return the same complete DKIM record.

Checkpoint: Checkpoint: Verify authoritative and recursive DNS

Continue whenBoth paths return the same complete DKIM record. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.

Stop whenStop before the next step when dig reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.

If this step fails

The command for “Verify authoritative and recursive DNS” fails, produces no useful evidence, or the expected service/configuration state is absent.

Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.

Safe checks
  • command -v dig 2>/dev/null || true
  • systemctl --failed --no-pager 2>/dev/null || true
  • journalctl -p warning -n 50 --no-pager 2>/dev/null || true

ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.

Security notes

  • Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.

Alternatives

  • When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.

Stop conditions

  • Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
05

config

Configure Exim DKIM transport settings

caution

Set dkim_domain only for authenticated/local senders in owned domains, dkim_selector, dkim_private_key, canonicalization, and strictness on the outbound SMTP transport.

Why this step matters

Configure Exim DKIM transport settings is a separate checkpoint because it establishes one auditable part of produce verifiable dkim signatures for authorized outbound mail without signing relayed spoofed domains. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.

What to understand

Set dkim_domain only for authenticated/local senders in owned domains, dkim_selector, dkim_private_key, canonicalization, and strictness on the outbound SMTP transport. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.

Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.

Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.

System changes

  • This step may affect the files, packages, identities, services, or runtime policy named in “Configure Exim DKIM transport settings”. The scope must remain limited to the selected application and supported host.

Syntax explained

sudoedit
Invokes the principal tool or configuration operation for “Configure Exim DKIM transport settings”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
/etc/exim4/exim4.conf.localmacros
Is the persistent configuration boundary changed by this step. Keep an attributable backup and validate the consumer before reload.
File /etc/exim4/exim4.conf.localmacros
Configuration
sudoedit /etc/exim4/exim4.conf.localmacros; sudo update-exim4.conf; sudo exim -bP transport remote_smtp
Example output / evidence
The transport resolves the domain, selector, protected key, and signing policy.

Checkpoint: Checkpoint: Configure Exim DKIM transport settings

Continue whenThe transport resolves the domain, selector, protected key, and signing policy. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.

Stop whenStop before the next step when sudoedit reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.

If this step fails

The command for “Configure Exim DKIM transport settings” fails, produces no useful evidence, or the expected service/configuration state is absent.

Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.

Safe checks
  • command -v sudoedit 2>/dev/null || true
  • systemctl --failed --no-pager 2>/dev/null || true
  • journalctl -p warning -n 50 --no-pager 2>/dev/null || true

ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.

Security notes

  • Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.

Alternatives

  • When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.

Stop conditions

  • Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
06

verification

Prove unauthorized domains are not signed

read-only

Route test an allowed sender and a spoofed external From domain; the latter must be rejected or sent unsigned according to anti-spoofing policy.

Why this step matters

Prove unauthorized domains are not signed is a separate checkpoint because it establishes one auditable part of produce verifiable dkim signatures for authorized outbound mail without signing relayed spoofed domains. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.

What to understand

Route test an allowed sender and a spoofed external From domain; the latter must be rejected or sent unsigned according to anti-spoofing policy. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.

Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.

Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.

System changes

  • This step may affect the files, packages, identities, services, or runtime policy named in “Prove unauthorized domains are not signed”. The scope must remain limited to the selected application and supported host.

Syntax explained

swaks
Invokes the principal tool or configuration operation for “Prove unauthorized domains are not signed”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
{{…}}
Marks an operator-supplied value. Replace every placeholder deliberately; do not paste untrusted text or leave braces in the production command.
Command
Fill variables0/4 ready

Values stay on this page and are never sent or saved.

swaks --server localhost --from {{allowedSender}} --to {{testRecipient}} --header 'From: {{allowedSender}}' --header 'X-Test: {{canaryAllowed}}'; swaks --server localhost --from attacker@example.net --to {{testRecipient}} --header 'From: attacker@example.net' --header 'X-Test: {{canaryDenied}}'
Example output / evidence
Owned mail is signed; spoofed unowned mail is denied or not signed.

Checkpoint: Checkpoint: Prove unauthorized domains are not signed

Continue whenOwned mail is signed; spoofed unowned mail is denied or not signed. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.

Stop whenStop before the next step when swaks reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.

If this step fails

The command for “Prove unauthorized domains are not signed” fails, produces no useful evidence, or the expected service/configuration state is absent.

Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.

Safe checks
  • command -v swaks 2>/dev/null || true
  • systemctl --failed --no-pager 2>/dev/null || true
  • journalctl -p warning -n 50 --no-pager 2>/dev/null || true

ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.

Security notes

  • Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.

Alternatives

  • When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.

Stop conditions

  • Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
07

verification

Inspect a delivered signature

read-only

Retrieve the received test message, confirm d=, s=, h=, a=, canonicalization, and verifier result; preserve the raw headers.

Why this step matters

Inspect a delivered signature is a separate checkpoint because it establishes one auditable part of produce verifiable dkim signatures for authorized outbound mail without signing relayed spoofed domains. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.

What to understand

Retrieve the received test message, confirm d=, s=, h=, a=, canonicalization, and verifier result; preserve the raw headers. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.

Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.

Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.

System changes

  • This step may affect the files, packages, identities, services, or runtime policy named in “Inspect a delivered signature”. The scope must remain limited to the selected application and supported host.

Syntax explained

grep
Invokes the principal tool or configuration operation for “Inspect a delivered signature”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
{{…}}
Marks an operator-supplied value. Replace every placeholder deliberately; do not paste untrusted text or leave braces in the production command.
Command
Fill variables0/1 ready

Values stay on this page and are never sent or saved.

grep -A3 -i '^DKIM-Signature:' {{receivedMessageFile}}; grep -iE 'Authentication-Results:.*dkim=' {{receivedMessageFile}}
Example output / evidence
The verifier reports dkim=pass with expected domain and selector.

Checkpoint: Checkpoint: Inspect a delivered signature

Continue whenThe verifier reports dkim=pass with expected domain and selector. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.

Stop whenStop before the next step when grep reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.

If this step fails

The command for “Inspect a delivered signature” fails, produces no useful evidence, or the expected service/configuration state is absent.

Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.

Safe checks
  • command -v grep 2>/dev/null || true
  • systemctl --failed --no-pager 2>/dev/null || true
  • journalctl -p warning -n 50 --no-pager 2>/dev/null || true

ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.

Security notes

  • Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.

Alternatives

  • When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.

Stop conditions

  • Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.
08

instruction

Rehearse overlapping key rotation

read-only

Publish the next selector first, verify DNS, configure it, test, keep the old public key through maximum message transit, then retire it with an incident-ready rollback.

Why this step matters

Rehearse overlapping key rotation is a separate checkpoint because it establishes one auditable part of produce verifiable dkim signatures for authorized outbound mail without signing relayed spoofed domains. Performing it independently keeps a failed prerequisite, syntax error, or compatibility mismatch from being hidden by later actions.

What to understand

Publish the next selector first, verify DNS, configure it, test, keep the old public key through maximum message transit, then retire it with an incident-ready rollback. Read the complete command or configuration before execution, replace the documented placeholders, and compare the target host with the supported environments listed at the beginning of this tutorial.

Capture the before-state and the exact output in the change record. If this step modifies a file or service, validate the candidate with its native checker before any reload; a successful process exit alone does not prove that the application uses the intended value.

Use a representative staging or canary host first. Repeat the stated checkpoint immediately, because proceeding with ambiguous evidence makes the later end-to-end verification and rollback materially harder.

System changes

  • This step may affect the files, packages, identities, services, or runtime policy named in “Rehearse overlapping key rotation”. The scope must remain limited to the selected application and supported host.

Syntax explained

dig
Invokes the principal tool or configuration operation for “Rehearse overlapping key rotation”; confirm that it resolves to the expected packaged executable or file before using elevated privileges.
{{…}}
Marks an operator-supplied value. Replace every placeholder deliberately; do not paste untrusted text or leave braces in the production command.
Command
Fill variables0/2 ready

Values stay on this page and are never sent or saved.

dig +short TXT {{nextSelector}}._domainkey.{{domain}}; sudo openssl pkey -in /etc/exim4/dkim/{{domain}}.{{nextSelector}}.key -check -noout
Example output / evidence
The next selector and key validate before activation.

Checkpoint: Checkpoint: Rehearse overlapping key rotation

Continue whenThe next selector and key validate before activation. Treat this concrete evidence as the minimum success signal and also confirm that unrelated services and the previous healthy path remain unchanged.

Stop whenStop before the next step when dig reports an error, the output differs materially from the example, an unexpected package/service/path is affected, or the required before-state and rollback artifact are missing.

If this step fails

The command for “Rehearse overlapping key rotation” fails, produces no useful evidence, or the expected service/configuration state is absent.

Likely causeA placeholder targets the wrong environment, the installed version uses another path or unit name, permissions are insufficient, or an earlier prerequisite was not satisfied.

Safe checks
  • command -v dig 2>/dev/null || true
  • systemctl --failed --no-pager 2>/dev/null || true
  • journalctl -p warning -n 50 --no-pager 2>/dev/null || true

ResolutionDo not improvise a privileged workaround. Re-read the environment and variable table, inspect the official source for the installed version, restore the candidate file if necessary, and repeat only this checkpoint.

Security notes

  • Keep secrets out of shell history, process arguments, screenshots, logs, and tutorial placeholders. Elevate only the narrow command that requires it and preserve package signature and TLS verification.

Alternatives

  • When the host layout or software version differs, use the vendor-supported equivalent in a disposable staging environment and document the mapping before touching production.

Stop conditions

  • Stop if the action broadens network exposure, permissions, package sources, writable paths, or service privileges beyond the tutorial's declared architecture.

Finish line

Verification checklist

Current DNS recorddig +short TXT {{selector}}._domainkey.{{domain}}A complete DKIM1 public key record is returned.
Delivered authenticationgrep -iE 'Authentication-Results:.*dkim=pass' {{receivedMessageFile}}The received message records DKIM pass for the owned domain.

Recovery guidance

Common problems and safe checks

A message remains queued or the remote server returns a temporary 4xx response.

Likely causeDNS/MX resolution, routing, network reachability, TLS negotiation, remote greylisting/rate limits, reputation or recipient policy prevents delivery.

Safe checks
  • exim -bp 2>/dev/null || postqueue -p
  • dig +short MX example.net
  • journalctl -u exim4 -u postfix --since '-30 min' --no-pager

ResolutionInspect one message's recorded diagnostic and route first, fix the evidenced dependency, then retry only that message; do not force an undiagnosed bulk queue.

SMTP accepts a recipient, but the mailbox is absent, unreadable or never visible over IMAP.

Likely causeRecipient maps, LMTP/LDA route, virtual UID/GID, Maildir path, quota, Dovecot namespace or filesystem permissions disagree.

Safe checks
  • doveconf -n
  • doveadm user user@example.com
  • doveadm mailbox list -u user@example.com

ResolutionTrace the exact address through recipient validation, delivery socket and resolved mailbox path; correct the narrow mapping/ownership mismatch before accepting more mail.

Authentication or TLS fails despite apparently correct credentials and certificate files.

Likely causeThe listener uses another configuration, hostname/SAN does not match, chain/key permissions are wrong, authentication is attempted without TLS, or the identity backend maps another username.

Safe checks
  • openssl s_client -connect mail.example.com:587 -starttls smtp -servername mail.example.com </dev/null
  • openssl s_client -connect mail.example.com:993 -servername mail.example.com </dev/null
  • journalctl -u dovecot -u postfix -u exim4 -p warning -n 100 --no-pager

ResolutionVerify the advertised hostname, chain, listener and mapped user independently; never disable certificate verification or enable plaintext authentication to bypass the failure.

After the procedure

Alternatives and next steps

Consider these alternatives

  • Use a reputable managed mail transport or mailbox provider when staffing, deliverability, abuse response, DNS reputation and 24/7 queue operations cannot be sustained.
  • Separate inbound, outbound, submission and mailbox roles across hosts only when TLS identity, routing, backups and observability remain end-to-end testable.

Operate it safely

  • Alert on queue age/depth, delivery deferrals, authentication failures, TLS/certificate expiry, disk/quota pressure, DKIM/DMARC failures and backup restore age.
  • Review relay/recipient maps, dormant users, supported versions, DNS policy and key/certificate rotation at least every 90 days.
  • Practice one-message queue diagnosis and an isolated mailbox/config restore so incident steps are proven before a real outage.

Reference

Frequently asked questions

Why is one successful test email insufficient?

It may bypass the actual external DNS, authentication, recipient, DKIM, queue retry or IMAP path. Test each boundary and preserve protocol/header evidence.

Can TLS be tested by checking that encryption is present?

No. Verify the chain and hostname and ensure authentication is unavailable before STARTTLS; encryption to an unverified endpoint is not server authentication.

Should a stuck queue be forced immediately?

No. Read one message's diagnostic and fix the dependency first. Bulk retries can amplify rate limits, duplicates or reputation damage.

Recovery

Rollback

Switch Exim back to the previous still-published selector and rebuild configuration.

  1. Restore the prior selector/key configuration, rebuild, restart, and send a canary.
  2. Keep both DNS public keys published until delayed mail using either selector has expired.
  3. Never delete private-key evidence during an active signing incident; revoke access instead.

Evidence

Sources and review

Verified 2026-07-25Review due 2026-10-23
Exim DKIM, SPF, SRS, and DMARCofficialRFC 6376: DomainKeys Identified MailofficialExim current specificationofficial