2009-10-26 41 views
9

因此我使用nginx作爲django(4個服務器運行)的靜態媒體和負載平衡和龍捲風作爲webserver的簡單設置。我的問題是REMOTE_ADDR沒有得到傳遞給Django的,所以我得到一個KeyError異常:REMOTE_ADDR沒有使用nginx和tornado發送到Django

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

的遠程地址被打通作爲X-實時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,如果沒有找到遠程地址鍵,但我很好奇,如果有更聰明的解決方案。

謝謝!

+0

這是不正確的解決方案,但我加了一個Django中間件轉向將HTTP_X_REAL_IP寫入REMOTE_ADDR。 – Nixarn 2009-10-30 15:06:28

+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 $ scheme; – glarrain 2013-03-14 16:38:47

回答

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,它應該是工作做好。

試圖用:

  • 的Django 1.5.4
  • Nginx的1.4.3
  • 龍捲風2.2.1
+0

根據這樣的:HTTPS://easyengine.io/tutorials/nginx/forwarding-visitors-real-ip/ 後端-nginx的CONF內: 位置〜\ .PHP $ { fastcgi_param REMOTE_ADDR $ http_x_real_ip; #...其他規則 } – Amini 2016-03-01 09:06:35

5

我有一個類似的設置。在將nginx放在apache之前後,我注意到apache日誌中的IP始終是127.0.0.1。安裝「libapache2-mod-rpaf」似乎解決了這個問題。我不知道你的問題是否相關。

+0

啊謝謝,但我沒有在這個項目中使用Apache。 – Nixarn 2009-10-30 15:05:45

+0

哎呀,當然,對不起, – asciitaxi 2009-10-30 15:26:15

+0

感謝您的回答。順便說一句:這也有助於PHP軟件,它依賴於$ _SERVER ['REMOTE_ADDR'],它現在也包含真正的遠程IP。 – Leif 2015-05-21 07:37:29

0

不,它是not possible在remote_addr上傳遞。所以我知道的唯一解決方案是使用X-Real-IP或X-Forwarded-For,並確保後端能夠正確處理這些問題。

編輯:適用於fastcgi_pass,不正規的nginx proxy_pass

+0

不可能? @ Juande的解決方案對我來說工作得非常好。 – 2011-10-28 22:13:47

+0

對於fastcgi處理程序,是的。但問題是關於一個nginx代理。 – windyjonas 2011-11-01 14:24:29

+1

哎呀,我應該仔細閱讀 - 'proxy_pass'不是'fastcgi_pass'。除非你編輯你的答案,否則我無法廢除我的失望。 :/如果你要編輯它,我會樂意改變它。 – 2011-11-03 17:07:03

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

與此唯一的問題是,如果你默默地放棄錯誤,你會發現錯誤配置的Web服務器太晚(可能丟失信息或用戶無法登錄)。我的建議是失敗或至少記錄錯誤。 – 2013-03-14 11:02:43

+2

幾乎總是,您不希望嘗試/除了:'CPython 2.x中沒有異常類型,因爲它也會捕獲SystemExit,KeyboardInterrupt和GeneratorExit - 這些都是您最好單獨離開的各種錯誤,或者罕見的情況下,分開抓住他們。 特別是在這種情況下,應該捕獲KeyError。但是,你可以進一步使所有這些代碼更簡單: request.META.setdefault('REMOTE_ADDR',request.META.get('HTTP_X_REAL_IP','1.1.1.1'))' – temoto 2013-03-22 21:26:09

+0

好的解決方案,但請記住has_key ()在Python 3.x中被刪除。 使用: 如果不是request.META.get('REMOTE_ADDR',None): – Robert 2016-11-01 17:10:43

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'答案)。 – 2011-11-03 17:09:49

+1

如何 - 'fastcgi_param REMOTE_ADDR $ http_x_real_ip;'?如果X-Real-IP可用於nginx,則可以使用它作爲fastcgi_param傳遞。這將消除對應用程序源代碼進行更改的需要。 – rahul286 2013-05-16 10:08:26

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)。

相關問題