ฉันจะตรวจสอบได้อย่างไรว่าเซิร์ฟเวอร์ใช้ SNI สำหรับ HTTPS หรือไม่


41

ฉันกำลังมองหาวิธีง่ายๆในการทราบว่าเซิร์ฟเวอร์ใช้ส่วนขยายชื่อเซิร์ฟเวอร์สิ่งบ่งชี้ SSL สำหรับใบรับรอง HTTPS บนเว็บไซต์หรือไม่ วิธีการที่ใช้ทั้งเบราว์เซอร์หรือบรรทัดคำสั่ง Unix นั้นใช้ได้

ขอบคุณ!

คำตอบ:


20

SNI เริ่มต้นโดยไคลเอนต์ดังนั้นคุณต้องมีไคลเอนต์ที่รองรับ เบราว์เซอร์ของคุณจะไม่ทำงานเว้นเสียแต่ว่าคุณจะอยู่บน windows XP หากไคลเอนต์ของคุณให้คุณดีบักการเชื่อมต่อ SSL อย่างถูกต้อง (น่าเศร้าแม้แต่คำสั่ง gnutls / openssl CLI ก็ไม่สามารถทำได้) คุณสามารถดูได้ว่าเซิร์ฟเวอร์ส่งเขตข้อมูล server_name กลับมาในสวัสดีแบบขยาย โปรดทราบว่าการไม่มีฟิลด์นี้หมายความว่าเซิร์ฟเวอร์ไม่ได้ใช้ server_name ในไคลเอนต์สวัสดีเพื่อช่วยเลือกใบรับรองไม่ใช่ว่ามันไม่สนับสนุน

ดังนั้นในทางปฏิบัติการทดสอบที่ง่ายที่สุดคือลองเชื่อมต่อ สำหรับสิ่งนี้คุณต้องรู้ชื่อสองชื่อที่แก้ไขเป็น IP เดียวกันซึ่งสามารถเชื่อมต่อ ssl ได้ https นั้นง่ายที่สุดเนื่องจากคุณสามารถเรียกดูทั้งชื่อและดูว่าคุณได้รับใบรับรองที่ถูกต้องหรือไม่

มีสามผลลัพธ์:

  • คุณได้รับใบรับรองไวด์การ์ด (หรือใบรับรองที่มีหัวเรื่องAltName) ซึ่งครอบคลุมทั้งสองชื่อ: คุณไม่ได้เรียนรู้อะไรเลย
  • คุณได้รับใบรับรองที่ผิดสำหรับอย่างน้อยหนึ่งใบรับรอง: เซิร์ฟเวอร์ไม่รองรับ SNI หรือมีการกำหนดค่าผิด
  • คุณได้รับใบรับรองสองใบที่แตกต่างกันทั้งชื่อที่ถูกต้อง: รองรับ SNI และกำหนดค่าอย่างถูกต้อง

การทดสอบที่ซับซ้อนขึ้นเล็กน้อยซึ่งจะให้ข้อมูลมากขึ้นคือเปิด wireshark และจับภาพขณะเรียกดู จากนั้นคุณสามารถค้นหาแพ็กเก็ตที่เกี่ยวข้องได้โดยการกรอง ssl.handshake ภาพหน้าจอด้านล่างเป็นตัวอย่างของคู่สวัสดี / เซิร์ฟเวอร์สวัสดีลูกค้าที่รองรับ SNI:

สวัสดีลูกค้า เซิร์ฟเวอร์สวัสดี

แน่นอนว่าไม่มีฟิลด์ server_name ในเซิร์ฟเวอร์ hello ไม่ได้ระบุว่าไม่รองรับ SNI โดยที่ server_name ที่ไคลเอ็นต์ระบุนั้นไม่ได้ใช้ในการตัดสินใจว่าจะใช้ใบรับรองใด


9
เดนนิส - opensslไม่เห็นด้วยกับ รายละเอียดบางอย่างที่มีอยู่: openssl s_client -servername alice.sni.velox.ch -tlsextdebug -msg -connect alice.sni.velox.ch:443บ่งชี้บางอย่างของการใช้ SNI จะได้รับในช่วง Qualys ทดสอบ SSL
Deer Hunter

อาฉันคิดถึงสิ่งนั้นใน manpage ขอบคุณสำหรับการเพิ่ม
เดนนิส Kaarsemaker

26

ซับในที่คุณอาจต้องการตรวจจับการมีส่วนหัวของส่วนขยายบ่งชี้ชื่อเซิร์ฟเวอร์ SSL / TLS คือ:

openssl s_client -servername www.SERVERNAME.com -tlsextdebug -connect www.YOURSERVER.com:443 2>/dev/null | grep "server name"

ซึ่งwww.SERVERNAME.comเป็นค่า SNI ที่คุณกำลังทดสอบและwww.YOURSERVER.comเป็นชื่อโดเมนหรือที่อยู่ IP ของเซิร์ฟเวอร์ที่รองรับ TLS ที่คุณกำลังทดสอบ

บรรทัดคำสั่งการใช้งานopenssl's s_client(ดูs_client (1) ) เพื่อเชื่อมต่อไปยังเซิร์ฟเวอร์ที่พอร์ตwww.YOURSERVER.com ผลัดตัวเลือกในการส่งออกขยาย TLS แก้จุดบกพร่อง ตัวเลือกที่บอกโปรแกรมที่จะผ่านเป็นค่าของสนาม SNI ในแพ็คเก็ต ClientHello ในช่วงการจับมือกัน TLS443-tlsextdebug-servernames_clientwww.SERVERNAME.com

ในที่สุด2>/dev/nullก็เพียงซ่อนเอาท์พุท stderr (ซึ่งอาจมีเสียงดัง) และ| grep "server name"ไปป์ไลน์ตัวกรอง stdout เพื่อแสดงนามสกุล TLS ที่เรียกว่า "ชื่อเซิร์ฟเวอร์" ในการs_clientแก้ไขจุดบกพร่องส่วนขยาย TLS ของ TLS

หากคุณเห็นบรรทัดของเอาต์พุตเช่น

TLS server extension "server name" (id=0), len=0

เซิร์ฟเวอร์จะส่งคืนข้อมูลส่วนหัว SNI ในการตอบกลับของ ServerHello หากคุณไม่ทำเช่นนั้นอาจเป็นไปได้ว่าเซิร์ฟเวอร์ไม่รองรับ SNI หรือไม่ได้รับการกำหนดค่าให้ส่งคืนข้อมูล SNI ตามชื่อที่คุณต้องการ ในกรณีนี้ให้ตรวจสอบอีกครั้งว่าคุณใช้ชื่อโดเมนใน-servernameตัวเลือกที่เซิร์ฟเวอร์ควรตอบกลับด้วยข้อมูล SNI เกี่ยวกับ


1
เอาท์พุทเหมือนกันไม่ว่าฉันจะใช้ถูกต้อง-servernameหรือไม่ -servername sdfsdlkfjsdf23.somedomain.somewhere -connect realhost.somedomain.somewhere= TLS server extension "server name" (id=0), len=0(และผลลัพธ์เดียวกันถ้าจับคู่กัน) คุณจะตรวจสอบได้อย่างไรว่ามันไม่ตรงกับโฮสต์บนเซิร์ฟเวอร์จากเอาต์พุต
bshea

1
@ bshea คุณต้องผ่าน-msgนอกเหนือจากพารามิเตอร์ด้านบนและ grep สำหรับ "Alert" หาก-servernameผิดคุณจะได้รับสิ่งที่ชอบTLS 1.2 Alert ... warning unrecognized_nameจากเซิร์ฟเวอร์ @Meitar ฉันคิดว่าถ้าคุณเพิ่มเข้าไปในคำตอบจะเป็นประโยชน์สำหรับคนอื่น ๆ
Viktor Nonov

@ViktorNonov -msgสวิตช์เพียงเพิ่ม hexdump ของข้อความโปรโตคอล TLS ไม่จำเป็นต้องสังเกตข้อผิดพลาดของการจับมือกันของ TLS ดังนั้นจะเพิ่มคำตอบนี้ไม่ถูกต้อง นอกจากนี้ข้อผิดพลาดการจับมือ TLS เช่นนี้จะถูกพิมพ์ไปยัง STDOUT ซึ่งหมายความว่า2>/dev/nullจะต้องลบออกจากคำตอบเพื่อให้สามารถดำเนินการได้grepในตอนแรก สิ่งที่ @bshea กำลังถามหาคือ "ฉันจะตรวจสอบข้อผิดพลาด TLS ได้อย่างไร" ซึ่งเป็นคำถามที่แตกต่างกันอย่างสิ้นเชิงกับคำถามของ "เซิร์ฟเวอร์นี้ใช้คุณสมบัติ SNI ของโปรโตคอล TLS หรือไม่" ซึ่งเป็นหัวข้อที่นี่
Meitar

@ Meitar ฉันไม่สามารถหาวิธีอื่นในการสังเกตข้อความจับมือ TLS นอกจากนี้แม้ว่าฉันเปลี่ยนเส้นทางSTDERRไปยังไฟล์ข้อความฉันไม่ได้รับข้อผิดพลาดนั้น หาก-msgฉันไม่พบตัวเลือกอื่นที่แสดงข้อความจับมือ (ใช้ openssl 1.0.2q) ตราบใดที่ความเกี่ยวข้องกับคำตอบคุณอาจถูกต้อง
Viktor Nonov

-2

คุณสามารถใช้opensslเพื่อดึงข้อมูลและสอบถามใบรับรอง

  • เรียกใบรับรองด้วย openssl s_client -connect
  • แยกใบรับรองด้วย openssl x509
  • grep เพื่อค้นหาข้อมูล "DNS:"

openssl s_client -connect alice.sni.velox.ch:443 | openssl x509 -noout -text | grep DNS:

% openssl s_client -connect alice.sni.velox.ch:443 | openssl x509 -noout -text | grep DNS:
depth=2 C = BM, O = QuoVadis Limited, CN = QuoVadis Root CA 2
verify return:1
depth=1 C = BM, O = QuoVadis Limited, CN = QuoVadis Global SSL ICA G2
verify return:1
depth=0 C = CH, ST = Zuerich, L = Zuerich, O = Kaspar Brand, CN = alice.sni.velox.ch
verify return:1
                DNS:alice.sni.velox.ch, DNS:carol.sni.velox.ch

บรรทัดสุดท้ายแสดงรายการ SNI ทั้งหมดที่มีอยู่ในหนังสือรับรอง:

                DNS:alice.sni.velox.ch, DNS:carol.sni.velox.ch

ฉันกำลังมองหาอะไรในผลลัพธ์นั้น? ความจริงที่ว่ามีหลายโดเมนอยู่?
spookylukey

DNS:... รายการในบรรทัดสุดท้ายแสดงทั้งหมดชื่อ SNI ที่ถูกต้องในใบรับรอง
spazm

4
SANs ในใบรับรองและการสนับสนุน SNI บนเซิร์ฟเวอร์นั้นแตกต่างกันการใช้ SANs สำหรับ HTTPS virtualhosting เป็นสิ่งที่แฮ็คที่มีมาก่อน SNI สำหรับ SNI คุณไม่จำเป็นต้องใช้ใบรับรองกับ SAN เนื่องจากเซิร์ฟเวอร์สามารถเลือกใบรับรองแต่ละรายการที่ตรงกับความต้องการในการตั้งชื่อของลูกค้า
mr.spuratic
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.