วิธีปฏิเสธการเข้าถึงทรัพยากรตามส่วนหัว X-forwarded-for


13

ฉันพยายาม จำกัด การเข้าถึงทรัพยากรที่อยู่เบื้องหลัง Nginx โดยอ้างอิงจาก IP ของลูกค้าที่ส่งผ่านในส่วนหัว X-forwarded-for Nginx กำลังทำงานอยู่ในคอนเทนเนอร์บน Kubernetes Cluster บน Google Cloud Platform และ ips ไคลเอ็นต์จริงจะถูกส่งผ่านในส่วนหัวแบบส่งต่อสำหรับ x เท่านั้น

จนถึงตอนนี้ฉันจัดการเพื่อทำ 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_addrและallow/ denydirectives ได้โดยใช้ที่อยู่ 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 ฉันพบสิ่งต่อไปนี้: X-Forwarded-For: <unverified IP(s)>, <immediate client IP>, <global forwarding rule external IP>, <proxies running in GCP> (requests only) รายการ <ทันทีไคลเอ็นต์ IP> คือไคลเอนต์ที่เชื่อมต่อโดยตรงกับตัวโหลดบาลานซ์
p1hr

1
เพื่อให้สามารถใช้งานได้คุณจะต้องระบุช่วงที่อยู่<global forwarding rule external IP>และ<proxies running in GCP>และเพิ่มset_real_ip_fromคำสั่งที่ครอบคลุมทั้งหมด
Richard Smith

<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"โดยที่ ccc.ccc.ccc.ccc เป็นกฎการส่งต่อทั่วโลก bbb.bbb.bbb.bbb.bbb ลูกค้าทันที ip - จับคู่สิ่งที่ฉันเห็นใน whatsmyip.org โอกาสใดที่คุณสามารถแนะนำวิธีการแยกส่วนนั้น
p1hr

1
ตกลงตอนนี้ฉันเริ่มสับสน คุณต้องให้ที่อยู่set_real_ip_fromทั้งหมดทางด้านขวาของที่อยู่ที่คุณต้องการอนุญาต / ปฏิเสธ ตามที่ระบุไว้ในreal_ip_recursiveส่วน
Richard Smith

5

คำตอบของ Richard มีข้อมูลเกี่ยวกับวิธีการรับที่อยู่ 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 อยู่ในเครือข่ายย่อย192.168.168.0/24จากนั้น$allowจะได้รับค่า 1 และคำขออนุญาต

คุณสามารถมีหลายบรรทัดในgeoบล็อกตามที่คุณต้องการเพื่อกำหนดช่วง IP ของคุณ


ขอบคุณ! ที่ดูเหมือนจะทำงานได้ดีจริงๆสิ่งสุดท้ายที่ฉันเผชิญคือ client_ip จาก X-forwarded-for ในขณะนี้มีการใช้งานจาก 3 ที่อยู่ IP ที่ส่งผ่านล่าสุด ฉันได้เพิ่มreal_ip_recursive on;ด้านล่างset_real_ip_fromแต่ก็ไม่ได้สร้างความแตกต่างใด ๆ
p1hr

คุณหมายถึงX-Forwarded-Forส่วนหัวของคุณมีสามที่อยู่แยกจากกันนั่นคือคำขอมาจากหลายผู้รับมอบฉันทะ? คุณมีส่วนหัวอื่น ๆ ที่นั่นคุณสามารถใช้ซึ่งมีเพียง IP ของลูกค้า?
Tero Kilkanen

พร็อกซีทุกคนในเครือจะผนวกที่อยู่ IP ของมันไว้ที่X-Forwarded-Forส่วนหัว นอกเหนือจากการเพิ่มreal_ip_recursive onคุณยังต้องเพิ่มset_real_ip_fromคำสั่งสำหรับที่อยู่ IP ของเซิร์ฟเวอร์ที่เชื่อถือได้แต่ละรายการในเชนพร็อกซีของคุณ Nginx จะทำงานผ่านแต่ละคำสั่งเหล่านี้และคืนค่า IP ของไคลเอ็นต์เป็นค่าแรกที่พบในX-Forwarded-Forส่วนหัวซึ่งไม่ตรงกับset_real_ip_fromค่าที่คุณระบุ
miknik

FWIW ชุดค่าผสมนี้ใช้ไม่ได้สำหรับฉันกับ AWS ALB สิ่งที่ทำงานคือการใช้คำสั่งพร็อกซีภายในบล็อกทางภูมิศาสตร์โดยมี IP เดียวกันกับ set_real_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.
    }

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.