Domanda

Ho un'applicazione piramidale che utilizza request.environ['REMOTE_ADDR'] in alcuni posti.

L'applicazione è servita da Python Incolla sulla porta 6543 e un server Nginx che ascolta sulla porta 80 è le richieste di inoltro al server incolla.

La configurazione Nginx è ispirata al libro di cucina 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;

    }

Nell'applicazione Pyramid la richiesta variabile.Environ ['remote_addr'] è sempre uguale a 127.0.0.1. Vedo alcune strategie per risolvere questo problema, ma non so se esiste un modo consigliato per farlo.

Ecco cosa sto prendendo in considerazione:

  • Aggiungi un abbonato NewRequest che sostituisce la richiesta.Environ ['remote_addr'] se necessario:

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

  • Utilizzare un middleware WSGI per modificare la richiesta. Environ prima di colpire il livello piramide.

  • qualcos'altro

Quale strategia usi per la distribuzione di applicazioni piramide? Cosa succederà se ho due proxy Nginx? (Il primo servizio della LAN e una seconda una macchina direttamente connessa a Internet).

È stato utile?

Soluzione

Se usi il paste.deploy.config.PrefixMiddleware nella tua pipeline WSGI via use = egg:PasteDeploy#prefix, tradurrà automaticamente X-Forwarded-For in REMOTE_ADDR. È anche ottimo per le altre proprietà del tuo proxy inverso, ad esempio si tradurrà X-Forwarded-Proto in wsgi.url_scheme Per garantire che se l'utente visita con HTTPS, gli URL generati sono anche HTTPS.

http://pythonpaste.org/deploy/class-pate.deploy.config.prefixmiddleware.html

Altri suggerimenti

Uso Gevent Server dietro Nginx e uso request.client_addr Per ottenere l'indirizzo IP di un client.

Se non si dispone di una pipline WSGI o non si desidera utilizzare paste, quindi aggiungi un gestore di eventi:

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

Il gestore di eventi può leggere come:

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)

e assicurati che il tuo proxy imposti le intestazioni

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 lo faccio:

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

Forse in Python è simile, $ ip è il tuo vero IP

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top