To avoid having to parse X-Forwarded-For in Varnish, I'm trying to just set a header on the SSL terminator (currently Apache) that stores the direct client IP in a header.

On our development machine, this works:

RequestHeader set X-Foo %{REMOTE_ADDR}e

However, in staging it doesn't. Specifically, the header is empty, as illustrated by both varnishlog:

13 TxHeader     b X-Foo: (null)

(On the development machine, this shows the IP address as expected.)

Similarly, logging REMOTE_ADDR shows that it only appears to be populated on the dev machine:

# Config
LogFormat "%{X-Forwarded-For}i %{REMOTE_ADDR}e" combined
CustomLog "/var/log/httpd/access_log" combined

# Log file, staging
<my ip> -

# Log file, development
<my ip> <my ip>

Since the dev machine is, well, a dev machine, it is different in a number of ways; however, I can't track down which difference is causing this. The versions of Apache are the same (2.2.22), and I don't see anything relevant in any of the standard config files or /etc/sysconfig/httpd. And the rest of the system is reasonably similar, since they're built off the same CentOS 5 base image.

I can't even tell from the Apache documentation whether REMOTE_ADDR is expected to exist or not as an environment variable, but it clearly works on one machine, whether by fluke or design, and the inconsistency is driving me mad.

  • Browser dependent behavior? Underlying http client implementation? – mdpc Aug 22 '14 at 20:36
  • hmmm not sure but can you check if mod_setenvif is enabled on both servers ? – krisFR Aug 22 '14 at 20:42
  • Using the same clients (Chrome and httpie) to check. The setenvif_module is statically compiled in, as reported by httpd -t -D DUMP_MODULES. – Xiong Chiamiov Aug 22 '14 at 21:09
  • what about mod_headers? Are you certain that REMOTE_ADDR is empty, that shouldn't be a case, it's more probable that headers are not set correctly. – Jakov Sosic Aug 22 '14 at 22:26

Looking through the sources, REMOTE_ADDR is set only for these handlers that come with the server itself: mod_proxy_scgi, mod_ext_filter, mod_include, mod_isapi, mod_cgid, and mod_cgi (only they call ap_add_common_vars) so somehow one of these handlers is getting called before mod_headers or mod_log_config on your dev box but not on the staging box. (You may have other handlers.)

In less technical speak, from the doc you reference it says the same thing:

In addition to all environment variables set within the Apache configuration and passed from the shell, CGI scripts and SSI pages (emphasis mine) are provided with a set of environment variables containing meta-information about the request as required by the CGI specification.

  • Ah, I see; thanks. I dug a bit more into it, but when I found myself writing an Apache module solely for the purpose of calling ap_add_common_vars, I took a step back and decided I was better off just parsing X-Forwarded-For in Varnish. – Xiong Chiamiov Aug 25 '14 at 20:11

If you use mod_ssl use 's' to get value of a variable (working on apache 2.4). This is an example to set X-Forwarded-For header to REMOTE_ADDR.

RequestHeader setifempty x-forwarded-for %{REMOTE_ADDR}s

More info about mod_headers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.