X-forwarded-forヘッダーに基づいてリソースへのアクセスを拒否する方法


13

X-forwarded-forヘッダーで渡されたクライアントIPに基づいて、Nginxの背後にあるリソースへのアクセスを制限しようとしています。NginxはGoogle Cloud Platform上のKubernetesクラスター上のコンテナーで実行されており、実際のクライアントIPはx-forwarded-forヘッダーのみで渡されます

これまでのところ、次のコードを使用して1つのIPに対してそれを行うことができました。

set $allow false;
if ($http_x_forwarded_for ~* 123.233.233.123) {
    set $allow true;
}
if ($http_x_forward_for ~* 10.20.30.40) {
    set $allow false;
}
if ($allow = false) {
    return 403;
}

しかし、IPの全範囲に対してこれを行うにはどうすればよいですか?数百のIPを手動で指定するのはあまり意味がありません。

すべての助けに感謝します

回答:


11

RealIPモジュールを使用して、X-Forwarded-Forヘッダーの値を尊重します。設定するset_real_ip_fromリバースプロキシ(現在の値のIPアドレスに$remote_addr)。

例えば:

server {
    ...
    real_ip_header X-Forwarded-For;
    set_real_ip_from 10.1.2.3;
    ...
}

これで、使用することができるはず$remote_addrallow/ denyクライアントの本当のIPアドレスを使用してディレクティブ。詳細については、このドキュメントを参照してください。


だから私は次のことを試みましたが無駄でした、私はそれを混乱させていますか? location / { real_ip_header X-Forwarded-For; set_real_ip_from 10.0.0.0/8; real_ip_recursive on; allow xxx.xxx.xxx.xxx;
-p1hr

Google Load Balancingのドキュメントを確認したところ、次のことがわかりましたX-Forwarded-For: <unverified IP(s)>, <immediate client IP>, <global forwarding rule external IP>, <proxies running in GCP> (requests only) 。<immediate client IP>エントリは、ロードバランサーに直接接続したクライアントです。
-p1hr

1
このために仕事に、あなたがのためにアドレス範囲を特定するために必要<global forwarding rule external IP><proxies running in GCP>して追加しset_real_ip_from、それらのすべてをカバーするステートメントを。
リチャードスミス

<global forwarding rule external IP>私のサービスの外部IPであり、GCPには他のプロキシはありません、nginxのログには次の形式のリクエストがあり[31/Jul/2017:20:05:46 +0000] "GET / HTTP/1.1" 403 169 "-" "curl/7.54.0" "aaa.aaa.aaa.aaa, bbb.bbb.bbb.bbb, ccc.ccc.ccc.ccc"ます。 ip-whatsmyip.orgに表示されるものと一致します。その部分を抽出する方法をアドバイスできますか?
-p1hr

1
わかりました、今私は混乱しています。あなたがする必要がありset_real_ip_from、あなたができるようにしたい1の右側にあるアドレスのすべてのために/拒否。real_ip_recursiveセクションに示されているとおり。
リチャードスミス

5

リチャードの回答には、実際のIPアドレスをnginxに最適に取得する方法に関する情報がすでに含まれていました。

一方、IP範囲を指定する際に問題になるのは、http://nginx.org/en/docs/http/ngx_http_geo_module.htmlを使用することです。

geoモジュールは次のように動作しmap、変数はIPアドレスの値に応じて値が割り当てられますされるモジュール。

例:

geo $allow {
    default 0;
    192.168.168.0/24 1;
}

server {
    real_ip_header X-Forwarded-For;
    set_real_ip_from 10.1.2.3;

    if ($allow = 0) {
        return 403;
    }
}

ここで、geoマップを割り当てます。デフォルト値$allowは0 です。IPアドレスがsubnetにある場合192.168.168.0/24$allow値1が取得され、リクエストが許可されます。

geoIP範囲を定義するのに必要な数の行をブロックに含めることができます。


ありがとうございました!それは本当にうまくいくようです、私が直面している最後の1つは、X-forwarded-forのclient_ipです。現時点では、渡された3つのIPアドレスから最後のIPアドレスが使用されます。real_ip_recursive on;以下に追加しましたset_real_ip_fromが、違いはありません
-p1hr

あなたの意味するかX-Forwarded-For、要求が複数のプロキシを経由して来ているヘッダ3つの別々のアドレスを持っているが、?クライアントIPのみを含む他のヘッダーを使用できますか?
テロキルカネン

チェーン内のすべてのプロキシは、そのIPアドレスをX-Forwarded-Forヘッダーに追加します。追加に加えreal_ip_recursive onset_real_ip_from、プロキシチェーン内の各信頼済みサーバーIPアドレスにディレクティブを追加する必要もあります。Nginxはこれらの各ディレクティブX-Forwarded-Forを処理し、指定したset_real_ip_from値のいずれとも一致しないヘッダーで最初にヒットした値としてクライアントIPを返します
-miknik

FWIW、この組み合わせはAWS ALBでうまくいきませんでした。仕事がset_real_ipと同じIPで、地理ブロック内のプロキシディレクティブを使用していた何をしたか- nginx.org/en/docs/http/ngx_http_geo_module.html
talonx

3

これらは私のために働いてくれました。

geo $remote_addr $giveaccess {
      proxy 172.0.0.0/8; <-- Private IP range here
      default 0;
      11.22.33.44 1; <-- Allowed IP here
    }


server{
##
    location ^~ /secure_url_here {
        if ($giveaccess = 0){
          return 403; 
        }
        try_files $uri $uri/ /index.php?$args; <-- Add this line specific for your CMS, if required.
    }

参照:http : //nginx.org/en/docs/http/ngx_http_geo_module.html

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.