19

Is there a way to get the origin IP of the user from the HTTP load balancing w/ GCloud? We are currently using just Network Load Balancing, and are needing to move to a cross region balancer although we need to user's IP for compliance and logging.

Does it pass in a header or something along those lines?

Thanks ~Z

Zeehad
  • 1,012
  • 1
  • 9
  • 11
keoir
  • 429
  • 1
  • 5
  • 12

5 Answers5

20

The documentation (https://cloud.google.com/compute/docs/load-balancing/http/) says it's the first IP address of the X-Forwarded-For header.

  X-Forwarded-For: <client IP(s)>, <global forwarding rule external IP>
Matt S.
  • 7,651
  • 3
  • 19
  • 12
  • 4
    Just a note that this header can be spoofed if the user sends a request with `X-Forwarded-For` already set. It would be great if GCP can specify an option to create a `X-Real-IP` header that overrides any request header with this name, only setting the IP of the request so it cannot be spoofed.. – Tony Jan 23 '17 at 18:05
  • 1
    Even if that were the case, a proxy upstream could set X-F-F to a spoofed address. You are correct that this header as a security mechanism is not fully sound. – Matt S. Jan 24 '17 at 19:41
  • 2
    I mean in that case, GCP can program the LB so that it sets the source IP from the actual incoming request, instead of reading it from the request's header (and overwriting existing `X-Real-IP` header if the client has it set). – Tony Jan 25 '17 at 17:22
  • 1
    @Tony, actually what happens is that all cloud service providers keep whatever is in the header, add the connection IP + the load balancer's IP at the end. See cakraww's answer below – Nikolay Dimitrov Jan 03 '19 at 04:41
16

If you are sure that you do not run any other proxy (that append additional IPs into X-Forwarded-For) behind Google Cloud Balancing, you can get the second to last IP from X-Forwarded-For as immediate client IP. Or even if you have some proxies but know the exact number of additional IPs that will be appended, you can also add those into account.

From https://cloud.google.com/compute/docs/load-balancing/http/#components:

X-Forwarded-For: <unverified IP(s)>, <immediate client IP>, <global forwarding rule external IP>, <proxies running in GCP> (requests only)

Only the <immediate client IP> and <global forwarding rule external IP> entries are provided by the load balancer. All other entries in the list are passed along without verification.

IPs that comes before immediate client IP could be spoofed IPs or IPs coming from client proxies. Even if the client spoofs X-Forwarded-For header, the load balancer still appends the actual IP that hits the load balancer.

Community
  • 1
  • 1
cakraww
  • 2,493
  • 28
  • 30
3

Ok, so after digging though headers and other things I found the following header that is passing the origin IP and thee IP for the user.

$_SERVER['HTTP_X_FORWARDED_FOR']

You will need to split it by the ',' and take the first part of the string. This is the user IP, that is being pushed by the Google Cloud HTTP Balancer.

serv-inc
  • 35,772
  • 9
  • 166
  • 188
keoir
  • 429
  • 1
  • 5
  • 12
1

Based on HTTP_X_FORWARDED_FOR header, a nice Nginx rule to split the IPs chain :

set $realip $remote_addr;
if ($http_x_forwarded_for ~ "^(\d+\.\d+\.\d+\.\d+)") {
  set $realip $1;
}
fastcgi_param REMOTE_ADDR $realip;

Paste it after include fastcgi_params; directive to be effective.

If you're using Cloudflare, you can get original client IP from HTTP_CF_CONNECTING_IP.

Takman
  • 1,028
  • 10
  • 13
1

I found this article https://geko.cloud/forward-real-ip-to-a-nginx-behind-a-gcp-load-balancer/

You can whitelist/ignore IPs that are known to GCP like the static ip needed for registering the loadbalancer

set_real_ip_from 36.129.221.25/32; // LB Public IP address
set_real_ip_from 130.211.0.0/22; // Private IP range for GCP Load Balancers
set_real_ip_from 35.191.0.0/16; //Private IP range for GCP Load Balancers
real_ip_header X-Forwarded-For;
real_ip_recursive on;
Ryan Clemente
  • 131
  • 1
  • 5