[PATCH] Mail: added PROXY PROTOCOL support

Murad Mamedov mail at muradm.net
Mon Jan 18 18:08:36 UTC 2021


Yes as security requirement one has to think about where do you get
PROXY header from. HAProxy clearly states in spec that, if receiver is
configured to have PROXY header, it has to expect it, if such header is
missing the connection should be closed immediatly. When such
configuration is introduced, one generally puts and application behind a
load balancer providing PROXY header. I.e. the PROXY header provider
is not an any system in the wild. As being part of network
configuration, generally it should be handled by the network
configuration. PROXY header introduced in the first place to mitigate
the network routing issues. For network configuration it is as simple as
having a private network between PROXY header provider and consumer
(most common case I beleive), at worst iptables rules. I.e. one, who
introduces PROXY header support, naturally thinks why it is done, and
what are the consequences.

On the other hand, for dynamic environments like running in Kubernetes,
Docker Swarm, a) tons of security is outsourced to them already; b) it
is realy hard to know addresses in advance; c) even if it is some how
queried, there is no precondition that dynamic infrastructure will not
change at any time (imagine PROXY header provider service is upgraded,
as result all containers recreated, with new IP addresses, even
networks, do one has to also update/reconfigure/restart all other parts
of application? This is definetly far from microservices approach :) ).

Does above make sense?

If not, considering all of the above, I can add support as following:
1) I think that "real_ip thing" can be implemented as an optional
feature. I.e. if "set_real_ip_from" is present, then it has to be
consulted, other wise just let proxy_protocol do its thing.
2) ngx_*_realip_module is very heavy, it also requires ngx_*_variables.
If implemented in mail, I see it as simple array directive of addresses
checked as described in 1) above. I.e. without variables etc.

On 2021.01.18 19:01, Maxim Dounin wrote:
>On Sat, Jan 16, 2021 at 07:38:49PM +0300, Murad Mamedov wrote:
>> First of all, ignore patch in first mail, I don't use mercurial on
>> daily basis, and my neomutt screwed the patch. Second mail in thread
>> contains just patch and it seems to be correct.
>> I wanted to address few other things on the subject. I started my way
>> from
>> http://mailman.nginx.org/pipermail/nginx-devel/2016-November/009083.html,
>> however decisions done there I found incorrect. Author tried to jump
>> right into XCLIENT from PROXY PROTOCOL. In proposed implementation proxy
>> protocol is handled in the begining of connections. Since XCLIENT gets
>> its address from ngx_connection_s, it will get automatically downstream
>> provided address of client.
>> In the same thread, there was questions on how to deal with
>> "real_ip_header" and "set_real_ip_from". As I mentioned in the original
>> description to the patch, one may need these in case of HTTP protocol,
>> which is very flexible, with tons of applications behind that may demand
>> presense of real ip address in different places/headers. For ancient mail
>> protocols, it is not the case. They are very strict, very few
>> applications that implement it, probably Postfix, Exim and Dovecot be
>> the only practical implementations. And they do support proxy protocol
>> out of the box. So I could not find real reason to apply "real_ip"
>> thing. With proposed implementation, it just worked out of the box, with
>> minimum configuration. The only thing which could be added if need is
>> the overriding of "destination address" of proxy protocol (i.e. address
>> which client reached). For now I didn't see where it could be useful in
>> mentioned above mail applications. Client address, yes, we do pass,
>> server address ¯\_(ツ)_/¯, who cares.
>The main problem the "real_ip thing" is expected to address is
>that whithout set_real_ip_from restricted set of addresses to
>accept IP address from you are open to IP spoofing.
>Most recent relevant discussion about "why one should never trust
>X-Forwarded-For addresses and what to do with the fact that many
>don't understand it" can be found in the thread here:
>Mail proxying is indeed much simplier than http, yet the question
>is still here: how to ensure that "listen ... proxy_protocol;" is
>only configured to accept client IP addresses from trusted
>Blindly assuming that anyone who used "listen ... proxy_protocol;"
>in the configuration took care and restricted access to the
>listening socket in question on the network level might not be a
>good idea.  Especially given it works differently in both http and
>stream modules.  Rather, I would like to see it equivalent to how
>it is implemented in the stream module with "set_real_ip_from"
>Maxim Dounin
>nginx-devel mailing list
>nginx-devel at nginx.org


More information about the nginx-devel mailing list