Skip to content

Allow customizing the real_ip_header directive when proxy_protocol is enabled #11623

@bossm8

Description

@bossm8

It should be possible to override the hardcoded value of real_ip_header even when proxy_protocol is used as this is an invalid setting for deployments where multiple proxies are involved.

Our current setup looks like this:

HAProxy - (via http) -> Octavia LB - (via proxy-protocol) -> ingress-nginx

The HAProxy already sets the X-Forwarded-For value to the real client IP address but there is no way to use this value when the proxy-protocol is enabled (in Helm: controller.config.use-proxy-protocol: "true") for the communication between the Octavia LB and the ingress-nginx because the nginx.tmpl hardcodes the value for the real_ip_header (source):

    {{/* Enable the real_ip module only if we use either X-Forwarded headers or Proxy Protocol. */}}
    {{/* we use the value of the real IP for the geo_ip module */}}
    {{ if or (or $cfg.UseForwardedHeaders $cfg.UseProxyProtocol) $cfg.EnableRealIP }}
    {{ if $cfg.UseProxyProtocol }}
    real_ip_header      proxy_protocol;
    {{ else }}
    real_ip_header      {{ $cfg.ForwardedForHeader }};
    {{ end }}

The only IP addresses which are being logged by the ingress access logs are now the ones of our HAProxies instead of the client IP addresses. We tried various configurations but were not able to get ingress-nginx to use the correct address except when we started it using a custom template with the following adjustments to the template above:

    {{/* Enable the real_ip module only if we use either X-Forwarded headers or Proxy Protocol. */}}
    {{/* we use the value of the real IP for the geo_ip module */}}
    {{ if or (or $cfg.UseForwardedHeaders $cfg.UseProxyProtocol) $cfg.EnableRealIP }}
    {{ if $cfg.UseProxyProtocol }}
-   real_ip_header      proxy_protocol;
+   real_ip_header      {{ or $cfg.ForwardedForHeader "proxy_protocol" }};
    {{ else }}
    real_ip_header      {{ $cfg.ForwardedForHeader }};
    {{ end }}

Now this would probably require a new variable as ForwardedForHeader always defaults to X-Forwarded-For(doc). But using this approach I was able to finally get the real client IP address logged by the ingress.

Is there currently another issue associated with this?

Could not find any.

Does it require a particular kubernetes version?

No (see Helm chart)

Additional Refs:

Is it possible to get a configuration option allowing overriding the hardcoded value as shown above. Because the approach with the custom template is just a hack which is not really usable in production as we would always need to fetch the template when updating the chart version.

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/featureCategorizes issue or PR as related to a new feature.lifecycle/frozenIndicates that an issue or PR should not be auto-closed due to staleness.needs-priorityneeds-triageIndicates an issue or PR lacks a `triage/foo` label and requires one.

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions