Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to disable open-relay behaviour ? #219

Closed
radsto opened this issue Dec 29, 2023 · 11 comments
Closed

How to disable open-relay behaviour ? #219

radsto opened this issue Dec 29, 2023 · 11 comments

Comments

@radsto
Copy link

radsto commented Dec 29, 2023

Hi, thanks for your great piece of software !

Actually if we expose the SMTP server on the Internet without authentication, it will show up as an open relay (tested with Wormly for example).

Even though the relay is configured to allow only specific domains through the regex set in recipient-allowlist, we should be able to reject clients that request RCPT TO that do not match the domain we want MailPit to act for.

Is there any mean to achieve this and therefore not appear as an open relay all over the web ?

Thanks very much for your hints and have a nice day !

Radu Stoichita

@axllent
Copy link
Owner

axllent commented Dec 29, 2023

Hi @radsto, I'm glad you like Mailpit! I do not think there is currently a solution to achieve what you are describing. Can you please explain in more detail what you are trying to achieve here exactly?

@radsto
Copy link
Author

radsto commented Jan 2, 2024

Hi @axllent, thanks very much for your quick reply. Wish you all the best for the new year.

Let me explain to you more in details the situation :

  1. We actually use Yopmail as a public disposable e-mail service mostly to proof our account activation e-mails.
  2. Yopmail does not seem to have an APi which we can use for programatically retrieve the said e-mails (for example, in our E2E tests)
  3. Therefore, I have deployed MailPit on our dev infrastructure to replace the Yopmail service with something managed internally.

Now :

  • The server is exposed to public without restriction on Internet on domain mp.digikare.dev
  • There are several mail servers (ours & third-party) that must be able to connect to MailPit to deliver our transactional e-mails
  • We have no control over who will send the e-mails therefore SMTP Auth is not an option

What we want :

  • The server should only accept e-mails for the e-mails ending in mp.digikare.dev
  • Any other e-mail should be rejected and not even enter the inbox

What I see / did :

  • Using a site like https://tools.appriver.com/OpenRelay.aspx we can clearly see that any recipient is accepted (appears as an open relay)
  • Although release is controlled by the whitelist pattern which forbids forwarding any other e-mail domain, the server still processes incoming e-mails unrelated to the said domain and shows them in the inbox.

The server is quite new and is not currently filled with garbage but I am afraid that it will be some time discovered and might be used by bots wrongly believing it is an open relay, trying to send zillions of mails to the outside world and cluttering our MailPit inbox with unwanted garbage.

Would it be easy / possible to implement a regex whitelist on the incoming connection at the RCPT TO command and deny delivery ?

image

Thanks very much for your insights, I could work on a PR for that if you believe it is not too complicated to develop.

With you a great day,

Radu Stoichita

@axllent
Copy link
Owner

axllent commented Jan 2, 2024

Thanks for the explanation @radsto - that makes a lot more sense now. As you have discovered, at the moment anyone, including spam bots can send to your Mailpit instance. I think that implementing an "allow list" is technically a feasible option, though I will need to sleep on this (give it more thought) before giving you a definitive answer.

I think there is an existing alternative solution in the meantime though ~ basically you can just leave Mailpit open. By default Mailpit will only keep the latest 500 messages (you can configure this to anything you like), so it's unlikely your server will fill up with zillions of emails as they will get auto-deleted. Spam bots (from experience) will not waste precious resources sending mail into a black hole - they are quite used to honeypots and will first attempt a few emails to confirm emails do actually get delivered before bombing your server with large loads. Very soon they will discover nothing is delivered (do not enable relaying!), give up and move on. The "issue" is you will get regular spam bots probing, and yes, you will get a fair bit of junk mail as each one tests. The API allows you to filter messages, so, provided your automation is done fairly soon after an email your want is delivered to Mailpit (so there aren't 500 spam messages delivered after yours before you check the API), then I see this "solution" working. I admit it's not a great solution, and only allowing emails matching certain addresses or domains is a much nicer option, but there are a few complications I need to consider first before deciding whether or not to implement this.

@radsto
Copy link
Author

radsto commented Jan 2, 2024

Thanks for your detailed reply, I already followed your recommendation as a workaround, for now there is not much unwanted clutter and relaying is disabled by with a regex filter and by pointing outgoing SMTP to itself this way :

relay.yaml: |
    host: 127.0.0.1
    port: 1025
    starttls: false
    allow-insecure: true
    auth: none
    recipient-allowlist: '@(.*\.|)(digikare|orthense|renacot)\.(dev|com|org)$'

I will patiently wait until you have thought out this usefule feature.

Thanks again for your dedication.

@axllent
Copy link
Owner

axllent commented Jan 2, 2024

That's great. The good news is I have just found a way to "intercept" the incoming message and reject it via the SMTPD package which Mailpit uses, so filtering by an "allow list" is technically possible 👍 The only potential issue I have is that I can only return an error message once the full message is sent (after the final .), whereas I think, depending on the error, it is supposed to come directly after the RCPT TO:<test@example.com> which isn't possible.

In the meantime, maybe you can help me (I'm just about to go to bed) - do you know what a suitable generic SMTP error response should be from the server? I know different servers respond slightly differently (my understanding is that SMTP error messages can really be anything, but it's the first 3 numbers in the response which actually means something to the client, not so much the message that follows), but so far I have found 551 relay not permitted, or 550 mailbox unavailable.

@radsto
Copy link
Author

radsto commented Jan 2, 2024

Wow great ! For the response code, if you implement target recipient regex filtering, I think you could return :

553 Requested action not taken: mailbox name not allowed

Source : https://www.iana.org/assignments/smtp-enhanced-status-codes/smtp-enhanced-status-codes.xhtml

image

smtp.gmail.com returns 530 for the open relay test (but it stops straight at sender not recipient):

image

image

@axllent
Copy link
Owner

axllent commented Jan 2, 2024

Awesome, thanks! I was actually mistaken, mhale/smtpd (the SMTPD package) does actually have built-in support for rejecting the attempt right at the RCPT TO: command (which is where this should happen) 🎉 The response is hardcoded to 550 5.1.0 Requested action not taken: mailbox unavailable which seems perfectly acceptable to me too, so I'll use this.

axllent added a commit that referenced this issue Jan 2, 2024
@axllent
Copy link
Owner

axllent commented Jan 3, 2024

@radsto I have just released this feature in v1.12.1 - Please test and confirm this does what you expect?

@radsto
Copy link
Author

radsto commented Jan 3, 2024

Hi Ralph ! Awesome work, I will check this out this morning and come back to you.

@radsto
Copy link
Author

radsto commented Jan 3, 2024

Hi @axllent, that works perfectly !

I upgraded the docker image to 1.12.1 and added the regex setting. Logs are as follows :

image

Thanks you so much for providing me with this feature and I am really impressed by the outstanding dedication to the follow-up of this project ❤️ !

@radsto radsto closed this as completed Jan 3, 2024
@axllent
Copy link
Owner

axllent commented Jan 3, 2024

You're very welcome, and thank you for the testing and feedback! I'll be curious to know (after some time) how many spam bot attempts you get in future (once they detect your IP and post 25) - assuming you remember of course, and of course how this solution works for you with your intended implementation :) As you probably noticed, I set the rejected message logs as a warning so they should always show in the logs (without turning on debugging).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants