Q&A for Work

Setup a private space for you and your coworkers to ask questions and share information. Learn more about Teams

I'm trying to include $remote_addr or $http_remote_addr on my proxy_pass without success.

The rewrite rule works

location ^~ /freegeoip/ {  
  rewrite ^ http://freegeoip.net/json/$remote_addr last;

The proxy_pass without the $remote_addr works, but freegeoip does not read the x-Real-IP

location ^~ /freegeoip/ {
  proxy_pass http://freegeoip.net/json/;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $host;

Then, I'm adding the ip to the end of the request, like this:

location ^~ /freegeoip/ {
  proxy_pass http://freegeoip.net/json/$remote_addr;

but nginx report this error: no resolver defined to resolve freegeoip.net

does the error occur when you restart nginx, or when an http request hits the location block? – Rob Squires Jul 16 '13 at 21:05

If the proxy_pass statement has no variables in it, then it will use the "gethostbyaddr" system call during start-up or reload and will cache that value permanently.

if there are any variables, such as using either of the following:

set $originaddr http://origin.example.com;
proxy_pass $originaddr;
# or even
proxy_pass http://origin.example.com$request_uri;

Then nginx will use a built-in resolver, and the "resolver" directive must be present. "resolver" is probably a misnomer; think of it as "what DNS server will the built-in resolver use". Since nginx 1.1.9 the built-in resolver will honour DNS TTL values. Before then it used a fixed value of 5 minutes.

The key being any variable present in the proxy_pass value, thanks for the right answer and explanation. – Pablo Banderas Mar 23 '17 at 13:54

It seems a bit strange that nginx is failing to resolve the domain name at runtime rather than at configuration time (since the domain name is hard coded). Adding a resolver declaration to the location block usually fixes dns issues experienced at runtime. So your location block might look like:

location ^~ /freegeoip/ {
  #use google as dns
  resolver 8.8.8.8;
  proxy_pass http://freegeoip.net/json/$remote_addr;

This solution is based on an article I read a while back - Proxy pass and resolver. Would be worth a read.

Do NOT use a publicly accessible DNS server such as 8.8.8.8. To prevent DNS spoofing, it is recommended configuring DNS servers in a properly secured trusted local network. – Tim Oct 7 '16 at 20:12 This should be the accepted answer because it cover other cases, like args, remote_addr, etc – onalbi Jan 20 '18 at 11:01 This is still valid with latest stable nginx/1.10.3. So resolver directive is required in conjunction with proxy_pass dynamic directive e.g. proxy_pass http://$host;. While this one works w/o resolver: server { listen 80; server_name myurl.com; location / {return 303 https://$host$request_uri;} } – stamster May 9 '18 at 16:21 In my case (Google Cloud), I used the internal nameserver, 169.254.169.254, to resolve other instances in my tenant by hostname. – Daniel Watrous Feb 9 at 3:41

If anyone is stll experiencing trouble, for me it helped to move the proxy_pass host to a seperate upstream, so I come up with something like this

upstream backend-server {
  server backend.service.consul;
server {
  listen       80;
  server_name  frontend.test.me;
  location ~/api(.*)$  {
    proxy_pass http://backend-server$1;
  location / {
    # this works mystically! backend doesn't...
    proxy_pass http://frontend.service.consul/;
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.

site design / logo © 2019 Stack Exchange Inc; user contributions licensed under cc by-sa 3.0 with attribution required. rev 2019.6.24.34095