Skip to content

Latest commit

 

History

History
589 lines (438 loc) · 24 KB

File metadata and controls

589 lines (438 loc) · 24 KB

mailauth CLI Usage

mailauth Logo

mailauth provides a command-line utility for email authentication, complementing its Node.js library. This guide explains how to use the mailauth CLI to perform various email authentication tasks.

Note

mailauth is used by EmailEngine for validating email authentication settings. See the Email Authentication Testing documentation for details.

Table of Contents

Installation

Install the mailauth CLI by downloading the appropriate package for your platform or via npm:

Getting Help

To display help information for the mailauth CLI or any specific command, use the --help flag:

mailauth --help
mailauth report --help
mailauth sign --help
mailauth seal --help
mailauth spf --help

Available Commands

The mailauth CLI offers several commands to perform different email authentication tasks:

  1. report — Validate SPF, DKIM, DMARC, ARC, and BIMI, and optionally DKIM2.
  2. sign — Sign an email with DKIM.
  3. dkim2-sign — Sign an email with DKIM2 (experimental).
  4. dkim2-verify — Verify the DKIM2 signatures of an email (experimental).
  5. dkim2-hash — Generate the DKIM2 header and body hashes for an email.
  6. seal — Seal an email with ARC.
  7. spf — Validate SPF for an IP address and email address.
  8. vmc — Validate BIMI VMC logo files.
  9. bodyhash — Generate the body hash value for an email.
  10. license — Display licenses for mailauth and included modules.

Warning

DKIM2 is not a published RFC yet. The DKIM2 commands are experimental and built against draft-ietf-dkim-dkim2-spec-06, draft-ietf-dkim-dkim2-dns-00 and draft-ietf-dkim-dkim2-bcp-01, see DKIM2.

report

The report command analyzes an email message and returns a JSON-formatted report detailing the results of SPF, DKIM, DMARC, ARC, and BIMI validations.

Usage

mailauth report [options] [email]
  • email: (Optional) Path to the EML-formatted email message file. If omitted, the email is read from standard input.

Options

  • --client-ip x.x.x.x, -i x.x.x.x: IP address of the remote client that sent the email. If not provided, it's parsed from the latest Received header: the connecting address in the TCP-info comment of its from clause (RFC 5321 section 4.4), never an address the client gave in its HELO.
  • --sender user@example.com, -f user@example.com: Email address from the MAIL FROM command. If not provided, it's parsed from the latest Return-Path header.
  • --helo hostname, -e hostname: Hostname from the HELO/EHLO command. Used in some SPF validations.
  • --mta hostname, -m hostname: Hostname of the server performing validations. Defaults to the local hostname.
  • --dns-cache /path/to/dns.json, -n /path/to/dns.json: Path to a DNS cache file. When provided, DNS queries use cached responses.
  • --verbose, -v: Enables verbose output, displaying debugging information.
  • --max-lookups number, -x number: Sets the maximum number of DNS lookups for SPF checks. Defaults to 10.
  • --max-void-lookups number, -z number: Sets the maximum number of void DNS lookups for SPF checks. Defaults to 2.
  • --strict: Follows the RFCs exactly instead of the lenient defaults, for example an rsa-sha1 DKIM signature is reported as dkim=policy. See Strict mode.
  • --reject-rsa-sha1: Reports an rsa-sha1 DKIM signature as dkim=policy and does not count it for DMARC, as --strict does, while every other check keeps the lenient default.
  • --dkim2: Verifies DKIM2 header fields as well. The result is in the dkim2 key of the report and a dkim2= entry is added to Authentication-Results. DKIM2 does not take part in DMARC.
  • --rcpt-to user@example.com, -r user@example.com: RCPT TO address of the delivery, checked against the highest DKIM2-Signature together with --sender. Can be repeated. Without it the DKIM2 result has the rcpt-to-not-checked warning.

Example

mailauth report --verbose --dns-cache examples/dns-cache.json test/fixtures/message2.eml

Sample Output:

Reading email message from test/fixtures/message2.eml
DNS query for TXT mail.projectpending.com: not found
DNS query for TXT _dmarc.projectpending.com: not found
{
  "receivedChain": [
    "..."
  ]
}

For a detailed example of DKIM checks, refer to this gist.

sign

The sign command signs an email message using a DKIM signature.

Usage

mailauth sign [options] [email]
  • email: (Optional) Path to the EML-formatted email message file. If omitted, the email is read from standard input.

Options

  • --private-key /path/to/private.key, -k /path/to/private.key: Path to the private key used for signing.
  • --domain example.com, -d example.com: Domain name for the DKIM signature (d= tag).
  • --selector selector, -s selector: Selector for the DKIM key (s= tag).
  • --algo algorithm, -a algorithm: Signing algorithm (e.g., rsa-sha256). Defaults to rsa-sha256 for an RSA key and ed25519-sha256 for an Ed25519 key.
  • --canonicalization method, -c method: Canonicalization method (e.g., relaxed/relaxed). Defaults to relaxed/relaxed.
  • --time timestamp, -t timestamp: Signing time as a Unix timestamp (t= tag).
  • --header-fields "field1:field2", -h "field1:field2": Colon-separated list of header fields to include in the signature (h= tag). It must include From.
  • --body-length length, -l length: Maximum length of the body to include in the signature (l= tag).
  • --headers-only, -o: Outputs only the DKIM signature headers without the entire message.
  • --strict: Refuses to sign with rsa-sha1 or with an RSA key shorter than 1024 bits (RFC 8301), and with a domain or selector that is not valid RFC 6376 syntax. Without it these are signed, and --verbose prints a warning.

Example

mailauth sign /path/to/message.eml --domain example.com --selector s1 --private-key /path/to/private.key --verbose

Sample Output:

Reading email message from /path/to/message.eml
Signing domain:             example.com
Key selector:               s1
Canonicalization algorithm: relaxed/relaxed
Hashing algorithm:          rsa-sha256
Signing time:               2023-03-15T12:00:00.000Z
--------
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com;
 h=MIME-Version:Date:Message-ID:Subject:To:From:Content-Type;
 ...

dkim2-sign

The dkim2-sign command signs an email message with DKIM2. It adds a DKIM2-Signature header field, and a Message-Instance header field when the message has none yet or has changed since its last instance. Use it as the originator of a message, or as a forwarder that adds its own hop to a message that is already DKIM2 signed.

Usage

mailauth dkim2-sign [options] [email]
  • email: (Optional) Path to the EML-formatted email message file. If omitted, the email is read from standard input.

Options

  • --private-key /path/to/private.key, -k /path/to/private.key: Path to a private key, RSA (at least 1024 bits) or Ed25519. Repeat it to sign with several keys, each with its own --selector.
  • --selector selector, -s selector: Selector of the private key in the same position. Can be repeated. At most two keys can use the same algorithm.
  • --domain example.com, -d example.com: Signing domain (d= tag). It has to be the MAIL FROM domain or a parent of it.
  • --mail-from user@example.com, -f user@example.com: MAIL FROM address the message is sent with (mf= tag), <> for the null sender.
  • --rcpt-to user@example.net, -r user@example.net: RCPT TO address the message is sent to (rt= tag). Can be repeated.
  • --next-domain example.net: For a hop across a trust boundary, the domain of the next DKIM2 signature (nd= tag). Used instead of --mail-from and --rcpt-to.
  • --flag flag: Flag to set (f= tag): donotmodify, donotexplode, exploded, feedback or feedhere. Can be repeated.
  • --nonce value: A value for your own use (n= tag), at most 64 characters.
  • --hash algorithm: Hash algorithm of a new Message-Instance, sha256 or sha512. Can be repeated. Defaults to sha256.
  • --recipe /path/to/recipe.json: For a forwarder that changed the message, a JSON file with the Recipe that recreates the previous instance (r= tag). It is checked before signing, and the command fails if it does not recreate the previous instance.
  • --time timestamp, -t timestamp: Signing time as a Unix timestamp (t= tag). Defaults to the current time.
  • --headers-only, -o: Outputs only the DKIM2 header fields without the message.

Either --mail-from and --rcpt-to, or --next-domain, is required.

Example

mailauth dkim2-sign /path/to/message.eml \
    -k /path/to/rsa.key -s rsa2026 -k /path/to/ed25519.key -s ed2026 \
    -d example.com -f bounces@example.com -r user@example.net

Sample Output:

DKIM2-Signature: i=1; m=1; t=1791646747; d=example.com; mf=
 PGJvdW5jZXNAZXhhbXBsZS5jb20+; rt=PHVzZXJAZXhhbXBsZS5uZXQ+; s=rsa2026:rsa-sha256:
 MXp6X81Tuu/cwbedt/kFqdO1sE4yPkfYVnFzfBMO2ZjfAtoXuptS+G79SYEpEaAo
 ...
Message-Instance: m=1; h=sha256:
 sbKYVMaA7tqVLzGg5HTTU3o95q7ufdnBincKg/jBBQc=:
 GjyEkbey2OupCW5AKJv4dzTPsPHSaZjRDMqUSmhpTyQ=;
From: ...

A mailing list that replaced the Subject header field, added a List-Id header field and appended a footer after the first 3 body lines signs its revision with a Recipe:

{ "h": { "subject": [{ "d": ["Original subject"] }], "list-id": [] }, "b": [{ "c": [1, 3] }] }
mailauth dkim2-sign revised.eml -k list.key -s list -d list.example.org \
    -f bounce@list.example.org -r member@example.net --recipe recipe.json

dkim2-verify

The dkim2-verify command verifies only the DKIM2 header fields of an email message and returns a JSON report. See DKIM2 Result Reference for the structure. Use report --dkim2 to check DKIM2 together with everything else.

Usage

mailauth dkim2-verify [options] [email]
  • email: (Optional) Path to the EML-formatted email message file. If omitted, the email is read from standard input.

Options

  • --mail-from user@example.com, -f user@example.com: MAIL FROM address the message was delivered with, <> for the null sender. Checked against the highest DKIM2-Signature.
  • --rcpt-to user@example.net, -r user@example.net: RCPT TO address the message was delivered to, checked against the highest DKIM2-Signature. Can be repeated.
  • --dns-cache /path/to/dns.json, -n /path/to/dns.json: Path to a DNS cache file. When provided, DNS queries use cached responses.
  • --time timestamp, -t timestamp: Time to verify against as a Unix timestamp. Defaults to the current time.
  • --max-age seconds: Seconds after which a signature expires, 0 to not check. Defaults to 14 days.
  • --max-future seconds: Seconds a signature timestamp may be ahead of the current time, 0 to not check. Defaults to 300.
  • --max-instances number: The most Message-Instance, and the most DKIM2-Signature, header fields to process. Defaults to 20.
  • --headers-only, -o: Outputs only the Authentication-Results entry (dkim2=...) instead of the JSON report.
  • --verbose, -v: Shows the DNS queries, and the parts of the envelope that were not checked.

The chain of custody against the delivery, which is what stops DKIM2 replay, is only checked for the parts of the envelope given with --mail-from and --rcpt-to. A missing part is reported in status.warnings.

Example

mailauth dkim2-verify -f bounces@example.com -r user@example.net -o /path/to/message.eml

Sample Output:

dkim2=pass (i=1 example.com pass) header.d=example.com

dkim2-hash

The dkim2-hash command computes the DKIM2 header and body hashes of an email message, in the algorithm:header-hash:body-hash form of the h= tag of a Message-Instance header field. Use it to check what a Message-Instance should contain, for example when writing a Recipe.

Usage

mailauth dkim2-hash [options] [email]
  • email: (Optional) Path to the EML-formatted email message file. If omitted, the email is read from standard input.

Options

  • --algo algorithm, -a algorithm: Hash algorithm, sha256 or sha512. Can be repeated. Defaults to sha256.
  • --verbose, -v: Also lists the header fields that go into the header hash. DKIM2 does not sign trace header fields, X- header fields, DKIM1, ARC and Authentication-Results header fields, or its own header fields.

Example

mailauth dkim2-hash -v /path/to/message.eml

Sample Output:

Reading email message from /path/to/message.eml
Hashed header fields: content-type, date, from, message-id, mime-version, subject, to
--------
sha256:sbKYVMaA7tqVLzGg5HTTU3o95q7ufdnBincKg/jBBQc=:GjyEkbey2OupCW5AKJv4dzTPsPHSaZjRDMqUSmhpTyQ=

seal

The seal command adds an ARC (Authenticated Received Chain) seal to an email message.

Usage

mailauth seal [options] [email]
  • email: (Optional) Path to the EML-formatted email message file. If omitted, the email is read from standard input.

Options

Sealing Options:

  • --private-key /path/to/private.key, -k /path/to/private.key: Path to the private key used for sealing.
  • --domain example.com, -d example.com: Domain name for the ARC seal (d= tag).
  • --selector selector, -s selector: Selector for the ARC key (s= tag).
  • --algo algorithm, -a algorithm: Sealing algorithm (e.g., rsa-sha256). Defaults based on the private key type.
  • --time timestamp, -t timestamp: Sealing time as a Unix timestamp (t= tag).
  • --header-fields "field1:field2", -h "field1:field2": Colon-separated list of header fields to include in the seal (h= tag).
  • --headers-only, -o: Outputs only the ARC seal headers without the entire message.
  • --strict: Follows the RFCs exactly instead of the lenient defaults.

Seal-Only Options:

By default, seal authenticates the message (SPF, DKIM, DMARC, ARC) and embeds the computed results in the ARC-Authentication-Results header. If the message was already authenticated elsewhere (for example at an edge MTA) and modified afterwards, you can instead provide the original Authentication-Results value yourself. When one of the following options is set, no authentication checks or DNS lookups are performed:

  • --auth-results "authserv-id; spf=pass ...": Authentication-Results value to embed in the ARC-Authentication-Results header (the part after i=N;). Used as is, except that line breaks are written as CRLF. A multi-line value must be folded: every line after the first starts with a space or a tab. A value with any other line break is refused, as it would start a new header field.
  • --auth-results-file /path/to/value.txt: Same as --auth-results, but the value is read from a file. Useful for long or multi-line values. Cannot be combined with --auth-results.
  • --cv status: Chain validation status for the ARC-Seal header (cv= tag): none, pass, or fail. Defaults to none.
  • --instance number: ARC instance number (i= tag). Defaults to the next instance number based on the existing ARC chain of the message, or 1.
mailauth seal message.eml -d example.com -s s1 -k private.key \
  --cv pass --auth-results-file auth-results.txt --headers-only

Authentication Options (from report command):

  • --client-ip x.x.x.x, -i x.x.x.x: IP address of the remote client that sent the email.
  • --sender user@example.com, -f user@example.com: Email address from the MAIL FROM command.
  • --helo hostname, -e hostname: Hostname from the HELO/EHLO command.
  • --mta hostname, -m hostname: Hostname of the server performing validations.
  • --dns-cache /path/to/dns.json, -n /path/to/dns.json: Path to a DNS cache file.
  • --verbose, -v: Enables verbose output.

Note: The canonicalization method (c= tag) for ARC sealing is always relaxed/relaxed and cannot be changed.

Example

mailauth seal /path/to/message.eml --domain example.com --selector s1 --private-key /path/to/private.key --verbose

Sample Output:

Reading email message from /path/to/message.eml
Signing domain:             example.com
Key selector:               s1
Canonicalization algorithm: relaxed/relaxed
Hashing algorithm:          rsa-sha256
Sealing time:               2023-03-15T12:05:00.000Z
--------
ARC-Seal: i=3; a=rsa-sha256; t=1678884300; cv=pass; d=example.com; s=s1;
 b=Fo3hayVos+J77lzzgmr6J92gsUBKlPt/ZkoQt9ZCi514zy8+1WLvTHmI8CMUXAcegdcqP0NHt
 ...

spf

The spf command checks the SPF (Sender Policy Framework) record for a given email address and IP address.

Usage

mailauth spf [options]

Options

  • --sender user@example.com, -f user@example.com: Email address from the MAIL FROM command. Required.
  • --client-ip x.x.x.x, -i x.x.x.x: IP address of the remote client that sent the email. Required.
  • --helo hostname, -e hostname: Hostname from the HELO/EHLO command.
  • --mta hostname, -m hostname: Hostname of the server performing the SPF check.
  • --dns-cache /path/to/dns.json, -n /path/to/dns.json: Path to a DNS cache file.
  • --verbose, -v: Enables verbose output.
  • --headers-only, -o: Outputs only the SPF authentication header.
  • --max-lookups number, -x number: Sets the maximum number of DNS lookups. Defaults to 10.
  • --max-void-lookups number, -z number: Sets the maximum number of void DNS lookups. Defaults to 2.
  • --max-elapsed-time ms: Maximum time in milliseconds for the whole SPF evaluation, after which the result is temperror. Not limited by default.
  • --strict: Follows RFC 7208 exactly instead of the lenient defaults.

Example

mailauth spf --verbose -f user@example.com -i 192.0.2.1

Sample Output:

Checking SPF for user@example.com
Maximum DNS lookups: 10
--------
DNS query for TXT example.com: [["v=spf1 include:_spf.example.com -all"]]
DNS query for TXT _spf.example.com: [["v=spf1 ip4:192.0.2.0/24 -all"]]
{
  "domain": "example.com",
  "client-ip": "192.0.2.1",
  "result": "pass",
  "..."
}

vmc

The vmc command validates a Verified Mark Certificate (VMC) used in BIMI (Brand Indicators for Message Identification).

Usage

mailauth vmc [options]

Options

  • --authority <url>, -a <url>: URL of the VMC resource.
  • --authorityPath <path>, -p <path>: Path to a local VMC file, used to avoid network requests.
  • --domain <domain>, -d <domain>: Sender domain to validate against the certificate.
  • --date <timestamp>, -t <timestamp>: ISO-formatted timestamp for certificate expiration checks. Defaults to the current time.

Example

mailauth vmc -a https://example.com/path/to/vmc.pem -d example.com

Sample Output:

{
    "url": "https://example.com/path/to/vmc.pem",
    "success": true,
    "domainVerified": true,
    "vmc": {
        "mediaType": "image/svg+xml",
        "hashAlgo": "sha256",
        "hashValue": "abc123...",
        "logoFile": "<Base64 encoded SVG>",
        "validHash": true,
        "type": "VMC",
        "certificate": {
            "subject": {
                "commonName": "Example Inc.",
                "markType": "Registered Mark",
                "..."
            },
            "subjectAltName": ["example.com"],
            "fingerprint": "12:34:56:78:9A:BC:DE:F0...",
            "serialNumber": "0123456789ABCDEF",
            "validFrom": "2023-01-01T00:00:00.000Z",
            "validTo": "2024-01-01T23:59:59.000Z",
            "issuer": {
                "commonName": "Trusted CA"
                "..."
            }
        }
    }
}

If validation fails, the output includes error details:

{
    "success": false,
    "error": {
        "message": "Self signed certificate in certificate chain",
        "details": {
            "..."
        },
        "code": "SELF_SIGNED_CERT_IN_CHAIN"
    }
}

bodyhash

The bodyhash command computes the body hash value of an email message, which is used in DKIM signatures.

Usage

mailauth bodyhash [options] [email]
  • email: (Optional) Path to the EML-formatted email message file. If omitted, the email is read from standard input.

Options

  • --algo algorithm, -a algorithm: Hashing algorithm (e.g., sha256). Defaults to sha256. Can also specify DKIM-style algorithms (e.g., rsa-sha256).
  • --canonicalization method, -c method: Body canonicalization method (e.g., relaxed). Defaults to relaxed. Can use DKIM-style (e.g., relaxed/relaxed).
  • --body-length length, -l length: Maximum length of the body to hash (l= tag).
  • --verbose, -v: Enables verbose output.

Example

mailauth bodyhash /path/to/message.eml -a sha1 --verbose

Sample Output:

Hashing algorithm:               sha1
Body canonicalization algorithm: relaxed
--------
j+dD7whKXS1yDmyoWtvClYSyYiQ=

license

The license command displays the licenses for mailauth and its included modules.

Usage

mailauth license

Example

mailauth license

Sample Output:

mailauth License: MIT License
Included Modules:
- module1: MIT License
- module2: Apache License 2.0
...

DNS Cache File

The --dns-cache option allows you to use a JSON-formatted DNS cache file for testing purposes. This avoids the need to set up a DNS server or wait for DNS propagation.

Format

The DNS cache file is a JSON object where:

  • Keys: Fully qualified domain names (e.g., "example.com"). DKIM and DKIM2 keys are looked up as selector._domainkey.domain.
  • Values: Objects with DNS record types as keys (e.g., "TXT", "MX") and their corresponding values.

Example:

{
    "example.com": {
        "TXT": [["v=spf1 include:_spf.example.com -all"]],
        "MX": [{ "exchange": "mail.example.com", "priority": 10 }]
    },
    "_dmarc.example.com": {
        "TXT": [["v=DMARC1; p=reject; rua=mailto:dmarc@example.com;"]]
    }
}

Usage

Specify the DNS cache file using the --dns-cache option:

mailauth report --dns-cache /path/to/dns-cache.json email.eml

When this option is used, mailauth will not perform actual DNS queries but will use the data from the cache file instead.

License

© 2020-2026 Postal Systems OÜ

Licensed under the MIT License.