#1589 closed defect (duplicate)
realip module's effective level
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | other | Version: | 1.13.x |
Keywords: | Cc: | ||
uname -a: | 3.10.0 | ||
nginx -V: | 1.13.6 |
Description
http {
real_ip_header X-Real-IP;
set_real_ip_from 127.0.0.1;
server {
listen 8000;
real_ip_header X-Forwarded-For;
location / {
....
}
}
}
local test:
#curl http://127.0.0.1:8000/
$remote_addr = "127.0.0.1"
#curl http://127.0.0.1:8000/ -H "X-Forwarder-For: 2.2.2.2" -H "X-Real-IP: 1.1.1.1"
$remote_addr = "1.1.1.1"
tracing the source code:
ngx_http_realip_handler is setted in POST_READ and PREACCESS phase.
if POST_READ phase meeting the conditions takes effect, it will call ngx_http_set_ctx(r, ctx, ngx_http_realip_module).
so that PREACCESS phase will skip.
I wonder to know why not location level takes effect in higher priority?
It's different from the other module's design idea of nginx.
Change History (5)
comment:1 by , 6 years ago
Resolution: | → duplicate |
---|---|
Status: | new → closed |
comment:2 by , 6 years ago
Full configuration:
http {
real_ip_header X-Real-IP;
set_real_ip_from 127.0.0.1;
log_format main '$remote_addr';
access_log logs/access.log main;
server {
listen 8000;
real_ip_header X-Forwarded-For;
location / {
content_by_lua '
ngx.say(ngx.var.remote_addr)
';
#or view access log
#proxy_pass http://127.0.0.1:9000;
}
}
}
follow-up: 4 comment:3 by , 6 years ago
Resolution: | duplicate |
---|---|
Status: | closed → reopened |
I think you don't get my point.
#curl http://127.0.0.1:8000/ -H "X-Forwarded-For: 2.2.2.2" -H "X-Real-IP: 1.1.1.1"
if the location level has higher priority, the $remote_addr should be 2.2.2.2, but the test result is 1.1.1.1.
the reason is that ngx_http_realip_handler is setted in POST_READ and PREACCESS phase.
if POST_READ phase meeting the conditions takes effect, it will call ngx_http_set_ctx(r, ctx, ngx_http_realip_module).
so that PREACCESS phase of the realip module will skip.
my question is:
I wonder to know why not location level takes effect in higher priority?
It's different from the other module's design idea of nginx.
comment:4 by , 6 years ago
Resolution: | → duplicate |
---|---|
Status: | reopened → closed |
Replying to cjhust@…:
#curl http://127.0.0.1:8000/ -H "X-Forwarded-For: 2.2.2.2" -H "X-Real-IP: 1.1.1.1"
if the location level has higher priority, the $remote_addr should be 2.2.2.2, but the test result is 1.1.1.1.
Have you tested it with the exact configuration provided? The result is 2.2.2.2
:
$ curl http://127.0.0.1:8000/ -H "X-Forwarded-For: 2.2.2.2" -H "X-Real-IP: 1.1.1.1" 2.2.2.2
As you were already told twice, your results do not match configuration you claim.
[...]
my question is:
I wonder to know why not location level takes effect in higher priority?
It's different from the other module's design idea of nginx.
As previously explained, there are no location-level handling in the configuration provided. Location level handling can indeed conflict with server-level handling, but this will happen in different configurations. For example, consider a configuration like this:
server { listen 8080; set_real_ip_from 127.0.0.1; real_ip_header X-Real-IP; location / { real_ip_header X-Forwarded-For; proxy_pass http://127.0.0.1:8081; proxy_set_header X-Remote-Addr $remote_addr; } } server { listen 8081; return 200 $http_x_remote_addr\n; }
In such a configuration the result will be indeed 1.1.1.1
- that is, nginx will use X-Real-IP
header as configured at the server level, but not X-Forwarded-For, as configured at the location level. That is because realip processing, when configured, happens as early as possible, in the POST_READ phase. This allows to assign correct IP before doing anything with the request, in particular - before executing rewrite directives and looking for a matching location. When a matching location is found, it is too late to re-apply realip processing with different settings (while technically it can, this will introduce a lot of confusion). This is generally in line with what nginx does in other similar cases - for example, it won't re-apply limit_req
and limit_conn
limits if it already applied some.
Summing the above, location-specific realip processing can only happen when nginx is not configured to do realip processing at the server level or this processing hasn't changed the address.
In either case, all of the above is completely irrelevant to the problem you claim. With the configuration you've provided, only POST_READ processing will happen, and no location-specific processing is expected since there is no location-specific realip configuration.
comment:5 by , 6 years ago
Thanks for your reply.
I accept the explaination:
That is because realip processing, when configured, happens as early as possible, in the POST_READ phase.
I think the PREACCESS phase of the realip module seems to be a bit superfluous.
For example the limit_req module is setted in the PREACCESS phase also, if the configuration is just like below:
http {
limit_req_zone $remote_addr zone=one:1m ...;
location / {
realip_ip_header X-Real-IP;
set_real_ip_frome xxx;
limit_req zone=one ...;
}
}
The limiting result will be incorrect because the limit_req module execute handler firstly.
Meantime it's so easy to take for granted that the location level has higher priority.
Thank you once again.
The realip handling in the PREACCESS phase is for location-specific realip handling. It works when you configure realip handling in a particular location. With the provided configuration only POST_READ phase handling will be used, so this is completely irrelevant to the configuration you are working with.
Test results provided indicate that requests are simply handled in a different server{} block. As already suggested in ticket #1588, if you need further help, please provide full configuration you are testing with.
Closing this as a duplicate of #1588.