Cara menolak akses ke sumber daya berdasarkan header X-forwarded-for

13

Saya mencoba membatasi akses ke sumber daya di balik Nginx berdasarkan IP klien yang diteruskan dalam header X-forwarded-for. Nginx berjalan dalam wadah pada Kubernetes Cluster di Google Cloud Platform dan ips klien nyata diteruskan dalam header x-diteruskan-hanya untuk header

Sejauh ini saya sudah berhasil melakukannya untuk satu IP dengan kode berikut:

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

Tetapi bagaimana saya bisa melakukan itu untuk seluruh rentang IP? Menentukan ratusan IP dengan tangan tidak masuk akal.

Semua bantuan dihargai

p1hr
sumber

Jawaban:

11

Gunakan modul RealIP untuk menghormati nilai X-Forwarded-Forheader. Setel set_real_ip_fromke alamat IP dari proxy terbalik (nilai saat ini $remote_addr).

Sebagai contoh:

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

Anda sekarang harus dapat menggunakan $remote_addrdan allow/ denymengarahkan menggunakan alamat IP yang sebenarnya dari klien. Lihat dokumen ini untuk lebih lanjut.

Richard Smith
sumber
jadi saya mencoba yang berikut ini tetapi tidak berhasil, apakah saya bingung? 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
Setelah melihat dokumen Google Load Balancing, saya menemukan yang berikut: X-Forwarded-For: <unverified IP(s)>, <immediate client IP>, <global forwarding rule external IP>, <proxies running in GCP> (requests only) Entri <direct client IP> adalah klien yang terhubung langsung ke load balancer.
p1hr
1
Agar ini berfungsi, Anda perlu mengidentifikasi rentang alamat untuk <global forwarding rule external IP>dan <proxies running in GCP>dan menambahkan set_real_ip_frompernyataan yang mencakup semuanya.
Richard Smith
<global forwarding rule external IP>adalah ip eksternal dari layanan saya, tidak ada proksi lain di GCP, pada log nginx saya, saya melihat permintaan dalam format berikut di [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"mana ccc.ccc.ccc.ccc adalah aturan penerusan global, bbb.bbb.bbb.bbb klien langsung ip - cocok dengan yang saya lihat di whatsmyip.org. Adakah peluang Anda untuk menyarankan cara mengekstrak bagian itu?
p1hr
1
Ok, sekarang saya mulai bingung. Anda perlu set_real_ip_fromuntuk semua alamat di sebelah kanan alamat yang ingin Anda izinkan / tolak. Seperti yang ditunjukkan di real_ip_recursivebagian ini.
Richard Smith
5

Jawaban Richard sudah berisi informasi tentang cara terbaik mendapatkan alamat IP asli ke nginx.

Sementara itu, apa yang muncul pada pertanyaan menentukan rentang IP, Anda dapat menggunakan http://nginx.org/en/docs/http/ngx_http_geo_module.html .

The geomodul bekerja seperti mapmodul, yaitu, variabel akan ditugaskan nilai tergantung pada nilai alamat IP.

Sebuah contoh:

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

Di sini kita menetapkan geopeta, di mana nilai default untuk $allowadalah 0. Jika alamat IP di subnet 192.168.168.0/24, maka $allowakan mendapatkan nilai 1, dan permintaan diizinkan.

Anda dapat memiliki banyak baris di geoblok yang Anda butuhkan untuk menentukan rentang IP Anda.

Tero Kilkanen
sumber
Terima kasih! yang tampaknya bekerja dengan sangat baik, satu hal terakhir yang saya hadapi adalah client_ip dari X-forwarded-for. Saat ini, dari 3 alamat ip yang dilewati yang terakhir digunakan. Saya telah menambahkan di real_ip_recursive on;bawah ini set_real_ip_fromtetapi tidak ada bedanya
p1hr
Apakah maksud Anda X-Forwarded-Fortajuk Anda memiliki tiga alamat terpisah, yaitu permintaan datang melalui beberapa proksi? Apakah Anda memiliki header lain di sana yang dapat Anda gunakan, yang hanya berisi IP klien?
Tero Kilkanen
Setiap proksi dalam rantai akan menambahkan alamat IP-nya ke X-Forwarded-Forheader. Selain menambahkan real_ip_recursive onAnda juga perlu menambahkan set_real_ip_fromarahan untuk setiap alamat IP server tepercaya dalam rantai proxy Anda. Nginx kemudian akan bekerja melalui masing-masing arahan ini dan mengembalikan IP klien sebagai nilai pertama yang hits di X-Forwarded-Forheader yang tidak cocok dengan set_real_ip_fromnilai yang Anda tentukan
miknik
FWIW, kombinasi ini tidak bekerja untuk saya dengan AWS ALB. Apa yang berhasil adalah menggunakan direktif proxy di dalam blok geo, dengan ip yang sama dengan set_real_ip - nginx.org/en/docs/http/ngx_http_geo_module.html
talonx
3

Buat ini bekerja untukku.

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

Ref: http://nginx.org/en/docs/http/ngx_http_geo_module.html

Seff
sumber