nginxプロキシの背後にあるピラミッドサーバーでクライアントの実際のIPを取得する方法

StackOverflow https://stackoverflow.com/questions/9380088

質問

使用するピラミッドアプリケーションがあります request.environ['REMOTE_ADDR'] いくつかの場所で。

アプリケーションは、ポート6543のPython Pasteによって提供され、ポート80でリスニングされるNginxサーバーは、Pasteサーバーへのリクエストを転送しています。

Nginx構成は、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;

    }

Pyramidアプリケーションでは、変数要求.Environ ['Remote_Addr']は常に127.0.0.1に等しくなりました。この問題を解決するためのいくつかの戦略が見られますが、それを行うための推奨方法があるかどうかはわかりません。

これが私が検討していることです:

  • 必要に応じて、request.environ ['remote_addr']を置き換えるnewRequestサブスクライバーを追加します。

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

  • WSGIミドルウェアを使用して、ピラミッド層を押す前にrequest.environを変更します。

  • 何か他のもの

ピラミッドアプリケーションの展開にどの戦略を使用していますか? 2つのnginxプロキシがある場合はどうなりますか? (最初のLANを提供し、2番目の1つはインターネットに直接接続されたマシンを提供します)。

役に立ちましたか?

解決

使用する場合 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

他のヒント

Nginxの背後にあるGeventサーバーを使用し、使用します request.client_addr クライアントのIPアドレスを取得します。

WSGI Piplineを持っていない場合、または使用したくない場合 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)

そして、あなたのプロキシがヘッダーを設定することを確認してください

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

PHPでは私がします:

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

おそらくPythonでは似ています、$ IPはあなたの本当のIPです

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top