Score:0

ไวยากรณ์คำสั่ง NGINX reverse proxy "ถ้าไม่ใช่"?

ธง us

ฉันมี nginx reverse proxy ที่ฉันต้องการเปลี่ยนเส้นทางคำขอ url ที่ไม่ใช่โดเมนระดับบนสุดของฉันไปที่ 404

จนถึงตอนนี้ฉันคิดว่าฉันต้องการสิ่งนี้ที่ด้านล่างของฉัน /etc/nginx/sites-enabled/site.conf:

เซิร์ฟเวอร์ {
        ฟัง 80;
        ถ้า ($host != *domain.com) {
                ส่งคืน 404 http://$host$request_uri;
        }
}

แต่ฉันไม่รู้ไวยากรณ์ที่แน่นอนที่นี่ ฉันมีบล็อกเปลี่ยนเส้นทางอื่นๆ ที่อยู่เหนือบล็อกนี้แล้ว ฉันแค่ต้องการให้คำขอ url สำหรับชื่อโฮสต์เฉพาะ IP หรือโดเมนอื่นๆ รับ 404 ทันทีและไม่ส่งต่อไปยังเซิร์ฟเวอร์ส่วนหลัง

นอกจากนี้ ฉันยังมี TLS passthrough ฉันต้องการทำสิ่งเดียวกัน แต่ฉันหลงทางเกี่ยวกับวิธีใช้คำสั่ง if ในการบล็อกสตรีม บล็อกสตรีมของฉันมีลักษณะเช่นนี้ใน /etc/nginx/nginx.conf:

ลำธาร {
        แผนที่ $ssl_preread_server_name $name {
                เซิร์ฟเวอร์.domain.com;
                www.domain.com www;
        }
        เซิร์ฟเวอร์ต้นน้ำ {
                แบ็กเอนด์ของเซิร์ฟเวอร์:443;
        }
        ต้นน้ำ www {
                เซิร์ฟเวอร์ backendip2:443;
        }
        เซิร์ฟเวอร์ {
                ฟัง 443;
                proxy_pass $ชื่อ;
                ssl_preread บน;
        }
}

เพื่อสิ่งนั้น ฉันจะใช้สิ่งนี้ใต้บล็อกเซิร์ฟเวอร์แรกหรือไม่

        เซิร์ฟเวอร์ {
                ฟัง 443;
                ถ้า ($ssl_preread_server_name != *domain.com) {
                        ส่งคืน 404 https://$host$request_uri;
                }
        }

ฉันคิดว่าเพื่อความปลอดภัย ฉันควรรวม default_server ในบรรทัดการฟังสำหรับบล็อกทั้งสองนี้ด้วยคำสั่ง if หรือไม่

ฉันแค่สมมติว่ามีไวยากรณ์จำนวนมากที่นี่ ดังนั้นความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชมอย่างมาก

Ivan Shatsky avatar
gr flag
คุณสามารถตรวจสอบการจับคู่แบบตรงทั้งหมด/ไม่ตรงกันบนสตริง หรือทำการจับคู่แบบตรงตามตัวพิมพ์เล็ก/ตัวพิมพ์เล็กกับรูปแบบ regex ดูเหมือนว่าคุณกำลังมองหา `if ($var !~ (.*\.)?domain\.com$) { ... }` เมื่อเร็ว ๆ นี้ฉันได้ให้คำตอบโดยละเอียดเกี่ยวกับการบล็อกการเข้าถึงทั้งหมดด้วยที่อยู่ IP แทนที่จะเป็นชื่อโฮสต์ [ที่นี่](https://stackoverflow.com/questions/69824838/block-access-with-https-ipaddress-on-nginx/69825652# 69825652).
ehammer avatar
us flag
ฉันได้ตรวจสอบโพสต์อื่นของคุณ ซึ่งช่วยในการบล็อก http ของฉัน ยังไม่แน่ใจว่าจะทำอย่างไรกับ nginx TLS passthrough (ส่งคืน 444 หาก SNI ไม่ใช่โดเมนที่แน่นอน)
Ivan Shatsky avatar
gr flag
ฉันไม่มีความรู้เกี่ยวกับโมดูลสตรีมเท่ากับฉันเกี่ยวกับ http หนึ่ง คุณไม่สามารถใช้อะไรจากโมดูลการเขียนซ้ำได้ (รวมถึง `if`) คุณไม่สามารถใช้ `return 444` ได้เนื่องจากโมดูลสตรีมมีคำสั่ง [`return`](http://nginx.org/en/docs/stream/ngx_stream_return_module.html) เป็นของตัวเองซึ่งแตกต่างจาก http อันหนึ่ง
Score:1
ธง gr

ฉันไม่รู้วิธีปิดการเชื่อมต่อกับโมดูลสตรีมอย่างสง่างาม ดังนั้นฉันไม่แน่ใจว่ามันจะเป็นวิธีแก้ปัญหาที่ถูกต้องหรือไม่ แต่ก็คุ้มค่าที่จะลอง (คุณสามารถใช้พอร์ตฟรีสำหรับเซิร์ฟเวอร์จำลอง/อัปสตรีม):

ลำธาร {
    แผนที่ $ssl_preread_server_name $name {
        เซิร์ฟเวอร์.domain.com;
        www.domain.com www;
        หุ่นจำลองเริ่มต้น;
    }
    เซิร์ฟเวอร์ต้นน้ำ {
        แบ็กเอนด์ของเซิร์ฟเวอร์:443;
    }
    ต้นน้ำ www {
        เซิร์ฟเวอร์ backendip2:443;
    }
    หุ่นต้นน้ำ {
        แบ็กเอนด์ 127.0.0.1:4343;
    }
    เซิร์ฟเวอร์ {
        ฟัง 443;
        proxy_pass $ชื่อ;
        ssl_preread บน;
    }
    เซิร์ฟเวอร์ {
        ฟัง 4343;
        กลับ "";
    }
}

อัปเดต

หลังจากทดสอบโซลูชันข้างต้นแล้ว ฉันสามารถยืนยันได้ว่าใช้งานได้จริง อย่างไรก็ตามมันสร้างรายการบันทึกข้อผิดพลาดเช่น

WSARecv() ล้มเหลว (10053: การเชื่อมต่อที่สร้างไว้ถูกยกเลิกโดยซอฟต์แวร์ในเครื่องโฮสต์ของคุณ) ขณะพร็อกซีและอ่านจากอัปสตรีม ไคลเอ็นต์: 127.0.0.1 เซิร์ฟเวอร์: 127.0.0.1:443 อัปสตรีม: "127.0.0.1:4343" , ไบต์จาก/ถึงไคลเอ็นต์:517/0, ไบต์จาก/ถึงอัปสตรีม:0/517

หลังจากคิดอยู่สักพักฉันก็ลองทำสิ่งนี้:

http {
    เซิร์ฟเวอร์ {
        ฟัง 4343 ssl;
        ssl_certificate /path/to/selfsigned.crt;
        ssl_certificate_key /path/to/selfsigned.key;
        กลับ 444;
    }
}
ลำธาร {
    แผนที่ $ssl_preread_server_name $name {
        เซิร์ฟเวอร์.domain.com;
        www.domain.com www;
        หุ่นจำลองเริ่มต้น;
    }
    เซิร์ฟเวอร์ต้นน้ำ {
        แบ็กเอนด์ของเซิร์ฟเวอร์:443;
    }
    ต้นน้ำ www {
        เซิร์ฟเวอร์ backendip2:443;
    }
    หุ่นต้นน้ำ {
        แบ็กเอนด์ 127.0.0.1:4343;
    }
    เซิร์ฟเวอร์ {
        ฟัง 443;
        proxy_pass $ชื่อ;
        ssl_preread บน;
    }
}

ใบรับรองและคีย์ที่ลงนามด้วยตนเองสามารถสร้างขึ้นได้โดยใช้คำสั่งต่อไปนี้:

openssl req -nodes -new -x509 -subj "/CN=localhost" -keyout /path/to/selfsigned.key -out /path/to/selfsigned.crt

อันนี้ปิดการเชื่อมต่ออย่างถูกต้อง

นอกจากนี้ยังใช้งานได้:

http {
    เซิร์ฟเวอร์ {
        ฟัง 80 default_server;
        กลับ 444;
    }
}
ลำธาร {
    แผนที่ $ssl_preread_server_name $name {
        เซิร์ฟเวอร์.domain.com;
        www.domain.com www;
        หุ่นจำลองเริ่มต้น;
    }
    เซิร์ฟเวอร์ต้นน้ำ {
        แบ็กเอนด์ของเซิร์ฟเวอร์:443;
    }
    ต้นน้ำ www {
        เซิร์ฟเวอร์ backendip2:443;
    }
    หุ่นต้นน้ำ {
        แบ็กเอนด์ 127.0.0.1:80;
    }
    เซิร์ฟเวอร์ {
        ฟัง 443;
        proxy_pass $ชื่อ;
        ssl_preread บน;
    }
}

แน่นอน, ขด บ่นเกี่ยวกับการพยายามจับมือกันสำหรับหมายเลขเวอร์ชัน SSL ที่ไม่ถูกต้อง และมีรายการตลกๆ ในบันทึกการเข้าถึง เช่น

127.0.0.1 - - [05/พ.ย./2021:01:04:34 +0200] "\x16\x03\x01\x02\x00\x01\x00\x01\xFC\x03\x03L\xF9[\xB2\x7F \x99\xB1(\xAC\xB4\x91}\xE2N\xC6H\xE3\xB3_\xD1\xEA\xA3C\x1D\xE5\xE5\xB6\x02\xDB\x04h\xB6 *\xCB\x0E\xC0\ xF5\xB7\xAF[y|\x1B\x14_\xC2g\xEA\xA2\x1E\xB4\xC4Bj3t\xE8d\xE72vm\xF2\x1B\x00>\x13\x02\x13\x03\x13\x01\xC0, \xC00\x00\x9F\xCC\xA9\xCC\xA8\xCC\xAA\xC0+\xC0/\x00\x9E\xC0$\xC0(\x00k\xC0#\xC0'\x00g\xC0" 400 163 "- " "-"

แต่บันทึกข้อผิดพลาดนั้นชัดเจน

ehammer avatar
us flag
ดูเหมือนว่าจะได้ผลฉันไม่เคยต้องการที่จะปิดการเชื่อมต่ออย่างสง่างาม ฉันต้องการฟังก์ชันประเภท http444 มากกว่านี้ ล้มเหลวอย่างเงียบๆ
Ivan Shatsky avatar
gr flag
@ehammer ตรวจสอบการอัปเดต
ehammer avatar
us flag
ฉันชอบมัน. ฉันมีบล็อกเริ่มต้น HTTP ที่ชี้ไปที่ 127.0.0.1:80 ถึง HTTP444 อยู่แล้ว ดังนั้นสิ่งนี้จึงรวมเข้าด้วยกันเป็นอย่างดี ตัวเลือก ```default``` ใต้บล็อกแผนที่หมายถึง default_server จริง ๆ หรือนี่เป็นเพียงชื่อตัวยึดตำแหน่ง
Ivan Shatsky avatar
gr flag
เป็นคำหลักพิเศษสำหรับบล็อกแผนที่ หมายความว่าค่านี้จะถูกส่งกลับหากไม่มีตัวแปรอื่นที่ตรงกัน หากไม่ได้ระบุไว้อย่างชัดเจน ค่าเริ่มต้นจะเป็นสตริงว่าง

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา