ntfy icon indicating copy to clipboard operation
ntfy copied to clipboard

E-mail publishing with access-control enabled

Open huwylphi opened this issue 1 year ago • 5 comments

Hi, I've enabled access-control and since I host ntfy on a private instance, I set auth-default-access to deny-all and added one user with specific permission on a specific topic. I also enabled the e-mail publishing feature in order to publish message by sending an e-mail to the ntfy server. Now when sending an e-mail I get a "forbidden" error feedback. When I switch off the access-control, the e-mails are sent. So I guess this has something to do with authentication and ACL check. How does the ntfy smtp-server fetch the user/password sending the e-mail? I guess this is needed for checking permission against ACL? Until now I tried publishing message via e-mail:

  1. by passing the user vie the from address (left side of '@'). But if that would be correct, how to pass the password?
  2. with smtp authentication

but none these 2 ideas are working.

Any example of e-mail publishing with user authentication or any hints would be appreciated. Thanks.

huwylphi avatar Sep 30 '22 12:09 huwylphi

How does the ntfy smtp-server fetch the user/password sending the e-mail? I guess this is needed for checking permission against ACL?

Email sending to password-protected topics is currently not supported. I am not entirely sure how to facilitate the login without giving away the password over a potentially insecure channel.

It would have to be part of the e-mail address, otherwise you woudn't be able to hook it up to external tools. Something like (a) [email protected] or (b) [email protected] or just (c) [email protected].

Option (c) would be the nicest, and would also enable the use of Bearer tokens in the HTTP Auth header, but it would mean extra auth work to store and associate tokens. Option (a) would be the easiest to implement, but you'd have your password in the clear and give it to whoever is sending the email.

TLDR: It's not implemented. There's work to implement it, and I'd prioritize other issues before this as of today.

binwiederhier avatar Sep 30 '22 15:09 binwiederhier

And what about my idea number 2: using the SMTP Authentication? I mean if the ntfy SMTP server would support a well established authorization protocols, then the user and password could be sent when the client is authenticating to the SMTP server?

Otherwise as a workaround, would it be possible to run 2 instances of ntfy that shares the same cache.db file, where

  • one instance is exposed on the public network for default ACL protected subscribing/publishing and
  • one instance is only exposed in a private network where e-mail publishing is enabled without ACL feature and where clients needing to publish message by e-mail could access that private network ntfy instance

Would this workaround be technically possible (I'm using docker container) without corrupting the shared cache?

I understand your concerns about priorities and in any case thank you for your feedback.

huwylphi avatar Sep 30 '22 16:09 huwylphi

And what about my idea number 2: using the SMTP Authentication? I mean if the ntfy SMTP server would support a well established authorization protocols, then the user and password could be sent when the client is authenticating to the SMTP server?

AFAIK, SMTP auth is for sending email, not for receiving it. Plus, how'd you tell an external service (like healthchecks.io or statuspage.io) to use your SMTP auth. If it is possible, it's not practical in the real world.

Would this workaround be technically possible (I'm using docker container) without corrupting the shared cache?

I don't think SQLite would be happy with that. Feel free to try and report back though.

-- --> **I think the best (and most elegant) approach would be the token email address ([email protected]). I'm gonna leave this ticket open with the intent to eventually implement that.

binwiederhier avatar Oct 01 '22 19:10 binwiederhier

Ok thanks for that feedback.
In the mean time I realize that my idea of running a second instance of ntfy sharing the same cache might actually not work just because it would result to 2 end-points for the client (or reverse-proxy). Some messages would be published by one instance and some messages by the second instance. Furthermore the chances are high that this would mess up the SQLite DB...

So I had another workaround idea by just delegating the smtp-relay to some other service that would play a mail-to-http-post gateway.
I found thingless/mailglove that I use as test by "connecting" it to ntfy and send messages. This means one sends a mail to mailglove that will forward it as http post to ntfy that will publish the message.
But here the payload created by mailglove is just not "easy" readable (big json).
For such situation we would need some mapper feature in ntfy for mapping incoming mail data to some ntfy message field. But this might be out of scope of ntfy I guess.
Or we might find another self-hostable mail-to-http-post solution where the http post output could be configurable.

Otherwise regarding the token idea, how would that token be generated? Would this token change for each mail? otherwise if one would intercept the token, then the security would be broken, right?

huwylphi avatar Oct 05 '22 15:10 huwylphi

Would you be open to adding config settings in server.yml for a user / password to be used by the smtp server? E.g.:

smtp-publish-user: mail smtp-publish-password:

And then have the smtp server use that authentication locally when it calls the web server?

To be clear, this is a workaround / hack that allows an admin to decide that all incoming mail should be treated as the same user, but then the admin can at least put access restrictions on that one user.

If you're open to it, I'm happy to write the code and submit a PR.

tomheon avatar Nov 10 '22 04:11 tomheon