IP family preference for outgoing SMTP connections
Hi! First of all, thanks for the great work on the project, really appreciate it. After years of battling with "traditional", 40-different-components mail servers, this is a real breath of fresh air.
Is it possible to configure mox to prefer IPv4 for outgoing SMTP connections? AFAIK mox only supports fully disabling IPv4/IPv6.
It would be great to have a way to prefer IPv4, while still allowing IPv6 as a fallback if the recipient server is IPv6-only.
Receiving over IPv6 is fine, but I’m still not fully comfortable sending over IPv6. A preference option would be a good middle ground during the transition to IPv6 (which has been going on for the last 20 years and will probably take 100 more 😄).
May I ask why you're not comfortable with sending over IPv6. Half of my inbound mailtraffic is IPv6 without any problems.
May I ask why you're not comfortable with sending over IPv6. Half of my inbound mailtraffic is IPv6 without any problems.
I’m okay with IPv6 for inbound traffic, but I’m just not too confident about sending mail over it. IP reputation is already messy with IPv4 as it is, and I’m not really sure how the bigger providers handle mail that comes in over IPv6. The last thing I want is to give Outlook and others another reason to silently drop my mail. Until IPv6 becomes a bit more common (maybe it already is?), I’d rather stick with IPv4 for outgoing connections whenever possible.
Indeed it's currently not possible to specify a preference.
I didn't know exactly how the address was selected. Since the resolver does both a lookup of an A and AAAA record concurrently, I suspected we would use whichever was returned first, i.e. non-deterministic. I looked into it, and we're actually preferring IPv6, since the pure Go DNS resolver uses address selection according to RFC 6724. See https://datatracker.ietf.org/doc/html/rfc6724#section-2.1 and the paragraph that says Another effect of the default policy table is to prefer communication using IPv6 addresses to communication using IPv4 addresses, if matching source addresses are available.
I haven't heard of problems due to delivery over IPv6. I have seen a few cases where delivery over IPv4 didn't work due to the IP being in a blocklist, while delivery over IPv6 worked fine. Mox does some special handling around address families: If the first delivery attempt fails with some permanent "5xx" codes, we should stop further delivery attempts according to the specs, but we still try again over the other address family just to work around bad DNSBLs.
However, in practice, recipient mail servers often "accept" incoming email, but "deliver" it to the spam folder. And the IP reputation status can play a role. In practice, in some cases IPv4 is better, and in others IPv6. We already monitor the system IPs in a few common DNSBLs. What we don't do, but probably should: If an address is listed in a DNSBL, prefer using other non-listed configured IPs for outgoing email.
I'm not against adding a config option to the "Direct" transport (that can already be used to only deliver using ipv4 or ipv6) to indicate preference for one address family. We are already using a fork of the pure Go DNS resolver (to get the DNSSEC status of a DNS response). Enabling that option would change the effect of the policy table, see https://github.com/mjl-/adns/blob/ab04b05bdfead46963439746347dbf1b805c0f70/addrselect.go#L240 and https://github.com/mjl-/adns/blob/ab04b05bdfead46963439746347dbf1b805c0f70/addrselect.go#L284
However, in practice, recipient mail servers often "accept" incoming email, but "deliver" it to the spam folder.
This kind of thing happens way too often. I've run into it with a bunch of different providers, and Outlook was the worst by far. Even if an IP hasn’t ever sent spam (at least during the time it’s been with me), isn’t listed in any DNSBL, and the server is set up properly, it still gets silently delivered to spam. It really feels like they just hate decentralisation and want to make the lives of postmasters as difficult as possible.
However, it doesn’t happen as much if the IP has been in use for a while and hasn’t had any issues. That’s why, if the receiving mail server supports both, I’d rather Mox choose IPv4 over IPv6.
What we don't do, but probably should: If an address is listed in a DNSBL, prefer using other non-listed configured IPs for outgoing email.
Great idea! With Postfix, I usually just removed the IP that was having issues until it was resolved, but automating something like this would be really nice.
EDIT: See below for original message, then I have corrections.
@mjl- I'm also extremely thankful for mox. Here is what I'm running into.
- I'm running mox on OVH.
- OVH assigns a default IPv4 and IPv6 addres, and then I got another IPv4 address that was "clean" and assigned it.
- Mail can't be delivered if it sends it with an IP address that doesn't have the correct PTR to the hostname.
- I can't assign the PTR record (on OVH) unless I have the addresses point to the domain.
- I don't want to associate the (tainted) IP addresses to the domain for obvious reasons.
So what I need to do, for the moment, is to ensure that outbound connections always send with a specific IP address (such as with host routing). Or something else so mox only sees a single IP address. (for various reasons, I may not be able to get rid of the other IPs)
But I would prefer, under each domains config, to be able to set a specific IP address to send from. In Go, I believe that we would need to create a new net.Dialer per account and set net.Dialer.LocalAddr.
If you would welcome the change, I could probably make it happen if you are okay with the above.
Corrections:
Mox already has a list of IP addresses it uses for both listening and sending in the mox.conf. However, if the remote IP address is IPv6 and mox only has mound an IPv4 address, then the logic in smtpclient/dail.go, in func Dial, then there will be no laddr set, so which IP address it uses will be undefined in Go.
The dialing order does appear to remain intact, starting with IPv4:
Aug 01 17:17:44 notify mox[241698]: l=debug m="ordered ips for dialing" pkg=queue pkg=smtpclient ips=[52.101.10.8;52.101.11.3;52.101.41.3;52.101.8.36;2a01:111:f403:f901::1;2a01:111:f403:c901::1;2a01:111:f403:c902::;2a01:111:f403:f805::1] cid=198617d3e01 [email protected] attempts=2 cid=198617d3e02
So perhaps errors happened with the IPv4 dest so it omits them.
That being said, I think it would be better such that if there is only a single localIPs defined OR if no IP is chosen, that a configured IP address is still chosen, and not one chosen by the OS. But I could be mistaken here.
For my own solution, I'm going to see if I can find a clean IPv6 address to use and set it up, as that should also resolve this issue.