2012-02-21 28 views
5

Tôi có ứng dụng Kim tự tháp sử dụng request.environ['REMOTE_ADDR'] ở một số nơi.Cách lấy IP thực của khách hàng trong máy chủ kim tự tháp phía sau proxy nginx

Ứng dụng được cung cấp bởi Python Dán trên cổng 6543 và máy chủ nginx đang nghe trên cổng 80 là yêu cầu chuyển tiếp tới máy chủ Dán.

Cấu hình nginx được lấy cảm hứng từ sách dạy nấu ăn Pyramid:

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; 

    } 

Trong ứng dụng Pyramid các request.environ biến [ 'REMOTE_ADDR'] tại là luôn bằng 127.0.0.1. Tôi thấy một vài chiến lược để giải quyết vấn đề này nhưng tôi không biết có cách nào được khuyến nghị để làm điều đó không.

Dưới đây là những gì tôi đang xem xét:

  • thêm một thuê bao NewRequest thay thế request.environ [ 'REMOTE_ADDR'] nếu cần thiết:

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

  • sử dụng một middleware wsgi để sửa đổi request.environ trước khi nhấn vào layer Pyramid.

  • cái gì khác

Chiến lược nào bạn sử dụng cho việc triển khai các ứng dụng Kim tự tháp? Điều gì sẽ xảy ra nếu tôi có hai proxy nginx? (lần đầu tiên phục vụ mạng LAN và máy thứ hai là một máy tính được kết nối trực tiếp với Internet).

Trả lời

6

Nếu bạn sử dụng paste.deploy.config.PrefixMiddleware trong WSGI của bạn đường ống qua use = egg:PasteDeploy#prefix, nó sẽ tự động dịch X-Forwarded-For thành REMOTE_ADDR. Nó cũng tuyệt vời cho các thuộc tính khác của proxy ngược của bạn, ví dụ: nó sẽ dịch X-Forwarded-Proto thành wsgi.url_scheme để đảm bảo rằng nếu người dùng truy cập bằng https thì URL được tạo cũng là https.

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

+0

Tôi phải bỏ lỡ điều gì đó vì lần đầu tiên tôi thử với PrefixMiddleware như được đề xuất trong sách dạy nấu ăn nhưng nó không hoạt động. Tôi rất cần phải thử lại lần nữa. – ascobol

+0

ok nó chỉ ra rằng tôi quên để chèn [đường ống: chính] phần. Mọi thứ đều hoạt động tốt – ascobol

-2

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

trong php i làm:

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

có lẽ trong python là tương tự, $ ip là ip thực sự của bạn

2

tôi sử dụng gevent server đằng sau nginx và tôi sử dụng request.client_addr để có được địa chỉ IP của một khách hàng.

1

Nếu bạn không có một pipline WSGI, hoặc không muốn sử dụng paste, sau đó thêm một event handler:

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

Các xử lý sự kiện có thể đọc như:

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) 

và làm chắc chắn proxy của bạn đặt tiêu đề

Các vấn đề liên quan