How to get the real IP address of the client on the pyramid server behind the nginx proxy server

I have a Pyramid application that uses request.environ['REMOTE_ADDR']in some places.

The application is served by Python Paste on port 6543, and the nginx server listening on port 80 sends requests to the Paste server.

The nginx configuration is based on the Pyramid cookbook:

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;

    }

In the Pyramid application, the variable request.environ ['REMOTE_ADDR'] is now always 127.0.0.1. I see several strategies to solve this problem, but I do not know if there is a recommended way to do this.

Here is what I am considering:

  • add a NewRequest subscriber who will replace request.environ ['REMOTE_ADDR'] if necessary:

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

  • use wsgi middleware to modify request.environ before hitting the pyramid layer.

  • -

Pyramid? , nginx? ( , - , ).

+5
4

paste.deploy.config.PrefixMiddleware WSGI 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

+6

gevent nginx, request.client_addr IP- .

+2

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

and make sure your proxy has set headers

+1
source

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

in php i do:

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

maybe in python similarly, $ ip is your real ip

-2
source

All Articles