Opened 5 years ago
Closed 5 years ago
#1936 closed defect (invalid)
'set_real_ip_from' in location section is not processed before REWRITE_PHASE
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | nginx-module | Version: | 1.17.x |
Keywords: | realip_module | Cc: | |
uname -a: | |||
nginx -V: | 1.17.8 |
Description (last modified by )
For the confuguration
server { listen 1024 proxy_protocol; location / { real_ip_header proxy_protocol; set_real_ip_from 0.0.0.0/0; return 200 remote_addr=$remote_addr; } }
response on request
echo -en "PROXY TCP4 4.4.4.4 5.5.5.5 1234 80\r\nGET / \n\n" | nc -q-1 0 1024
is
remote_addr=127.0.0.1
It is wrong address. The same in the access log.
Moving real_ip* directives into the server section or removing 'return' provide the correct result.
server { listen 1024 proxy_protocol; real_ip_header proxy_protocol; set_real_ip_from 0.0.0.0/0; location / { return 200 remote_addr=$remote_addr; } }
remote_addr=4.4.4.4
This happens due to missing call of ngx_http_realip_handler() with config of a location on PREACCESS_PHASE.
Because 'return' works off on REWRITE_PHASE.
Change History (5)
comment:1 by , 5 years ago
Description: | modified (diff) |
---|
comment:2 by , 5 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
comment:3 by , 5 years ago
If something satisfies the way is was supposed to be written, it doesn't get right because of this.
NGINX has an extremely controversial behavior here.
It is a modules conflict or a flaw of architecture/documentation (inconsistency of phase handlers planning).
The realip module, if specified in a particular location, starts working only if a particular location is chosen
Particular location is chosen, because 'return' directive inside it does execute.
And this is always last chosen location, because there are no redirection is specified for it.
configuration is only considered to be chosen after processing by the rewrite module
The presented case above have simple unambiguous location config.
But it is processed incorrectly due to flaw of consistent execution of rewrite module's directives with directives from other modules placed in the same location.
And there is no right place for a correct processing it now: nor on the same phase (there are no such phase), nor on the different phases (there are no appropriate phases).
Obviously, it is incorrect to declare an ability to use 'realip' directives in the location if they have conflicts with location handling directives.
In your particular example request processing is stopped by the return directive of the rewrite module before this happens.
Exactly. And this ticket insists that it is bug of nginx, which is possible to fix by changing the way it treats with locations.
comment:4 by , 5 years ago
Resolution: | invalid |
---|---|
Status: | closed → reopened |
It would be right to change the Summary of the ticket to
Wrong processing of rewrite-module's directives inside location leads to incorrect processing of 'set_real_ip_from' there
comment:5 by , 5 years ago
Resolution: | → invalid |
---|---|
Status: | reopened → closed |
As already explained above, the behaviour you observe is in line with the current design. While it may be counter-intuitive, it is not a bug.
The realip module, if used only in a particular location, changes the IP address once the location is finally chosen, and this happens after the rewrite module instructions are executed, because these instructions is a logical part of the process of choosing a location. As such, rewrite module instructions will see the original IP address, not yet changed by the realip module.
If you think you can came up with a better design, which will result in more intuitive processing, don't hesitate to submit a patch.
The realip module, if specified in a particular location, starts working only if a particular location is chosen. The rewrite module (and the
return
directive as a part of it) is designed to conditionally select configurations, and therefore a configuration is only considered to be chosen after processing by the rewrite module. In your particular example request processing is stopped by thereturn
directive of the rewrite module before this happens.If you want the realip module to apply to all requests, including ones where a configuration wasn't yet chosen, and to all phases of request processing after reading the request, including processing by the rewrite module, configure the realip module at the server level.