Nginx ฉันจะปฏิเสธคำขอไปยังเซิร์ฟเวอร์เสมือน ssl ที่ไม่แสดงรายการได้อย่างไร


14

ฉันมีใบรับรองไวด์การ์ด SSL และโดเมนย่อยหลายรายการใน IP เดียวกัน ตอนนี้ฉันต้องการให้ nginx ของฉันจัดการเฉพาะชื่อเซิร์ฟเวอร์ที่กล่าวถึงและการเชื่อมต่อแบบหล่นสำหรับผู้อื่นเพื่อให้ดูเหมือนว่า nginxไม่ทำงานสำหรับชื่อเซิร์ฟเวอร์ที่ไม่แสดง (ไม่ตอบสนองปฏิเสธปฏิเสธไม่ใช่หนึ่งไบต์ในการตอบสนอง) ฉันทำต่อไปนี้

ssl_certificate         tls/domain.crt;
ssl_certificate_key     tls/domain.key;

server {
  listen 1.2.3.4:443 ssl;
  server_name validname.domain.com;
  //
}

server {
  listen 1.2.3.4:443 ssl;
  server_name _;
  // deny all;
  // return 444;
  // return 404;
  //location {
  //  deny all;
  //}
}

ฉันได้ลองเกือบทุกอย่างในบล็อกเซิร์ฟเวอร์ล่าสุด แต่ไม่สำเร็จ ฉันได้รับการตอบสนองที่ถูกต้องจากเซิร์ฟเวอร์เสมือนที่รู้จักหรือรหัสข้อผิดพลาด กรุณาช่วย.

คำตอบ:


7

วิธีนี้ใช้ไม่ได้: การจับมือ SSL เกิดขึ้นก่อน HTTP ดังนั้นชื่อบนใบรับรองจะได้รับการประเมินในเบราว์เซอร์ก่อนที่คุณจะสามารถเปลี่ยนเส้นทางหรือทำสิ่งอื่นใดภายในการกำหนดค่า nginx


มันไม่ดี แต่ต้องยอมรับ) ขอบคุณ
andbi

3
สิ่งนี้ไม่เป็นความจริง: คุณสามารถทำสิ่งอื่นในระดับที่ต่ำกว่าได้เช่นการเชื่อมต่อที่ไม่มีการตอบสนองใด ๆ ดังอธิบายในคำตอบอื่น ๆ
collimarco

14

คำตอบโดย cjc ชี้ให้เห็นปัญหาอย่างถูกต้องแล้วกับการพยายามจับคู่ชื่อโฮสต์เมื่อเปิดใช้งาน SSL อย่างไรก็ตามมันเป็นไปได้ที่จะทำเช่นนี้:

server {
    ...

    if ($host !~* ^validname\.domain\.com$ ) {
        return 444;
    }
    ...
}

หมายเหตุ: ใช่มันเป็นความจริงที่โดยทั่วไปแล้วifเป็นความชั่วร้ายแต่ก็ปลอดภัยที่จะใช้ifในกรณีนี้ (อ่านหน้าเชื่อมโยงหากคุณต้องการโน้มน้าวตัวเอง)

ตรงกันข้ามกับสิ่งที่ได้รับการแนะนำเพียงแค่เพิ่มบล็อกต่อไปนี้จะไม่ทำงาน:

server {
    listen 80;
    listen 443 ssl;
    return 444;
}

เนื่องจากใบรับรอง SSL ที่ตรงกันvalidname.domain.comไม่ตรงกับชื่อโดเมนสุ่ม ฉันได้ลองแล้วและ nginx ก็ทำตัวเหมือนบล็อกไม่มีอยู่เลย

สิ่งนี้จะไม่ทำงาน:

server {
    listen       443;
    server_name    _;
    return 444; 
}

เพราะมันจะทำให้การเชื่อมต่อ HTTPS ทุกครั้งที่พอร์ต 443 ล้มเหลวแม้แต่สิ่งที่ควรทำ ฉันก็ลองอันนี้เหมือนกัน wgetรายงานข้อผิดพลาด SSL handshake


คำตอบนี้ถูกต้องอย่างแน่นอน สำหรับผู้ที่สงสัยคุณควรเพิ่มส่วนนี้ในการกำหนดค่าเซิร์ฟเวอร์ที่ใช้งานได้ ดังนั้นสำหรับการกำหนดค่าเริ่มต้นของหัวข้อจะเป็นเซิร์ฟเวอร์ {Listen 443 ssl; server_name validname.domain.com; if ($ host! ~ * ^ validname \ .domain \ .com $) {return 444; }}
Ivan Yaremchuk

6

คำตอบส่วนใหญ่ที่นี่เป็นเรื่องเกี่ยวกับสาเหตุที่ใช้งานไม่ได้ไม่ใช่วิธีการทำงาน

นี่คือวิธี - คุณต้องทำให้เซิร์ฟเวอร์ catch-all เป็น 'default_server' และต้องระบุพา ธ ไปยังใบรับรอง / คีย์เพื่อให้สามารถถอดรหัสการร้องขอ ssl ขาเข้าและจับคู่ส่วนหัวโฮสต์:

server {
    listen 80 default_server;
    listen 443 ssl default_server;
    server_name _;
    ssl_certificate <path to cert>;
    ssl_certificate_key <path to key>;
    return 404;
}

จดบันทึก ssl_certificate / ssl_certificate_key ตรงนั้น หากไม่ได้ระบุไว้ nginx จะพยายามใช้ default_server ดังกล่าวและล้มเหลวเนื่องจากไม่สามารถยอมรับการเชื่อมต่อ ssl โดยไม่มีใบรับรอง / คีย์ หนึ่งสามารถใช้ใบรับรอง / คีย์ใด ๆ เช่นลงนามด้วยตนเอง ...

วิธีสร้างใบรับรองที่ลงนามเอง:

openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365 

ดู/server//a/841643/87439


1
คุณเคยลองสิ่งนี้หรือไม่? คุณจะสร้างใบรับรอง SSL ที่ตรงกับชื่อเซิร์ฟเวอร์ของ "_" ได้อย่างไร
Tim

ใช่วิธีนี้ใช้ได้สำหรับฉัน ฉันมีปัญหาที่แน่นอนเหมือนกันและคิดจากเอกสารที่ nginx ต้องการใบรับรอง / คีย์เนื่องจากไม่ได้ดู TLS SNI คุณสามารถใช้ใบรับรอง / คีย์ใด ๆ เช่นลงนามด้วยตนเอง
andreycpp

1

ฉันนำวิธีการแก้ปัญหาข้างต้นมาใช้ในวันนี้และมันก็ทำงานได้ดี ไม่ได้ระบุ URL ทั้งหมดจะถูกลบตอนนี้ การวางรหัสเซิร์ฟเวอร์นี้ก่อนรายการเซิร์ฟเวอร์เสมือนจริงคือกุญแจ - URL ที่มีรูปแบบไม่ถูกต้องทั้งหมดตอนนี้ไปที่เซิร์ฟเวอร์ 'ค่าเริ่มต้น'

... 
server {
     listen       443;
     server_name    _;
     return 444; }

server {
     listen       443;
     server_name  [URL]

0

คุณควรจะสามารถจัดการสิ่งนี้ได้โดยการทำให้เซิร์ฟเวอร์ที่จัดการรายการที่ไม่อยู่ในรายการบล็อกเซิร์ฟเวอร์แรกในการกำหนดค่าของคุณ

http {
    ...

    server {
        listen 80;
        listen 443 ssl;
        return 444;
    }

    server {
        server_name validname.domain.com;
        ...
    }
}

โดเมนทั้งหมดที่ไม่ได้ระบุเฉพาะจะถูกจัดการโดยบล็อกเซิร์ฟเวอร์นี้


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