zone-eu / zone-mta

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

Report very big bug #418

Closed ravivgolov closed 1 week ago

ravivgolov commented 2 weeks ago

Hello

I want to report a bug that you may want to fix to improve your MTA.

When there are multiple MX records, I receive the following error:

DNS Error: DNS error occurred while resolving the Mail Exchange (MX) server for the specified domain (removed.com). DNS server returned general failure

The recipient domain has the following DNS records:

1 | aspmx.l.google.com | 2607:f8b0:4004:c06::1b
5 | alt1.aspmx.l.google.com | 209.85.202.26Google LLC (AS15169) 
5 | alt1.aspmx.l.google.com | 2a00:1450:400b:c00::1b 
5 | alt2.aspmx.l.google.com | 64.233.184.26Google LLC (AS15169)
5 | alt2.aspmx.l.google.com | 2a00:1450:400c:c0b::1b
10 | alt3.aspmx.l.google.com | 142.250.27.26Google LLC (AS15169) 
10 | alt3.aspmx.l.google.com | 2a00:1450:4025:401::1a

I have gone ahead and tried via another MTA - and that worked. I can provide the recipient domain if you want to test it.

Note: this is a big issue.

louis-lau commented 2 weeks ago

You can disable the built in dns caching if you don't need it in your setup.

https://github.com/zone-eu/zone-mta-template/blob/2ec1ba85a44c4665a6326271c8162ee76c4d6d02/config/dns.toml#L2

ravivgolov commented 2 weeks ago

Oh thank you so much. is it better to have for performance?

Edit: it is already set to false:

# If true then caches DNS results to Redis
caching=false
cacheTTL=600 # TTL of cached dns keys in seconds

# Define nameservers to use (IP addresses only). If using a local DNS cache server, then set caching=false
nameservers=[]

#caching=false
#nameservers=["127.0.0.1"]

blockDomains=[]

# If true then messages to local interfaces are blocked (eg. you can not send to username@localhost)
blockLocalAddresses=false

Does the error could be due to my server resolving to public DNS resolvers, such as Cloudflare?

louis-lau commented 2 weeks ago

It could simply be that the ttl hasn't expired yet on whatever dns your server uses. If you do use 1.1.1.1, you can request manual expiry of the cache here: https://one.one.one.one/purge-cache/

Googles 8.8.8.8 has a similar tool.

Doesn't sound like a bug to me, sounds like your normal everyday dns propagation :)

ravivgolov commented 2 weeks ago

Yeah, but the weird thing, is I tried from 3 different servers on 3 different data centers all servers failed:

root@smtp:/home/ubuntu# dig mx removed.org @8.8.8.8

; <<>> DiG 9.18.28-0ubuntu0.22.04.1-Ubuntu <<>> mx removed.org @8.8.8.8
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 44325
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
; EDE: 10 (RRSIGs Missing): (For removed.org/mx)
;; QUESTION SECTION:
;removed.org.                  IN      MX

;; Query time: 40 msec
;; SERVER: 8.8.8.8#53(8.8.8.8) (UDP)
;; WHEN: Sun Aug 25 11:47:20 UTC 2024
;; MSG SIZE  rcvd: 66

root@smtp:/home/ubuntu#

Can I share the recipient's domain with you privately, so you can check if you're able to send an email or dig into the MX records?

It's quite strange. I used online tools to check the domain, and all tools resolved this MX, including another MTA I used (MailChannels). However, from three different servers of mine, I'm unable to connect.

louis-lau commented 2 weeks ago

Do the servers actually use 8.8.8.8 as the resolver though?

louis-lau commented 2 weeks ago

Sorry I missed that it reports a complete failure. I thought it was giving old mx for some reason. That what you get for quickly answering on your phone haha.

Still sounds like an issue with whatever resolver your server is using though. You can try and set zone-mta to use 8.8.8.8 directly.

ravivgolov commented 2 weeks ago

Some of them, but I also tested directly via 8.8.8.8 with the following: dig mx removed.org @8.8.8.8 or dig mx removed.org @1.1.1.1

All reports return the same result. I found that there is a DNSSEC issue with this domain, but how come online tools are able to resolve the MX records? It’s probably due to caching, maybe? What’s more unusual is how MailChannels was able to deliver the email to that recipient despite the issue with their MX records.

How do I set zone-mta to use 8.8.8.8? that will be good for performance?

louis-lau commented 2 weeks ago

Lol I also missed that there was an error on 8.8.8.8 per what you shared. I need to go eat something, not thinking clearly. Never mind about what I said.

DNSSEC failure does make sense. It's up to the resolver to verify DNSSEC, both google and Cloudflare do this. The online tools may be using resolvers that aren't DNSSEC capable. Mailchannels probably as well, which is unexpected to be completely honest.

ravivgolov commented 2 weeks ago

No worries :).

Omg, that means I found MailChannels tricks his customers because the email is not really delivered! Wow...

One last thing, I really can’t understand: I’ve connected ZoneMTA to my WHMCS and enabled the DKIM plugin, which is working fine. DKIM signatures are applied correctly and everything looks good.

However, when I send an email using WHMCS with the same email address, I get a "hash break" in the body. How is this possible? Nothing has changed inside ZoneMTA, and this issue only occurs with WHMCS. Is it possible that WHMCS manipulates the email right after connecting to ZoneMTA during the SMTP connection? I'm not sure how this could happen. Also, when I use MailChannels, the problem does not occur :).

louis-lau commented 2 weeks ago

Not sure to be honest! Does sound odd

ravivgolov commented 1 week ago

@louis-lau Do you know how to bypass the from?

 app.addHook('sender:headers', (delivery, connection, next) => {

        // Working without the condition, but how can I get the condition if the envelope is not available here?

        // if(delivery.envelope.smtpAuthProp && delivery.envelope.smtpAuthProp.spamFilter !== "active"){
        //         if (delivery.envelope.from) {
        //            
        //             delivery.envelope.from = `mw_bounce-${delivery.envelope.id}@test.com`;
        //
        //         }
        // }

        next();
    });

That is working, I mean the bypass, but the condition is not. I'm unable to retrieve envelope.smtpAuthProp.spamFilter that I set in smtp:data. I can get the value in other functions where the envelope is available, but sender:headers do not have the envelope, and in delivery.envelope, it is empty.

Do you have any idea how to bypass the from with another hook?

louis-lau commented 1 week ago

Envelope from is not the same as header from. What are you trying to achieve? Also, please open new issues if they're seperate issues.

ravivgolov commented 1 week ago

It's a different question just I do not want to spam with more threads, because it simple question and not an issue.

Yes, I want to change the Return-Path AKA Enevelope From, for some reason, I need to do this.

Do you still want to open a new question? I just need the right hook for this. So I can also get the envelope.

ravivgolov commented 1 week ago

@louis-lau @andris9 So I am looking something similar to this: https://github.com/zone-eu/zone-mta/issues/354

I was able to achieve it as above, but I need also access to the envelope.from, which hook can I use to bypass the Return-Path/Mail from?

ravivgolov commented 1 week ago

Able to find the right hook. thanks

louis-lau commented 1 week ago

because it simple question and not an issue.

I understand! But the email I get in my inbox has the subject "Report very big bug" ;). Glad you were able to find the right hook