ฉันกำลังแก้ไขข้อบกพร่องของแอปพลิเคชันที่ใช้ Java ซึ่งดึงข้อมูลเพย์โหลด JSON (รายการ CVE จาก NIST) ผ่าน HTTPS เมื่อฉันเชื่อมต่อกับ NIST โดยตรง ฉันดึงข้อมูลได้สำเร็จ เมื่อฉันใช้พร็อกซี HTTP ฉันได้รับข้อผิดพลาด TLS "ชื่อที่ไม่รู้จัก" ซึ่งบ่งชี้ถึงปัญหาเกี่ยวกับการระบุชื่อเซิร์ฟเวอร์
ฉันไม่สามารถเข้าถึงโค้ดของแอปพลิเคชัน Java และมีความสามารถน้อยที่สุดที่จะยุ่งกับการตั้งค่า JVM ดังนั้น ฉันได้ทำการทดสอบแยกต่างหากโดยใช้ openssl โดยตรง และฉันสามารถจำลองปัญหาได้ในระดับหนึ่งด้วยสิ่งนี้
เมื่อฉัน tcpdump การโทรต่อไปนี้ ฉันเห็นส่วนขยาย server_name อยู่ในแพ็กเก็ต Client Hello:
openssl s_client -connect services.nvd.nist.gov:443
อย่างไรก็ตาม หากฉันส่งผ่าน Squid proxy และดัมพ์แพ็กเก็ตระหว่างพร็อกซีและเซิร์ฟเวอร์เป้าหมายด้วยสิ่งต่อไปนี้ จะไม่มีส่วนขยาย server_name อยู่ในแพ็กเก็ต Client Hello:
openssl s_client -เชื่อมต่อ services.nvd.nist.gov:443 -proxy myproxy:3128
คำตอบจาก openssl คือ:
140012895368512:error:14094458:รูทีน SSL:ssl3_read_bytes:tlsv1 ชื่อที่ไม่รู้จัก:../ssl/record/rec_layer_s3.c:1543:SSL alert number 112
---
ไม่มีใบรับรองเพื่อน
---
และเราจะเห็นว่าไม่มีรายการ server_name ในแพ็คเก็ต:
ฉันเชื่อว่านี่คือเหตุผลที่เซิร์ฟเวอร์เป้าหมายส่งคืนข้อผิดพลาด (แม้ว่าจากสิ่งที่ฉันเข้าใจว่าควรจะส่งคืนใบรับรองเริ่มต้นในสถานการณ์นี้)
ตอนนี้ฉันสามารถทำงานได้โดยใช้พร็อกซีโดยระบุชื่อเซิร์ฟเวอร์ด้วยตนเอง:
openssl s_client -connect services.nvd.nist.gov:443 -proxy myproxy:3128 -ชื่อเซิร์ฟเวอร์ nvd.nist.gov
ความเข้าใจของฉันคือพร็อกซีเพียงแค่ขุดอุโมงค์ข้อมูล TLS และไม่ควรแก้ไข ดังนั้นจึงแนะนำว่า openssl เลือกที่จะไม่ส่งข้อมูลส่วนขยายชื่อเซิร์ฟเวอร์เมื่อมีการใช้งานพร็อกซี ทำไมถึงเป็นเช่นนี้?
(เห็นได้ชัดว่าในกรณีของ openssl ฉันสามารถระบุพารามิเตอร์ชื่อเซิร์ฟเวอร์ได้ แต่ด้วยแอปพลิเคชัน Java ฉันไม่มีความหรูหรานี้ ฉันหวังว่าฉันจะเข้าใจว่าทำไม opensl เลือกที่จะไม่ส่งรายละเอียด SNI ผ่านพร็อกซี มันอาจจะ ให้ความกระจ่างว่าทำไม Java ถึงทำเช่นเดียวกัน)