Skip to content

set_real_ip_from ignored with PROXY protocol for HTTP #4429

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
TvdW opened this issue Aug 11, 2019 · 2 comments · Fixed by #4557
Closed

set_real_ip_from ignored with PROXY protocol for HTTP #4429

TvdW opened this issue Aug 11, 2019 · 2 comments · Fixed by #4557

Comments

@TvdW
Copy link

TvdW commented Aug 11, 2019

NGINX Ingress controller version:

0.25.0

Kubernetes version (use kubectl version):

1.13.9

What happened:

DigitalOcean's k8s load balancer uses nodePort-style services which are then load-balanced by their custom setup which can optionally speak PROXY protocol. These are always on the local 10.0.0.0/8 range, but the ports are publicly exposed, so it's important for nginx to have set_real_ip_from configured correctly. However, the X-Real-IP seen by the application (and in nginx access logs) does not perform the source IP validation correctly.

What you expected to happen:

Requests using PROXY protocol coming from IP addresses that are not whitelisted in set_real_ip_from should not have their IP addresses taken from the handshake.

How to reproduce it (as minimally and precisely as possible):

Regular ingress-nginx setup, w/ configmap:

use-proxy-protocol: "true"
proxy-real-ip-cidr: 1.2.3.4/32

Then make a request with PROXY protocol (curl --haproxy-protocol http://<nginx>, do a request directly to the pod) and see which IP address shows up in the logs. Unless your IP address is actually 1.2.3.4, it should list your IP address, rather than what curl decided your address is.

Anything else we need to know:

The nginx ingress controller spits out this (correct) config:

real_ip_header      proxy_protocol;
real_ip_recursive   on;
set_real_ip_from    10.0.0.0/8;

However, this is where it goes wrong:

# The following is a sneaky way to do "set $the_real_ip $remote_addr"
# Needed because using set is not allowed outside server blocks.
map '' $the_real_ip {
# Get IP address from Proxy Protocol
default          $proxy_protocol_addr;
}

proxy_protocol_addr is the raw value, pre-validation. nginx' realip module then takes this and puts the validated value in remote_addr. Since the template here uses proxy_protocol_addr instead of remote_addr, it's sending the raw value whether it passed validation or not.

@TvdW TvdW changed the title set_real_ip_from ignored with PROXY protocol set_real_ip_from ignored with PROXY protocol for HTTP Aug 11, 2019
@bzon
Copy link

bzon commented Oct 3, 2019

@TvdW What should be the replacement? We are using the $the_real_ip in our log format.

@ElvinEfendi
Copy link
Member

$remote_addr is the replacement

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants