How to log real client ip in rails log when behind proxy like nginx

In my opinion, your current approach is the only sane one. The only step that is missing is overwriting the IP address in env.

The typical REMOTE_ADDR seldom holds the correct IP if you’ve any amount of layers of proxies and load balancers and what not — you’re not unique in this respect. Each potentially adds or changes remote IP-related headers. And you cannot assume that each of those fields necessarily correspond to a single IP address, at that. Some will push or unshift an IP to a list instead.

There is only one way to know for sure which field holds the correct value and how, and that is to dive in there and look. You’ve evidently done that already. Now, just overwrite env['REMOTE_ADDR'] with its correct value using your Rack middleware. There’s little point in letting any piece of code you didn’t write log or process the wrong IP address, as is happening now.

(This being Ruby, you could also monkey patch Rack::Request, of course…)

For colorful reading that illustrate the varying degrees of which exotic setups can mess up attempts at finding a client’s real IP address, see for instance the unending discussions that occurred about this for WordPress:

  • https://core.trac.wordpress.org/ticket/9235
  • https://core.trac.wordpress.org/ticket/4198
  • https://core.trac.wordpress.org/ticket/4602

It’s PHP but the gist of the points raised apply equally well to Ruby. (Note that they’re unresolved as I write this, too, and that they’ve been around for aeons.)

Leave a Comment