2012-02-21 49 views
5

我有一個金字塔應用程序,它在某些地方使用request.environ['REMOTE_ADDR']如何在金字塔服務器後面的nginx代理中獲取客戶端的真實IP

該應用程序由Python粘貼在端口6543上,一個監聽端口80的nginx服務器將請求轉發給粘貼服務器。

nginx的配置由金字塔食譜啓發:

server { 

    listen 80; ## listen for ipv4 
    listen [::]:80 default ipv6only=on; ## listen for ipv6 

    server_name localhost; 

    access_log /var/log/nginx/localhost.access.log; 

    location/{ 

     proxy_set_header  Host $host; 
     proxy_set_header  X-Real-IP $remote_addr; 
     proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for; 
     proxy_set_header  X-Forwarded-Proto $scheme; 
     proxy_pass http://127.0.0.1:6543; 

    } 

在金字塔應用可變request.environ [「REMOTE_ADDR」]現在是始終等於127.0.0.1。 我看到一些策略來解決這個問題,但我不知道是否有推薦的方法來做到這一點。

這裏是我考慮:

  • 添加必要的,這取代了request.environ一個NewRequest用戶[ 'REMOTE_ADDR'],如果:

    if 'HTTP_X_REAL_IP' in event.request.environ: event.request.environ['REMOTE_ADDR'] = event.request.environ['HTTP_X_REAL_IP']

  • 使用WSGI中間件在點擊Pyramid圖層之前修改request.environ。

  • 別的

你使用哪種策略部署金字塔的應用程序? 如果我有兩個nginx代理,會發生什麼? (第一臺服務於局域網,第二臺服務器直接連接到互聯網)。

回答

6

如果您在WSGI使用paste.deploy.config.PrefixMiddleware管道通過use = egg:PasteDeploy#prefix,它會自動將X-Forwarded-For轉換爲REMOTE_ADDR。它也適用於您的反向代理的其他屬性,例如它會將X-Forwarded-Proto轉換爲wsgi.url_scheme,以確保如果用戶使用https訪問,則生成的URL也是https。

http://pythonpaste.org/deploy/class-paste.deploy.config.PrefixMiddleware.html

+0

我一定錯過了一些東西,因爲我第一次嘗試使用PrefixMiddleware,正如食譜中的建議,但它沒有奏效。我有意識地需要再試一次。 – ascobol 2012-02-22 15:28:36

+0

好吧,事實證明,我忘了插入[管道:主]部分。一切正常 – ascobol 2012-02-22 16:09:40

-2

在nginx的:

location/{ 
    proxy_pass http://yourapp; 
     proxy_redirect  off; 
     proxy_set_header Host    $host; 
     proxy_set_header X-Real-IP  $remote_addr; 
     proxy_set_header X-Forwarded-For $remote_addr; 
     } 

在PHP我做的:

 if($_SERVER["HTTP_X_FORWARDED_FOR"]){ 
     $ip = $_SERVER["HTTP_X_FORWARDED_FOR"]; 
    }else{ 
     $ip = $_SERVER["REMOTE_ADDR"]; 
     } 

也許蟒蛇是相似的,$ IP是你的真實IP

2

我使用nginx的背後服務器GEVENT我用request.client_addr獲得客戶端的IP地址。

1

如果你沒有一個WSGI pipline,或者不希望使用paste,然後添加一個事件處理程序:

config.add_subscriber(reverseProxyProtocolCorrection,'pyramid.events.NewRequest') 

事件處理程序可以讀取,如:

def reverseProxyProtocolCorrection(event): 
    event.request.scheme = 'https' if event.request.headers['X-Forwarded-Proto']=='https' else 'http' 
    event.request.remote_addr=parseXForward(event.request.headers['X-Forwarded-For'],event.request.remote_addr) 

,使確定你的代理設置了標題

相關問題