Good, I now have enough to give a comprehensive, doc-grounded answer. Let me compile the full picture.
The docs do have a dedicated “Outbound network requirements” section in the system requirements page, and the various spam-filter pages fill in the rest. There is no single consolidated firewall checklist page, but here is what the docs document:
Outbound connections Stalwart needs
The System Requirements page has the official “Outbound network requirements” section, and the spam-filter docs fill in the rest. Here is the full picture from the docs:
Fixed HTTPS endpoints (port 443)
| Destination |
Purpose |
Docs |
github.com, objects.githubusercontent.com |
WebUI bundle download on startup / scheduled refresh |
Requirements / WebUI |
acme-v02.api.letsencrypt.org (default) |
ACME/Let’s Encrypt TLS certificate issuance and renewal |
Requirements |
github.com (releases) |
Spam filter rules download (spam-filter-rules.json.gz) on first start and scheduled updates |
Spam filter general settings |
Your configured AI provider (e.g. api.openai.com, or a local LLM) |
LLM spam classifier / message categorisation (Enterprise, if enabled) |
AI Models |
All of the above can be pointed at internal mirrors/proxies by changing the respective resourceUrl (Applications), ACME directory URL, spamFilterRulesUrl (SpamSettings), or AI model url fields.
DNS (UDP+TCP port 53, or DoH)
Outbound DNS to your configured resolver is required for:
- MX/SPF/DKIM/DMARC lookups for outbound mail delivery
- DNSBL/DNSWL lookups (Spamhaus, Spamcop, Barracuda, Mailspike, and the full
STWT_ core list – these are DNS queries routed through your resolver, not direct TCP connections to the blocklist operators)
DNSBL zone suffixes (e.g. zen.spamhaus.org, bl.spamcop.net, etc.) are resolved via normal DNS – your resolver needs to be able to reach those authoritative servers, but Stalwart itself only talks to your resolver.
Pyzor (UDP port 24441)
Default server: public.pyzor.org:24441 (UDP). Configurable in the SpamPyzor object in WebUI under Settings > Spam Filter > Pyzor. (Pyzor docs)
Intra-cluster / storage (your list was correct)
The docs don’t enumerate specific ports for these because they depend entirely on your chosen backend (PostgreSQL default 5432, Redis default 6379, S3-compatible HTTPS 443, etc.) and cluster transport config.
Regarding “where to find the configured list programmatically”: there is no single API endpoint that dumps all configured outbound destinations. The destinations are spread across configuration objects (SpamDnsblServer, SpamPyzor, SpamSettings, AiModel, Application). The most practical approach for firewall scripting is to query those objects via the JMAP API (or read them in the WebUI) and extract the relevant host/zone/url fields.
This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong.