7

I am running a Ruby on Rails app (using Passenger in Nginx mode) on Google Container Engine. These pods are sitting behind a GCE network load balancer. My question is how to access the external Client IP from inside the Rails app.

The Github issue here seems to present a solution, but I ran the suggested:

for node in $(kubectl get nodes -o name | cut -f2 -d/); do
  kubectl annotate node $node \
    net.beta.kubernetes.io/proxy-mode=iptables;
  gcloud compute ssh --zone=us-central1-b $node \
    --command="sudo /etc/init.d/kube-proxy restart";
done

but I am still getting a REMOTE_ADDR header of 10.140.0.1.

On ideas on how I could get access to the real Client IP (for geolocation purposes)?

Edit: To be more clear, I am aware of the ways of accessing the client IP from inside Rails, however all of these solutions are getting me the internal Kubernetes IP, I believe the GCE network load balancer is not configured (or perhaps unable) to send the real client IP.

Jared S
  • 380
  • 4
  • 14
  • http://stackoverflow.com/questions/4465476/rails-get-client-ip-address http://stackoverflow.com/questions/3887943/get-real-ip-address-in-local-rails-development-environment – Eray Balkanli Mar 29 '16 at 12:52
  • 1
    Possible duplicate of [How to access client IP of an HTTP request from Google Container Engine?](http://stackoverflow.com/questions/36464890/how-to-access-client-ip-of-an-http-request-from-google-container-engine) – Jared S Apr 14 '16 at 13:33

2 Answers2

2

A Googler's answer to another version of my question verifies what I am trying to do is not currently possible with the Google Container Engine Network Load Balancer currently.

EDIT (May 31, 2017): as of Kubernetes v1.5 and up this is possible on GKE with the beta annotation service.beta.kubernetes.io/external-traffic. This was answered on SO here. Please note when I added the annotation the health checks were not created on the existing nodes. Recreating the LB and restarting the nodes solved the issue.

Jared S
  • 380
  • 4
  • 14
0

It seems as though this is not a rails problem at all, but one of GCE. You can try the first part of

request.env["HTTP_X_FORWARDED_FOR"]

Explanation

Getting Orgin IP From Load Balancer advises that https://cloud.google.com/compute/docs/load-balancing/http/ has the text

The proxies set HTTP request/response headers as follows:

  • Via: 1.1 google (requests and responses)
  • X-Forwarded-Proto: [http | https] (requests only)
  • X-Forwarded-For: <client IP(s)>, <global forwarding rule external IP> (requests only) Can be a comma-separated list of IP addresses depending on the X-Forwarded-For entries appended by the intermediaries the client is traveling through. The first element in the section shows the origin address.
  • X-Cloud-Trace-Context: <trace-id>/<span-id>;<trace-options> (requests only) Parameters for Stackdriver Trace.
Community
  • 1
  • 1
serv-inc
  • 35,772
  • 9
  • 166
  • 188
  • Thanks for your response. I should have been more clear in my question, I agree with you that it is not a Rails problem and it does seem possible with the HTTP load balancer, however I am currently using the _network_ load balancer which I can't find documentation on how to retrieve the original IP. – Jared S Mar 30 '16 at 15:20
  • @JaredS: Thanks for the feedback. Seems like the network load balancer only works at the TCP level (for your purpose, also AH, UDP, etc, as of https://cloud.google.com/compute/docs/load-balancing/network/forwarding-rules). That makes adding the originating IP nontrivial. You might be able to redirect to a Squid proxy or the HTTP load balancer which then adds the origin-IP, as described in http://stackoverflow.com/a/8108013/1587329, but I might have misunderstood. – serv-inc Mar 30 '16 at 16:12