Your question
I am trying to route my emails through my VPS for the SPF checks to validate, and I am wondering how can I set up a second Stalwart instance to be a smarthost email relay. I can find configuration options to send emails to a relay, but not necessarily how to set up a stalwart instance as a relay.
Setting up a dedicated smarthost in Stalwart involves two separate pieces of configuration: the relay (receiving) server must be told to accept and forward mail that isn’t addressed to its own local domains, and the sending server must be told to route outbound mail to that relay.
On the relay instance (VPS)
- It needs some form of authentication or trusted-IP check so it doesn’t become an open relay. This is controlled by the
allowRelaying expression on the MtaStageRcpt object (Settings › MTA › Session › RCPT TO Stage). By default it only allows relaying for authenticated sessions:{
"allowRelaying": {
"match": {"0": {"if": "!is_empty(authenticated_as)", "then": "true"}},
"else": "false"
}
}
You can instead (or additionally) match on the sending server’s source IP if you’d rather not configure SMTP auth credentials for this link.
- Normal outbound delivery (MX lookups etc.) on the relay then just handles forwarding the mail onward as usual, no special config needed there beyond your regular MTA outbound setup.
On your main instance (the one originating mail)
Define a Relay type MtaRoute pointing at the VPS, and select it from your MtaOutboundStrategy routing expression so outbound mail uses it instead of direct MX delivery:
{
"@type": "Relay",
"name": "smarthost",
"address": "vps.example.org",
"port": 25,
"protocol": "smtp",
"implicitTls": false,
"authUsername": "relay_user",
"authSecret": {"@type": "Value", "secret": "your-secret"}
}
Then set the outbound route expression to select 'smarthost' for the relevant recipients (e.g. else: "'smarthost'" to send everything through it).
These objects are managed via the WebUI (Settings › MTA) or stalwart-cli, not a config file.
Reference: MTA outbound routing and RCPT stage / relay
This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong.
Stalwart already relays for authenticated users by default, so the VPS instance needs very little. Install it with the default storage, don’t add your domains to it (it would try to deliver them locally), and create one account, say relay, with a password. That account sends mail for addresses that aren’t its own, so turn off the sender check for it in the MTA AUTH stage settings (mustMatchSender, see MtaStageAuth | Stalwart):
{"match":[{"if":"authenticated_as == 'relay'","then":"false"}],"else":"true"}
Authentication is only offered on TLS ports other than 25. If Pangolin is already using 465 and 587 on the VPS to forward inbound mail home, give the VPS instance a submission listener on another port, 2525 with implicit TLS for example. It sends outbound on 25 without needing to listen there.
On your home server, create a route of type Relay with the VPS hostname as address, that port, TLS and the relay credentials, then change the outbound strategy’s route expression so it returns that route for non-local recipients. Routing | Stalwart has an example. Reload the settings afterwards.
Keep DKIM signing at home; the VPS won’t sign because the domain isn’t local there. Then add the VPS IP to your SPF record and make sure its PTR matches the hostname the VPS uses in EHLO.