2013-07-16 1 views
15

Я пытаюсь включить $ remote_addr или $ http_remote_addr в свой proxy_pass без успеха.

правило переписывание работы

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

proxy_pass без $ remote_addr работает, но freegeoip не читает 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; 
} 

Затем я добавляю IP-к в конце запроса, например:

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

, но nginx сообщите об этой ошибке: нет распознавателя, определенного для re решить freegeoip.net

+0

имеет место ошибки при перезапуске Nginx, или когда HTTP-запрос попадает в блок местоположения? –

+0

Когда я запрашиваю URL-адрес –

ответ

60

Если у оператора proxy_pass нет переменных в нем, тогда он будет использовать системный вызов «gethostbyaddr» во время запуска или перезагрузки и будет кэшировать это значение навсегда.

, если есть какие-либо переменные, такие как использование любого из следующих:

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

Тогда Nginx будет использовать встроенный распознаватель, и «распознаватель» директива должна присутствовать. «резольвер», вероятно, является неправильным; подумайте об этом как «какой DNS-сервер будет использовать встроенный преобразователь». Начиная с nginx 1.1.9 встроенный преобразователь будет соблюдать значения DNS TTL. До этого он использовал фиксированное значение 5 минут.

+1

Это более полезный и информативный ответ. Спасибо. –

+0

Да, это очень полезно, спасибо. – jwerre

+0

Ключом является любая переменная, присутствующая в значении proxy_pass, спасибо за правильный ответ и объяснение. –

35

Кажется немного странным, что nginx не может разрешить имя домена во время выполнения, а не во время конфигурации (поскольку доменное имя жестко закодировано). Добавление объявления resolver в блок местоположения обычно фиксирует проблемы DNS, возникающие во время выполнения. Так что ваш блок место может выглядеть следующим образом:

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

Это решение основано на статье я прочитал некоторое время назад - Proxy pass and resolver. Было бы полезно прочитать.

+6

Do ** NOT ** использовать общедоступный DNS-сервер, такой как '8.8.8.8'. [Чтобы предотвратить спуфинг DNS, рекомендуется настроить DNS-серверы в правильно защищенной доверенной локальной сети.] (Http://nginx.org/en/docs/http/ngx_http_core_module.html#resolver) – Tim

+0

Это должен быть принятый ответ, потому что он охватывает другие случаи, такие как args, remote_addr и т. д. – onalbi

0

Вы также можете упомянуть свой nginx server port в proxy_pass uri. Это решило проблему для меня.

0

Если кто-то stll испытывают проблемы, для меня это помогло переместить proxy_pass хост отдельных вверх по течению, так что я придумал что-то вроде этого

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/; 
    } 
} 
Смежные вопросы