stalwartlabs / mail-server

Secure & Modern All-in-One Mail Server (IMAP, JMAP, POP3, SMTP)
https://stalw.art
5.19k stars 214 forks source link

[bug]: SMTP relay sent to wrong domain #381

Closed europacafe closed 6 months ago

europacafe commented 6 months ago

What happened?

Send a mail to my yahoo, gmail, and outlook accounts in one mail. The mail reached my gmail and outlook mail without problem, but my yahoo mail did not receive it (either in inbox or spam), instead my gmail received the same mail twice, one in its inbox, the other one in its spam box.

I found this incident two times.

If I sent a mail to only my yahoo mail, it reached its inbox/spam box every time.

FYI, I use "brevo" smtp relay free tier service.

How can we reproduce the problem?

I can reproduce the problem by doing the following steps: set up remote servers set routing to the remote servers send a mail to yahoo mail and gmail

Version

v0.7.x

What database are you using?

RocksDB

What blob storage are you using?

RocksDB

Where is your directory located?

Internal

What operating system are you using?

Docker

Relevant log output

Thu, 25 Apr 2024 12:31:53   
INFO    
smtp::outbound::delivery: Delivery completed. context="queue" event="completed"
Thu, 25 Apr 2024 12:31:52   
INFO    
smtp::outbound::session: context="rcpt" event="delivered" rcpt="xxxx@yahoo.com" mx="smtp-relay.brevo.com" response=Delivered: Code: 250, Enhanced code: 2.0.0, Message: I'll make sure <xxxx@yahoo.com> gets this
Thu, 25 Apr 2024 12:31:51   
INFO    
smtp::outbound::session: context="rcpt" event="delivered" rcpt="xxxx@outlook.com" mx="smtp-relay.brevo.com" response=Delivered: Code: 250, Enhanced code: 2.0.0, Message: I'll make sure <xxxx@outlook.com> gets this
Thu, 25 Apr 2024 12:31:50   
INFO    
smtp::outbound::session: context="rcpt" event="delivered" rcpt="xxxx@gmail.com" mx="smtp-relay.brevo.com" response=Delivered: Code: 250, Enhanced code: 2.0.0, Message: I'll make sure <xxxx@gmail.com> gets this
Thu, 25 Apr 2024 12:31:48   
INFO    
common::listener::listen: context="tls" event="handshake" version=TLSv1_3 cipher=TLS13_AES_256_GCM_SHA384
Thu, 25 Apr 2024 12:31:48   
INFO    
smtp::queue::spool: Message queued for delivery. context="queue" event="scheduled" id=171427723762208820 from="cxxxx@mydomain.com" nrcpts=3 size=1659

Code of Conduct

europacafe commented 6 months ago

my sent box image

mdecimus commented 6 months ago

Please provide your next-hop configuration settings.

europacafe commented 6 months ago

I set it with Admin GUI

image

Remote Hosts image

puRe1337 commented 6 months ago

I have also noticed that if you enter e.g. 'relay' under 'Outbound -> Routing -> Next hop', no more mails can be received (if the relay server needs sender authentication), as these are also sent to the relay server. Is this intended?

Screenshot

mdecimus commented 6 months ago

This looks like an issue with Brevo, if you look at the logs you provided all three messages were delivered to Brevo:

smtp::outbound::session: context="rcpt" event="delivered" rcpt="xxxx@yahoo.com" mx="smtp-relay.brevo.com" response=Delivered: Code: 250, Enhanced code: 2.0.0, Message: I'll make sure <xxxx@yahoo.com> gets this
Thu, 25 Apr 2024 12:31:51   
INFO    
smtp::outbound::session: context="rcpt" event="delivered" rcpt="xxxx@outlook.com" mx="smtp-relay.brevo.com" response=Delivered: Code: 250, Enhanced code: 2.0.0, Message: I'll make sure <xxxx@outlook.com> gets this
Thu, 25 Apr 2024 12:31:50   
INFO    
smtp::outbound::session: context="rcpt" event="delivered" rcpt="xxxx@gmail.com" mx="smtp-relay.brevo.com" response=Delivered: Code: 250, Enhanced code: 2.0.0, Message: I'll make sure <xxxx@gmail.com> gets this
Thu, 25 Apr 2024 12:31:48   
INFO    

It is Brevo's responsibility to deliver the message to the right account.

alucryd commented 5 months ago

@puRe1337 Noticing the same thing here, did you find a way around it?

mdecimus commented 5 months ago

This is because you probably removed the rule routing local messages, try with this:

[queue.outbound]
next-hop = [ { if = "is_local_domain('', rcpt_domain)", then = "'local'" }, 
             { else = "'relay'" } ]
PaddyPat commented 2 months ago

could you post a hint, hotwo make a next-hop check to use only brevo/sendinblue only, if recipient is hotmail or microsoft or google (use relay only for special recipients)? like postfix: transport: /.*@hotmail.*/i relay:[smtp-relay.sendinblue.com]:587

europacafe commented 2 months ago

I believe you can add another "if" expression to the Next-Hop for special recipients. See the example here: https://stalw.art/docs/configuration/expressions/overview it could be at the "Next-Hop" expression, add another if after if "is_local_domain"

PaddyPat commented 2 months ago

thx but it doesn't work.. I cant save this expression Invalid variable or function name "rcpt"

europacafe commented 2 months ago

Have you tried as below? (if) is_local_domain('*', rcpt_domain) ==> 'local' (if) recipients = "xxx@gmail.com" || "yyy@hotmail.com" ==> 'sendinbluerouteid' (else) 'false'

image

When using relay smtp, please don't forget to disable DANE and MTA-STS image

PaddyPat commented 2 months ago

Sorry, with your string it sends all mails to relay, not only mails to address or domain x …

europacafe commented 2 months ago

(if) recipients = "xxx@gmail.com" || "yyy@hotmail.com" ==> 'sendinbluerouteid'

sorry you need parenthesis (if) recipients = ('xxx@gmail.com' || 'yyy@hotmail.com') ==> 'sendinbluerouteid' if you want the whole domain (if) rcpt_domain = ('gmail.com' || 'hotmail.com') ==>'sendinbluerouteid'

for 'recipients' variable, according to the online documentation, it should accept an array, e.g. ['xxx@gmail.com', 'yyy@hotmail.com'], but it doesn't work even if it passes the config validation and can be saved and reloaded.

PaddyPat commented 2 months ago

Thanks, this was the mistake 👍