2009-10-26 1 views
9

Итак, я получил простую настройку с nginx для статических носителей и балансировки нагрузки и торнадо в качестве веб-сервера для django (4 сервера). Моя проблема remote_addr не получает передается на Джанго, так что я получаю исключение KeyError:REMOTE_ADDR не отправляется в Django с использованием nginx & tornado

article.ip = request.META['REMOTE_ADDR']

Удаленный адрес послана через, как X-Real-IP (HTTP_X_REAL_IP) благодаря nginx.conf:

location/{ 
     proxy_pass_header Server; 
     proxy_set_header Host $http_host; 
     proxy_redirect false; 
     proxy_set_header X-Real-IP $remote_addr; 
     proxy_set_header X-Scheme $scheme; 
     proxy_pass http://frontends; 
    } 

Как HTTP предваряется ключ META Я не могу просто сделать proxy_set_header remote_addr $ remote_addr. Что я могу сделать, это прочитать X-Real-IP, если удаленный ключ addr не найден, но мне любопытно, есть ли более разумное решение.

Спасибо!

+0

Это не правильное решение, но я добавил Джанго промежуточное программное обеспечение, который превратил HTTP_X_REAL_IP в REMOTE_ADDR. – Nixarn

+0

Эти заявления помогут вам: proxy_redirect off; proxy_set_header X-Real-IP $ remote_addr; \t \t proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for; \t \t proxy_set_header Схема X-Scheme $; – glarrain

ответ

11

Попробуйте это:

location/{ 
    proxy_pass http://frontends; 
    proxy_pass_header Server; 
    proxy_redirect off; 
    proxy_set_header Host $http_host; 
    proxy_set_header X-Real-IP $remote_addr; 
    proxy_set_header X-Scheme $scheme; 
    proxy_set_header REMOTE_ADDR $remote_addr; 
} 

Просто добавьте proxy_set_header REMOTE_ADDR, и это должно быть хорошо работать.

Пробовал с:

  • Джанго 1.5.4
  • Nginx 1.4.3
  • Tornado 2.2.1
+0

согласно следующим образом: https: //easyengine.io/tutorials/nginx/forwarding-visitors-real-ip/ внутри серверной-Nginx конф: место ~ \ .php $ { fastcgi_param REMOTE_ADDR $ http_x_real_ip; # ... другие правила } – Amini

5

У меня есть аналогичная установка. После установки nginx перед apache я заметил, что IP-адрес в журналах apache всегда был 127.0.0.1. Установка «libapache2-mod-rpaf», похоже, исправить. Я не знаю, связана ли ваша проблема.

+0

Ах спасибо, но я вообще не использую apache для этого проекта. – Nixarn

+0

Упс, конечно, извините за это – asciitaxi

+0

Спасибо за ваш ответ. BTW: Это также помогает программному обеспечению PHP, которое полагается на $ _SERVER ['REMOTE_ADDR'], который теперь также содержит настоящий удаленный IP-адрес. – Leif

0

Нет, это not possible для передачи на remote_addr. Поэтому единственным решением, которое я знаю, является использование X-Real-IP или X-Forwarded-For и убедитесь, что бэкэнд правильно их обрабатывает.

Edit: это относится к fastcgi_pass, а не регулярные Nginx proxy_pass

+0

Невозможно? Решение Juande работает очень хорошо для меня. –

+0

К обработчику fastcgi, да. Но вопрос был о прокси-сервере nginx. – windyjonas

+1

Упс, я должен был прочитать ближе - 'proxy_pass' не 'fastcgi_pass'. Я не могу отменить мой downvote, если вы не отредактируете свой ответ, по-видимому. :/Если бы вы его отредактировали, я был бы счастлив вместо этого отменить. –

14

Вот как я решил проблему. Используя это промежуточное программное обеспечение:

class SetRemoteAddrMiddleware(object): 
    def process_request(self, request): 
     if not request.META.has_key('REMOTE_ADDR'): 
      try: 
       request.META['REMOTE_ADDR'] = request.META['HTTP_X_REAL_IP'] 
      except: 
       request.META['REMOTE_ADDR'] = '1.1.1.1' # This will place a valid IP in REMOTE_ADDR but this shouldn't happen 

Надеюсь, что это поможет!

+2

Единственная проблема с этим в том, что если вы молча удаляете ошибку, вы обнаружите этот неверно настроенный веб-сервер намного позже (с потенциально потерянной информацией или пользователями, которые не могут войти в систему). Мое предложение состояло бы в сбое или, по крайней мере, регистрации ошибки. –

+2

Практически всегда вы не хотите использовать 'try/except:' тип исключения в CPython 2.x, потому что он также поймает SystemExit, KeyboardInterrupt и GeneratorExit - это всевозможные ошибки, которые вам лучше оставить в покое или в редкие случаи, поймать их отдельно. В частности, в этом случае следует уловить KeyError. Но тогда вы могли бы сделать этот код еще проще: 'request.META.setdefault ('REMOTE_ADDR', request.META.get ('HTTP_X_REAL_IP', '1.1.1.1'))' – temoto

+0

Хорошее решение, но помните has_key() был удален в Python 3.x. Использование: if not request.META.get ('REMOTE_ADDR', None): – Robert

5

Добавить "fastcgi_param REMOTE_ADDR $ remote_addr;" в файл nginx.conf:

location/{ 
    # host and port to fastcgi server 
    fastcgi_pass 127.0.0.1:8801; 
    fastcgi_param PATH_INFO $fastcgi_script_name; 
    fastcgi_param REQUEST_METHOD $request_method; 
    fastcgi_param QUERY_STRING $query_string; 
    fastcgi_param CONTENT_TYPE $content_type; 
    fastcgi_param CONTENT_LENGTH $content_length; 
    fastcgi_pass_header Authorization; 
    fastcgi_intercept_errors off; 
    ... 
    # Add this line! 
    fastcgi_param REMOTE_ADDR $remote_addr; 
    ... 
} 

Источник: how to nginx virtual servers + fcgi for django?

+0

Это отлично работает для 'fastcgi_pass' (спасибо!), Но это не будет работать для' proxy_pass', который является настройкой OP (см. @windyjonas 'ответ). –

+1

Как насчет - 'fastcgi_param REMOTE_ADDR $ http_x_real_ip;'? Если X-Real-IP доступен для nginx, его можно использовать для передачи как fastcgi_param. Это устранит необходимость внесения изменений в исходные коды приложения. – rahul286

2

Для меня, используя следующие работали:

server { 
    listen 80; 
    server_name foo.bar.com; 
    location/{ 
     proxy_pass http://127.0.0.1:8000; 
     proxy_set_header X-Forwarded-For $remote_addr; 
    } 
} 

Это работает с Django 1.4 (в частности, localshop).

 Смежные вопросы

  • Нет связанных вопросов^_^