2012-05-22 20 views
11

ho controllare l'indirizzo IP del controller consbagliato indirizzo IP con nginx + Unicorn + rotaie

request.env['REMOTE_ADDR'] 

questo funziona bene nel mio ambiente di test. Ma sul server di produzione con nginx + unicorno ottengo sempre 127.0.0.1.

Questo è il mio config nginx per il sito:

upstream unicorn { 
    server unix:/tmp/unicorn.urlshorter.sock fail_timeout=0; 
} 

server { 
    listen 80 default deferred; 
    # server_name example.com; 
    root /home/deployer/apps/urlshorter/current/public; 

    location ^~ /assets/ { 
    gzip_static on; 
    expires max; 
    add_header Cache-Control public; 
    } 

    try_files $uri/index.html $uri @unicorn; 
    location @unicorn { 
    proxy_set_header X-Real-IP  $remote_addr; 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header Host $http_host; 
    proxy_redirect off; 
    proxy_pass http://unicorn; 
    } 

    error_page 500 502 503 504 /500.html; 
    client_max_body_size 4G; 
    keepalive_timeout 10; 
} 

risposta

3

La risposta è nel file di configurazione :) Il seguente dovrebbe fare ciò che si vuole:

real_ip = request.headers["X-Real-IP"] 
più

qui: http://api.rubyonrails.org/classes/ActionDispatch/Request.html#method-i-headers

UPDATE: La risposta corretta è qui in un altro Q:

https://stackoverflow.com/a/4465588

o in questa discussione:

https://stackoverflow.com/a/15883610

spoiler:

uso request.remote_ip

+1

Non è un grande fan di questo approccio in quanto non funziona nel mio ambiente dev utilizzando sottili . – dgmdan

+0

Hai ragione. Ho risolto la risposta. – forker

17

Ho avuto problemi con questo anche; Ho trovato questa domanda, ma l'altra risposta non mi ha aiutato.

Ho esaminato l'implementazione di Rack 3.2 # di Rails 3.2.8 per vedere come ha deciso cosa dire; per farlo usare un indirizzo passato attraverso l'ambiente senza filtrare gli indirizzi dalla mia rete locale (sta cercando di filtrare i proxy intermedi, ma non è quello che volevo), ho dovuto impostare il HTTP_CLIENT_IP dal mio blocco di configurazione del proxy nginx in aggiunta per quello che hai sopra (X-Forwarded-For deve essere lì anche per questo lavoro!):

proxy_set_header CLIENT_IP $remote_addr; 
+2

mi ha aiutato anche con nginx + unicorno + sinatra. – glasz

6

Se si utilizza request.remote_addr si otterrà il del proxy Nginx.

Per ottenere l'indirizzo IP reale dell'utente, è possibile utilizzare request.remote_ip.

Secondo il codice sorgente di Rails, si verifica la presenza di varie intestazioni HTTP per offrirti la più pertinente: in Rails 3.2 o Rails 4.0.0.beta1

3

Il proxy_set_header CLIENT_IP $remote_addr; non ha funzionato per me. Ecco cosa ha fatto ..

La soluzione che ho trovato dopo aver esaminato il codice actiondispatch remote_ip.rb source. Ora ottengo l'IP corretto nei miei processi di idea/guardiano e qualsiasi altra routine che sto osservando request.remote_ip

Il mio config ... Ruby 2.2.1 - Rails 4.2.1 - NGINX v1.8.0 - Unicorn v4.9.0 - Devise v3.4.1

nginx.conf

HTTP_CLIENT_IP vs client_ip

location @unicorn { 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header Host $http_host; 
    proxy_set_header X-Real-IP $remote_addr; 
    proxy_set_header HTTP_CLIENT_IP $remote_addr; <----- 
    proxy_redirect off; 
    proxy_pass http://unicorn; 
} 

Fonte actionpack-4.2.1/lib/action_dispatch/middleware/remote_ip.rb

Linea 114:

client_ips = ips_from('HTTP_CLIENT_IP').reverse 

Linea 126:

"HTTP_CLIENT_IP=#{@env['HTTP_CLIENT_IP'].inspect} " + 
4

Per ELB - nginx - rotaie si vuole seguire questa guida:

http://engineering.blopboard.com/resolving-real-client-ip-with-amazon-elb-nginx-and-php-fpm

See:

server { 
    listen 443 ssl spdy proxy_protocol; 

    set_real_ip_from 10.0.0.0/8; 
    real_ip_header proxy_protocol; 

    location /xxx { 
    proxy_http_version 1.1; 
    proxy_pass <api-endpoint>; 
    proxy_set_header  Host    $http_host; 
    proxy_set_header  X-Forwarded-By $server_addr:$server_port; 
    proxy_set_header  X-Forwarded-For $remote_addr; 
    proxy_set_header  X-Forwarded-Proto $scheme; 
    proxy_set_header  X-Real-IP   $remote_addr; 
    proxy_set_header  CLIENT_IP   $remote_addr; 
    proxy_pass_request_headers on; 
    } 
    ... 
+0

Grazie! Stava avendo un problema che l'app stava ricevendo "unicorno" come HTTP_HOST così durante il reindirizzamento Rails stava reindirizzando a 'http: // unicorn/posts' vs' http: // MY_SERVER/posts' e questo ha risolto il mio problema. – pcasa

+0

@todd Il link alla bacheca non è valido – TheRealMrCrowley