ทำไมต้องฟัง 443 default_server การแทนที่กฎ nginx กฎที่กำหนดค่าไว้แล้ว (กฎ http ทำงานปกติ)


9

ฉันมี nginx และโดเมนย่อยต่างกัน:

a.mydomain.com
b.mydomain.com
c.mydomain.com

Nginx มีกฎ 4 ข้อ:

1) เขียนกฎใหม่:

server {
  listen 80
  server_name gl.udesk.org;

  root /nowhere;
  rewrite ^ https://a.mydomain.com$request_uri permanent;
}

2) กฎ https:

server {

  listen 443;
  server_name a.mydomain.com;

  root /home/a/a/public;

  ssl on;
  ssl_certificate conf.d/ssl/a.crt;
  ssl_certificate_key conf.d/ssl/a.key;
  ssl_protocols ...
  ssl_ciphers ...
  ssl_prefer_server_ciphers on;

  location ...
}

3) กฎเริ่มต้น http:

server {
  listen 80 default_server;
  return 444;
}

4) กฎเริ่มต้น https:

server {
  listen 443 default_server;
  return 444;
}

ดังนั้นถ้าฉันเริ่ม nginx และ:

  • ถ้าฉันไปที่เบราว์เซอร์เพื่อhttp://a.mydomain.comจะเปลี่ยนเส้นทางไปที่ https://a.mydomain.comและจากนั้นจะส่งคืนข้อผิดพลาด 107 (สุทธิ :: ERR_SSL_PROTOCOL_ERROR): ข้อผิดพลาดของโปรโตคอล SSL
  • ถ้าฉันไปในเบราว์เซอร์เพื่อhttps://b.mydomain.comฉันคาดว่าจะส่งคืนข้อผิดพลาด 444 กลับ แต่จะส่งกลับข้อผิดพลาด 107 เดียวกัน (สุทธิ :: ERR_SSL_PROTOCOL_ERROR): ข้อผิดพลาดของโปรโตคอล SSL แทน
  • ดังนั้นสำหรับการลงทะเบียนทั้งหมดโดยผู้ให้บริการ DNS CNAME (เช่น a, b, c)
  • http- เวอร์ชันทั้งหมด (เช่นกฎ 3 -) ทำงานตามที่คาดไว้:

ดังนั้นทำไมกฎ https ในnginxจึงยุ่งยากในการกำหนดค่าและฉันควรกำหนดค่าให้เหมาะสมเพื่อให้มีพฤติกรรมเช่นเดียวกับรุ่น http หรือไม่

ปรับปรุง:

การสร้างใบรับรองใหม่และการเพิ่ม:

ssl on;
ssl_certificate conf.d/ssl/default.crt;
ssl_certificate_key conf.d/ssl/default.key;

ใช้งานได้ แต่ฉันจะมีทางออกโดยไม่ต้องใช้ใบรับรอง SSL ใด ๆ เพียงรีเซ็ตการเชื่อมต่อทั้งหมดสำหรับโดเมนย่อย https (พอร์ต 443) ทั้งหมดยกเว้นhttps://a.mydomain.com โดยไม่ต้องให้ใบรับรอง


2
คุณทำไม่ได้ SSL ต้องการใบรับรองก่อนที่เว็บเซิร์ฟเวอร์จะรู้ว่าคุณต้องการโดเมนใด ต้องมีใบรับรองเพื่อส่งหรือไม่สามารถสร้างการเชื่อมต่อเพื่อพูดคุยกับลูกค้า
Darth Android

2
@DarthAndroid: ความมหัศจรรย์ที่เรียกว่า SNI - en.wikipedia.org/wiki/Server_Name_Indication
Shi

@Shi ฉันรู้ SNI - ที่ช่วยให้เว็บเซิร์ฟเวอร์ที่จะเลือกที่ใบรับรองการส่ง แต่ก็ยังต้องเลือกใบรับรอง ไม่ฉลาดพอที่จะรู้ว่าไม่ต้องการใบรับรองสำหรับสิ่งที่ผู้ใช้ต้องการทำ nginx
Darth Android

คำตอบ:


3

อย่าผสมพอร์ต 443 กับ ssl! Nginx เป็นผู้ไม่เชื่อเรื่องพระเจ้าอย่างสมบูรณ์พอร์ต คุณสามารถเสนอ https ผ่านพอร์ต 80 ได้เช่นกัน อนุญาตรุ่น nginx ที่ทันสมัย

listen 1234 ssl;

และคุณไม่ต้องการssl on;บรรทัด

แต่ถ้าคุณต้องการให้บริการ https คุณต้องระบุใบรับรอง เซิร์ฟเวอร์ของคุณเข้าสู่ https เมื่อเขียนคำขอ http เป็นคำขอ https อีกครั้ง

คุณได้รับข้อผิดพลาด PROTOCOL เนื่องจาก SSL Handshake เสร็จสิ้นก่อนสิ่งอื่นใด ดังนั้นreturn 444ไม่ถึง และ SSL Handshake ใด ๆ จะต้องมี ceritificate และไพรเวตคีย์เพื่อป้อนอัลกอริธึมการเข้ารหัสด้วยคู่ใบรับรอง / ไพรเวตคีย์


3

returnสั่งเป็นส่วนหนึ่งของโมดูลเขียน หากคุณตรวจสอบเอกสารคุณอาจเห็นว่ามันใช้งานได้กับการร้องขอ ในคำขอ HTTPS สามารถทำได้หลังจากจับมือเสร็จแล้วเท่านั้น

มีคำขอคุณสมบัติ: https://trac.nginx.org/nginx/ticket/195และมีวิธีแก้ไขปัญหาให้

server {
    listen 443 ssl;
    server_name bbb.example.com;
    ssl_ciphers aNULL;
    ssl_certificate /path/to/dummy.crt;
    ssl_certificate_key /path/to/dummy.key;
    return 444;
}

หมายเหตุนี้จะทำลายไม่ใช่ SNI ที่รองรับลูกค้า HTTPS (เช่น Nginx ของตัวเองproxy_passถ้าคุณตั้งค่าproxy_ssl_server_name on;) จากการเข้าถึงอื่น ๆserver_names(เพื่อเป็นหลักทำลายถูกต้องตามกฎหมายserver_nameของที่คุณไม่ต้องการที่จะปล่อยให้ผ่านไป) ดูtrac.nginx.org/nginx/ticket/195#comment:11สำหรับรายละเอียด
nh2
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.