2012-02-21 3 views
5

어떤 곳에서는 request.environ['REMOTE_ADDR']을 사용하는 피라미드 애플리케이션이 있습니다.nginx 프록시 뒤에있는 피라미드 서버에서 클라이언트의 실제 IP를 얻는 방법

응용 프로그램은 포트 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 항상 동일하다. 이 문제를 해결하기위한 몇 가지 전략이 있지만 권장 방법이 있는지 모르겠습니다.

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

  • 는 WSGI 미들웨어를 사용

    • 이 필요한 NewRequest의 request.environ 대체합니다 가입자 [ 'REMOTE_ADDR'] 경우를 추가 : 여기

      내가 고려하고 무엇인가 피라미드 레이어를 치기 전에 request.environ을 수정하십시오.

    • 뭔가 다른

    당신이 피라미드의 응용 프로그램을 배포하기 위해 사용합니까 전략

    ? 두 개의 nginx 프록시가 있으면 어떻게됩니까? (LAN에 서비스를 제공하는 첫 번째 서비스와 인터넷에 직접 연결된 시스템을 연결하는 첫 번째 서비스). 의 nginx에서

  • 답변

    6

    입니다 파이프 라인을 통해 X-Forwarded-ForREMOTE_ADDR으로 자동 변환합니다. 역방향 프록시의 다른 속성에도 유용합니다. 예를 들어 X-Forwarded-Protowsgi.url_scheme으로 변환하여 사용자가 https를 방문하면 생성 된 URL도 https가되도록합니다.

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

    +0

    내가 처음으로 PrefixMiddleware를 시도했지만 요리 책에 제안 된 것처럼 작동하지 않았을 것입니다. 나는 그것을 다시 시도해야한다. – ascobol

    +0

    [pipe : main] 섹션을 삽입하는 것을 잊어 버렸습니다. 모든 것이 잘 작동합니다. – ascobol

    -2

    : PHP에서

    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; 
         } 
    

    내가 할 : 파이썬 아마도

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

    이 유사하다

    당신이 당신의 WSGI에 paste.deploy.config.PrefixMiddleware를 사용하는 경우, $의 IP는 실제 IP

    2

    나는 nginx를 뒤에 gevent 서버를 사용하고 난 클라이언트의 IP 주소를 얻을 수 request.client_addr를 사용합니다.

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

    이벤트 핸들러처럼 읽을 수 있습니다 : 당신이 WSGI의 pipline이없는, 또는 paste을 사용하지 않으려면

    1

    , 다음 이벤트 처리기 추가

    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) 
    

    및 확인 프록시가 헤더를 설정했는지 확인하십시오

    관련 문제