#901 Support PROXY protocol for usage with HaProxy

Reporter Thomas L.
Owner Nobody
Stars ★★★★ (8)  
  • Status-New
  • Type-Enhancement
  • Priority-Medium
  1. Thomas L. on

    If you have Prosody running behind a NAT or TCP proxy for high availability or load balancing, Prosody can't see the real IP addresses of connecting clients and servers. Therefore Prosody can't block IP-addresses: Brute force attacks cannot be handled, and registration attempts cannot be limited. Fortunately there is a solution to it: HAProxy implements the PROXY protocol, which transmits a client's IP address to the application endpoint, e.g. a mail server or another application server. Prosody does not support the PROXY protocol yet. Let's implement that! :-)

  2. Thomas L. on

    More information on the PROXY protocol: https://www.haproxy.com/blog/haproxy/proxy-protocol/

  3. MattJ on

    Coincidentally I was looking at this a few days ago. It could certainly be implemented in a plugin :)

  4. Thomas L. on

    Just wanted to add a bounty to this issue on Bountysource, but Bountysource seems to support GitHub only :-( https://www.bountysource.com/issues/44710850-901-support-proxy-protocol-for-usage-with-haproxy-open-prosody-im-issue-tracker Unfortunately I can't develop such a module myself or contribute to the code, as I'm not a Lua expert. Are you interested in developing a module for PROXY support, MattJ? :-) Or is there any chance to get someone else motivated regarding this topic?

  5. Lunar on

    Anyone still like this idea? :(

  6. MattJ on

    Yes, I still like the idea, but haven't had time to implement it with other things taking priority. As mentioned in a previous comment, it shouldn't be too hard to implement in a plugin.

  7. Pascal Mathis on

    As I am already familiar with the PROXY protocol and implemented it within other software, I started developing this feature for Prosody to resolve/close this issue. However I can not find a way to implement this as a plugin as suggested by MattJ. The PROXY protocol has to be processed before any other action happens, so in case of legacy-SSL the PROXYv1/v2 message has to be parsed -before- the SSL/TLS handshake happens. This is impossible to do with the current implementation of the network listeners, where "onconnect" gets called after the handshake has happened. Additionally, I can not find an easy way to pass the real IP address to the actual services which have to process the connection after the PROXY protocol has been handled. As there is no session and I would prefer a service-independent implementation, I suggest spoofing/replacing conn:ip(). This is again not possible within a plugin though, unless I would wrap all listener methods and replace/spoof the "conn" object each time - or am I missing something? This would still not solve the SSL-handshake issue though, so that's a partial solution for all non-legacy services which use plaintext or StartTLS. In my opinion this should be directly implemented in the net/server_XXX modules instead, possibly with a generic implementation/interface to not have the same logic several times? Last but not least, implementing this would require adding a new service_info property (e.g. use_proxy_protocol) as the proxy protocol does not permit "guessing" if the proxy protocol is being used - instead separate ports/listeners should be used. Would be happy to hear some thoughts from more experienced Prosody developers.

  8. Pascal Mathis on

    I have published a module implementing support for both PROXY protocol versions about an hour ago, which can be found within the official community modules repository by the name mod_net_proxy: https://modules.prosody.im/mod_net_proxy.html Except for the limitation that ports with an automatic SSL-handshake, e.g. legacy_ssl which does not use StartTLS, are currently unsupported, every other service using either plaintext or StartTLS can now be put behind a TCP proxy supporting the PROXY protocol. First tests in my own environments turned out to be successful, but I would be grateful for any additional feedback. Thanks in advance for giving it a try, feel free to ask in case there are any issues and enjoy!

  9. ge0rg on

    Thanks for implementing that! > Please do not expose any ports offering PROXY protocol to the internet Unfortunately, I don't have firewall permissions on the machine running prosody. Could you please add a proxy_allowed {} option where the user needs to explicitly configure the whitelisted IPs from which PROXY protocol is accepted? That would also be a good "security in depth" measure.

New comment