zone-eu / zone-mta

📤 Modern outbound MTA cross platform and extendable server application
European Union Public License 1.2
599 stars 96 forks source link

Help with pool & zones #320

Open DuredhelFinceleb opened 1 year ago

DuredhelFinceleb commented 1 year ago

I feel kind of stupid but I can't figure this out.

I have a wildduck+zone-mta+haraka setup (got it from the wildduck install script) The whole setup is in a proxmox container behind a firewall with NAT (iptables), so no direct access to the host public IP

Currently, submitting mails to zone-mta for my domain fails because zone-mta tries to connect to the public IP address and fails

I could try to solve this though firewall rules but in fact these NAT iptables rules are finicky and so far I'm ending up with looping connections. Otherwise I could set up a SMTP relay on the host to forward request sents there by zone-mta into haraka. But this really feels hackish

What I need is a way to tell zone-mta that for my domain there is no need to get the IP from the MX record as the MX address is localhost actually Is that even possible?

Tried to add a pool like this [[local]] address="127.0.0.1" name="localhost"

and a local.toml zone like this [local] preferIPv6=false ignoreIPv6=true processes=1 connections=5 pool="local" recipientDomains=["mydomain.com"]

Logs shows that the zone is correctly detected and used when sending mails to my domain but zone-mta still tries to use the public IP from thr MX record. I did not succeed in making it search for haraka on localhost.

Can someone help?

louis-lau commented 1 year ago

If it fails against the public IP you're not able to receive emails from anyone right? Or is this a test setup where only local mail should be possible?

DuredhelFinceleb commented 1 year ago

Nope, I'm receiving emails just fine and this is production

If I send a mail to some domain, my zone-mta contacts that domain smtp and everything's fine

If someone from some domain sends me an email, their mta contacts my haraka & everything's fine

If I send an email to one of the domain I manage (for example, mail to myself), my zone-mta pulls out my host IP from the MX record and uses it to reach my haraka instead of simply going for localhost. This fails as the host receives an IP request coming from a natted address for which it has no rule. And if you add that rule, then the IP connection loops & never actually connects

How could I miss this? At first, there was just me on that setup, and for some reason it never occured to me to test the "email to myself case" I recently integrated a domain from someone and it's when I realized we could not send mail to each other that I realized the problem.

So far my options to solve this use case are

The last option looks like the easiest & maybe cleanest. Unfortenately, so far I haven't be able to pull this off, hence my question

louis-lau commented 1 year ago

Sounds like your router doesn't support NAT loopback/hairpin NAT? That's very inconvenient indeed, not just for this setup but also for a bunch of other usecases.

People usually resolve this by either getting a router that actually supports NAT loopback, or by running an internal DNS server that points the domain to a local ip.

Those are general solutions though. To only "fix" zone-mta I think you'd create a zone like this:

[loopback]
preferIPv6=false
ignoreIPv6=true
processes=1
connections=5
interface="lo0"
host = "127.0.0.1"
port = 25
recipientDomains=["mydomain.com"]
DuredhelFinceleb commented 1 year ago

Thanks a lot it works!!

I will investigate the NAT loopback/hairpin NAt thing though The way you describe it, it would be the best solution. Additional motivation is that zone-mta says "DeprecationWarning: Setting the TLS ServerName to an IP address is not permitted by RFC 6066. This will be ignored in a future version." so I guess this solution won't hold forever

louis-lau commented 1 year ago

I don't think that's a warning of zonemta itself. Probably a warning of nodejs when zonemta tries starttls on 127.0.0.1. But if that ever fails it should also just send without starttls. I think you should be fine.

DuredhelFinceleb commented 1 year ago

well the warning goes away if you just set 'host="localhost' instead of 'host="127.0.01"' 😃

DuredhelFinceleb commented 1 year ago

so I've managed to set up NAT hairpin still not the solution though.

without hairpin, no CT can connect to an other one via the public IP with hairpin, the wildduck CT can connect to the other CTs via the public IP and vice-versa but it won't work when the wildduck CT is trying to connect to itself via the public IP (and in the end I think it's not a big surprise) and that last case is my use case I guess I could set up an addtional interface with a new local IP address in the wildduck CT and setup things so that connection to haraka go through that new address. This way, technically speaking, the CT would try to connectot itself anymore

All in all, for this use case using the new zone is just simpler so I'll stick to that

louis-lau commented 1 year ago

but it won't work when the wildduck CT is trying to connect to itself via the public IP (and in the end I think it's not a big surprise)

The idea behind hairpin NAT is that you'd access the public ip internally exactly the same way as you would externally. So that is a big suprise to me. It doesn't sounds like it's working correctly to me. But sticking with a special loopback zone should work fine as well.

DuredhelFinceleb commented 1 year ago

nailed it on the wildduck CT, I had to add a iptables rules to redirect connections to the public IP to localhost local net routing must be activated for this to work with this everything works the hairpin takes care of the cases when the wildduck CT talks to another CT the local net routing takes case of the cases when the wildduck CT talks to itself