Outbound Mail Sender Identity Provisioning Gate for Egress IPs avatar

Outbound Mail Sender Identity Provisioning Gate for Egress IPs

Pricing

from $2.00 / 1,000 run starteds

Go to Apify Store
Outbound Mail Sender Identity Provisioning Gate for Egress IPs

Outbound Mail Sender Identity Provisioning Gate for Egress IPs

SPF result for your egress IP, before the first mail. Give it the From domain, the egress IP addresses and the DKIM selectors of a new relay, tenant or email provider. It runs SPF check_host() for each IP (RFC 7208, with lookup counts), checks reverse DNS

Pricing

from $2.00 / 1,000 run starteds

Rating

0.0

(0)

Developer

kingii98

kingii98

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Categories

Share

Outbound Mail Sender Identity Provisioning Gate for Egress IPs, DKIM Selectors, and Reverse DNS

Get the SPF result for your egress IP and the reverse DNS result before you send the first mail.

You give the From domain, the egress IP addresses and the DKIM selectors of a new relay, tenant or email provider. For each sender identity, the Actor does these checks:

  • It runs SPF check_host() (RFC 7208) for each egress IP. It gives the result, the mechanism that matched, the DNS lookup count against the limit of 10 and the void lookup count against the limit of 2.
  • It finds the PTR names of each egress IP. It checks if each name resolves back to the IP (forward-confirmed reverse DNS). It also marks provider default names, for example ec2-…amazonaws.com. This mark is a heuristic.
  • It checks that the HELO name resolves to the egress IP.
  • It looks up each DKIM key at <selector>._domainkey.<from domain>. It gives the key type, the key size and the revoked state (empty p=). It also compares the key with the SHA-256 that you expect.
  • It finds the DMARC record and its policy, and it tells you if DMARC alignment is possible.
  • It gives a ready or blocked verdict. The verdict lists each blocking code with a one-line fix.

Use it in a deploy pipeline. Call the Actor through the Apify API before the pipeline enables mail for a new environment, tenant, customer, relay or provider.

What the Actor does not do

  • It does not open SMTP connections, and it does not send mail.
  • It does not query commercial DNS blocklists, because their free use does not permit commercial use.
  • It uses public DNS only: DNS-over-HTTPS at dns.google, with cloudflare-dns.com as the fallback. It does not fetch URLs that you supply.
  • It does not check private or reserved egress addresses (for example 10.0.0.0/8, 192.0.2.0/24, fe80::/10). Such an address gets the code egress_ip_not_public, and the gate is blocked.

Input

FieldRequiredDescription
identitiesyes (has a default)1 to 50 sender identities.
identities[].from_domainyesThe RFC 5322 From domain.
identities[].egress_ipsyes1 to 16 IPv4 or IPv6 addresses.
identities[].dkim_selectorsyes1 to 5 selectors.
identities[].envelope_domainnoThe MAIL FROM (Return-Path) domain. The SPF check uses this domain. Default: from_domain.
identities[].helo_namenoThe HELO or EHLO name of the relay. The %{h} SPF macro also uses it.
identities[].expected_dkim_key_sha256noAn object selector -> SHA-256 of the base64-decoded p= value, in hex or base64. With one selector, a single string is also correct.
fail_onnoThe check codes that set the gate to blocked. Default: spf_not_pass, dkim_missing, ptr_missing, ptr_not_forward_confirmed, dmarc_missing.

Example:

{
"identities": [
{
"from_domain": "example.com",
"envelope_domain": "bounce.example.com",
"egress_ips": ["198.51.100.25", "2001:db8:25::25"],
"dkim_selectors": ["s2026"],
"helo_name": "relay1.example.com",
"expected_dkim_key_sha256": {"s2026": "3f1c…64 hex characters…"}
}
],
"fail_on": ["spf_not_pass", "dkim_missing", "ptr_missing", "ptr_not_forward_confirmed", "dmarc_missing", "ptr_generic"]
}

The addresses in this example are documentation addresses. The Actor does not check them. Use your public egress addresses.

With an empty input, the Actor checks two sample identities: github.com (ready) and example.com (blocked, because its SPF record is -all and it has no DKIM key).

If the input is not valid, the Actor writes one run-error record with the reason, and the run ends SUCCEEDED. It checks nothing and charges nothing.

Output

The default dataset has four record types. The Gate verdicts, Egress IPs and DKIM selectors views show them as tables.

sender-ip: one record for each identity and egress IP

FieldMeaning
egressIp, ipVersionThe address.
evaluatedfalse for a private or reserved address that the Actor did not check.
spfResultpass, fail, softfail, neutral, none, permerror or temperror.
spfMatchedMechanismThe path to the mechanism that matched, for example include:_spf.google.com > ip4:209.85.128.0/17.
spfReason, spfRecordWhy the result occurred, and the SPF record of the envelope domain.
spfDnsLookups / spfDnsLookupLimitThe DNS lookups of the evaluation, and the limit of 10.
spfVoidLookups / spfVoidLookupLimitThe lookups that returned no data, and the limit of 2.
spfAlignment, spfAlignedstrict, relaxed or none for the envelope domain against the From domain, and if this satisfies the DMARC aspf tag.
ptrNames, fcrdnsResult, fcrdnsNamesThe PTR names. The result is pass, fail, no_ptr or lookup_error. The names are the names that resolve back to the IP.
genericPtr, genericPtrReason, genericPtrIsHeuristicThe generic-PTR heuristic (see below).
heloResult, heloAddressesmatches_egress_ip, resolves_elsewhere, no_address, lookup_error or not_given.
checkCodesThe check codes of this IP.

dkim-selector: one record for each DKIM selector

selector, dnsName, txtFound, dkimRecord, keyType (rsa or ed25519), keySizeBits, revoked (empty p=), testMode (t=y), keySha256, expectedKeySha256, expectedKeyMatch, note and checkCodes.

sender-gate: one record for each identity

status (ready or blocked), blockingCodes, warningCodes, fixes (for each code: the code, blocking, a one-line fix, and where the code occurred), dmarcFound, dmarcRecordName, dmarcRecord, dmarcPolicy, dmarcSubdomainPolicy, dmarcPct, aspf, adkim, alignmentPossible (yes or no), spfPassIps, usableDkimSelectors, egressIpsRejected and failOn.

Alignment is possible if all checked egress IPs get SPF pass with an aligned envelope domain, or if one selector has a usable DKIM key under the From domain.

For a subdomain without its own DMARC record, the Actor uses the record of the organizational domain (Public Suffix List) and its sp= policy.

run-summary: one record for each run

The number of identities that are ready, blocked and skipped, the blocked identities with their codes, the checked IPs and selectors, the DNS lookup count and the notes.

The status message of the run gives the same summary, for example 2 sender identities: 1 ready, 1 blocked (example.com: dkim_missing, spf_not_pass). 2 egress IPs and 2 DKIM selectors checked.

A blocked gate is a result, not an error. The run ends SUCCEEDED. Your pipeline must read status from the sender-gate records.

Check codes

CodeBlocks by defaultMeaning
spf_not_passyesThe SPF result for the egress IP is not pass.
spf_lookup_limit_nearnoThe evaluation used 8 or more of the 10 DNS lookups.
spf_not_alignednoThe envelope domain does not align with the From domain.
dkim_missingyesThe selector has no usable key: no record, an empty p=, a key that does not parse, or an RSA key under 1024 bits.
dkim_revokednoThe record has an empty p=. It also sets dkim_missing.
dkim_invalid_keynoThe p= value is not a valid RSA or Ed25519 key. It also sets dkim_missing.
dkim_weak_keynoThe RSA key has fewer than 1024 bits. It also sets dkim_missing.
dkim_key_mismatchnoThe key is not the key that expected_dkim_key_sha256 names.
dkim_test_modenoThe record has t=y.
ptr_missingyesThe egress IP has no PTR record.
ptr_not_forward_confirmedyesNo PTR name resolves back to the egress IP.
ptr_genericnoThe PTR name looks like a provider default (heuristic).
helo_not_resolvingnoThe HELO name has no A or AAAA record.
helo_mismatchnoThe HELO name does not resolve to the egress IP.
dmarc_missingyesNo single valid DMARC record applies to the From domain.
dmarc_alignment_impossiblenoNeither SPF nor DKIM can give DMARC alignment.
egress_ip_not_publicalwaysThe address is private or reserved.
dns_lookup_erroralwaysA DNS lookup failed or timed out. The check is not proven, so the gate is blocked. Run the gate again.

To make a code block the gate, add it to fail_on. egress_ip_not_public and dns_lookup_error always block.

The generic-PTR heuristic

A PTR name is generic when one of these rules is true:

  1. The name contains the IP address: the four octets in order or reversed, the first three octets, the 12 zero-padded digits, or the 8 hex digits. For IPv6, the name contains the last 12 hex nibbles.
  2. A part of a label is a word for an access or dynamic pool, for example dynamic, dhcp, pool, dsl, cable, customer or client.
  3. The name ends with a provider default suffix, for example .amazonaws.com, .googleusercontent.com, .your-server.de, .vultrusercontent.com or .linodeusercontent.com.

The rule is a heuristic, so ptr_generic does not block by default. If a result is incorrect, open an issue.

Limits

  • 50 identities, 16 egress IPs and 5 selectors for each identity.
  • Each DNS answer is cached for the run, so the same include chain across many IPs costs its lookups one time.
  • One run has a limit of 15,000 DNS lookups. Each lookup has a timeout of 8 s. Each SPF evaluation has a timeout of 40 s, and after that the result is temperror.
  • The DNS answers have a limit of 64 KB. The Actor does not follow redirects.
  • The %{p} SPF macro expands to unknown, as RFC 7208 section 7.3 permits.

Pricing

This Actor uses pay per event.

EventUnitPrice (USD)When
run-startedone Actor run0.002Once for each run with a valid input.
sender-ip-evaluatedone egress IP evaluated against SPF and reverse DNS for one identity0.004Once for each public egress IP of each checked identity. A private or reserved address is not charged.
dkim-selector-checkedone DKIM selector looked up and its key checked0.001Once for each selector of each checked identity.
sender-gate-verdictone ready or blocked verdict for one sender identity0.01Once for each checked identity.

The Actor charges the events of an identity after it writes the records of that identity. The run-summary record and a run-error record are not charged.

What one provisioning call costs

1 identity, 2 egress IPs, 2 DKIM selectors:

EventCountPriceCost (USD)
run-started10.0020.0020
sender-ip-evaluated20.0040.0080
dkim-selector-checked20.0010.0020
sender-gate-verdict10.010.0100
Total0.0220

How the size of the run changes the cost

"Charged" uses the default maximum charge of USD 2.00 for each run.

IdentitiesIPs eachSelectors eachUncapped (USD)Charged (USD)Identities checked
1220.02200.02201
10420.28200.282010
50221.00201.002050
501653.95201.977025

What happens at the maximum charge

Before the Actor checks an identity, it makes sure that all events of that identity fit in the rest of the maximum charge. If they do not fit, the Actor stops. It does not check that identity or the identities after it. It writes a note in the run-summary record and in the status message. An identity is never half checked.

With the maximum input (50 identities with 16 IPs and 5 selectors each), a run at the default limit of USD 2.00 checks 25 identities. To check all 50 identities in one run, set the maximum charge to USD 3.96 or more, or split the identities into two runs.