How to Forward Client's request IP

Hi,

This is a typical behavior/drawback of many reverse-proxies and load-balancers. Luckily for you, and as one would expect, there exist ways to circumvent them!

Retrieving the client IP in your API

First and foremost, Kong will set the X-Forwarded-For header for you since 0.11.0. You can use its value in your upstream services to retrieve the client IP. This is, I believe, the answer you are looking for.

But let’s take a deeper dive here, because there are other important areas around this topic to cover before implementing Kong in a production-ready environment.

When Kong is itself behind a load-balancer

Now, what to do when Kong’s client is a previous load-balancer/reverse-proxy hop in the HTTP chain?

The most obvious way to address this is to rely on the ngx_http_realip_module module from NGINX which is bundled in Kong’s official distribution packages. This module properly parses the X-Forwarded-For header according to rules you can configure yourself.

Kong exposes various configuration properties (trusted_ips, real_ip_header, and real_ip_recursive) that abstract the NGINX module’s directives of the same name to help you configure it in such a way so that your upstream services can retrieve the client’s address.

If your Kong instance is properly configured, it will be able to retrieve the client IP, as well as each individual IP from every previous HTTP hop between the client and itself. It will then add its own IP to the X-Forwarded-For header, and proxy the request to your upstream service. Your service is thus able to retrieve the same information as well.

Retrieving the client IP in plugins

The ngx_http_realip_module will update the $remote_addr NGINX variable to contain the client IP (granting it is correctly configured and the request comes from a trusted IP). You can access this variable in Lua from ngx.var.remote_addr.

Beware, for existing plugins already access this value like so, such as the rate-limiting plugin. This means, if Kong/ngx_http_realip_module is badly configured, this plugin will rate-limit based on a previous load-balancer’s IP address, instead of each individual client’s IP address, leading to a drastically different behavior than expected!

Other client information transferred by Kong

Kong will also set other X-Forwarded-* headers:

  • X-Forwarded-Proto, containing the protocol used by the client (http or https).
  • X-Forwarded-Host, containing the original Host header sent by the client.
  • X-Forwarded-Port, containing the original port against which the client initially connected to.

If the request comes from a non-trusted IP (likely, directly from a client), Kong will set those values itself. However, if the request comes from a trusted IP and those headers are present, Kong will simply forward them upstream, untouched.

Support for PROXY protocol

Rather specific to HAProxy and ELBs, this protocol is natively supported by the ngx_http_realip_module’s real_ip_header directive. The Kong equivalent property of the same name can also receive the proxy_protocol value. This is documented in the Kong configuration file and reference.

Read more

9 Likes