ฉันจะทำให้ apache ร้องขอใบรับรอง SSL ไคลเอ็นต์โดยไม่ต้องตรวจสอบกับ CA ที่รู้จักได้อย่างไร


9

ฉันใช้ apache2 (2.2.3) เพื่อให้บริการเว็บไซต์ที่ฉันต้องการให้ลูกค้ารับรองความถูกต้องกับใบรับรอง เนื่องจากฉันต้องการตรวจสอบว่าผู้ใช้ที่แสดงใบรับรองเฉพาะนั้นเป็นผู้ใช้รายเดียวกันซึ่งได้นำเสนอใบรับรองนั้นในอดีต CA ที่เซ็นชื่อใบรับรองนั้นไม่เกี่ยวข้อง ดูเหมือนว่าการใช้SSLVerifyClient requireต้องการSSLCACertificateFile ...(หรือSSLCACertificatePath ...) แล้ว apache จะยอมรับเฉพาะใบรับรองที่ลงนามโดย CA ในไฟล์ / พา ธ นั้น มีวิธีรับ apache ในการยอมรับใบรับรองไคลเอ็นต์ใด ๆ โดยไม่คำนึงถึง CA ที่ออก / ร้องเพลง (เช่นตรวจสอบว่าลูกค้ามีคีย์ส่วนตัวที่สอดคล้องกับกุญแจสาธารณะที่นำเสนอ แต่ไม่ต้องตรวจสอบ CA ที่ออก / ลงนาม)


คุณวางแผนในการติดตามใบรับรองใดที่รับรองความถูกต้อง
Shane Madden

@ShaneMadden: มีบางอย่างที่เหมือนกับใบรับรองการจับคู่ตารางกับ ID ผู้ใช้ภายใน กลไกของการเข้ารหัสคีย์สาธารณะจะแทนที่การแลกเปลี่ยนรหัสผ่าน
Isaac

2
ถูกต้อง - สิ่งที่ฉันได้รับคือ Apache ไม่ได้ทำใบรับรองการแมปตารางกับ ID ผู้ใช้ภายใน หากคุณกำลังจะให้ผู้ใช้รับรองความถูกต้องกับใบรับรองลูกค้าทำไมไม่ให้ใบรับรองผู้ใช้ที่คุณลงชื่อเข้าใช้ ดังที่คุณกล่าวถึงมีผู้ให้บริการ OpenID ที่ทำสิ่งนั้นอย่างแน่นอน Apache's mod_sslถูกออกแบบมาเพื่อรับรองความถูกต้องของผู้ใช้ตามความสัมพันธ์ของการลงนามใบรับรอง หากคุณต้องการเพิกเฉยด้วยเหตุผลบางประการคุณจะต้องใช้การรับรองความถูกต้องใบรับรองในรหัสของคุณเองที่จัดการการแมปใบรับรองกับผู้ใช้ของคุณด้วย
Shane Madden

@ShaneMadden: ฉันหวังว่าจะหลีกเลี่ยงการออกใบรับรองและหากฉันยอมรับเฉพาะใบรับรองที่ฉันออกให้เท่านั้นใบรับรองที่ใช้สมาร์ทการ์ดจะไม่ทำงาน ไม่ว่าฉันจะทำอะไรบางส่วนของระบบจะเกิดขึ้นในระดับแอปพลิเคชัน แต่เนื่องจากมีmod_sslเครื่องจักรทั้งหมดอยู่ที่นั่นฉันจึงหวังว่ามันจะดูแลงานบางอย่างให้ฉัน
Isaac

1
@ShaneMadden ข้อดีอย่างหนึ่งของoptional_no_caมันคือมันจะดีกว่าสำหรับ UI เนื่องจากคุณสามารถแสดงข้อความแสดงข้อผิดพลาด HTTP หากมีสิ่งผิดปกติกับใบรับรอง (คุณทำไม่ได้เป็นอย่างอื่นเนื่องจากใบรับรองลูกค้าที่ไม่ดีจะหยุดการเชื่อมต่อก่อนเลเยอร์ HTTP ) นอกจากนี้ยังมีประโยชน์หากคุณต้องการลองวิธีอื่นในการตรวจสอบใบรับรอง (เช่นWebID ) คุณพูดถูกแล้วคุณต้องการให้มีบางสิ่งที่จะทำการตรวจสอบและนั่นจะใช้ได้เฉพาะเมื่อคำขอนั้นถูกจัดการด้วยรหัส (เช่นภายใน PHP / CGI / Java) ไม่ใช่ไฟล์มากนัก
บรูโน่

คำตอบ:


10

ในขณะที่คุณได้พบคุณสามารถปิดการใช้งานการตรวจสอบใบรับรองที่เข้ารหัส SSL / TLS ระดับการจับมือกันภายใน Apache Httpd SSLVerifyCLient optional_no_caโดยใช้

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

เมื่อร้องขอใบรับรองไคลเอ็นต์เซิร์ฟเวอร์จะส่งCertificateRequestข้อความ TLSไปยังไคลเอนต์ระหว่าง handhsake ข้อความนี้มีcertificate_authoritiesรายการ:

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

เบราว์เซอร์ใช้สิ่งนี้เพื่อเลือกใบรับรองไคลเอ็นต์ที่จะส่ง (ถ้ามี)

(โปรดทราบว่าส่วนที่เกี่ยวกับรายการที่ว่างเปล่าจะมีเฉพาะในสเปคตั้งแต่ TLS 1.1 เป็นต้นไป SSL 3.0 และ TLS 1.0 จะเงียบในเรื่องนี้และในทางปฏิบัติมันจะทำงานด้วย)

คุณมีสองทางเลือกสำหรับสิ่งนี้

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

  • ตัวเลือกที่สอง (สะอาดน้อยกว่า) คือการยอมรับ DN ของผู้ออกที่ใช้ร่วมกันกับใบรับรองไคลเอ็นต์ทั้งหมดที่คุณคาดหวังไม่ว่าพวกเขาจะได้รับใบรับรอง CA นั้นจริงหรือไม่ก็ตาม (หรือว่า CA นั้นมีอยู่จริงหรือไม่ก็ตาม) ด้วยการทำเช่นนี้คุณจะทำลายโมเดล PKI มากขึ้น (มากขึ้น)

    หากคุณเห็นด้วยกับผู้ออก DN เช่นCN=Dummy CA(ตัวอย่าง) ทุกคนสามารถสร้างใบรับรองที่ลงนามเองได้โดยใช้CN=Dummy CAเป็นหัวเรื่อง DN (และผู้ออก DN) ซึ่งอาจมีคีย์ที่แตกต่างกัน แม้ว่าSSLCADNRequestFiledirective คาดว่าจะถูกกำหนดค่าด้วยใบรับรองเพื่อสร้างรายการเหล่านี้ไม่ได้ใช้ในการตรวจสอบใบรับรองลูกค้าเลยมันเป็นเพียงความซับซ้อน (แต่เป็นธรรมชาติในบริบทของคำสั่งอื่น ๆ ) ของการกำหนดค่าcertificate_authoritiesรายการ หากคุณเป็นผู้ให้บริการใส่ใบรับรองที่ลงนามเองด้วยชื่อเหล่าSSLCADNRequestFileนี้สิ่งนี้จะทำให้CertificateRequestข้อความ TLS ใช้CN=Dummy CAในcertificate_authoritiesรายการ (นี่เป็นเพียงชื่อไม่ใช่ใบรับรองในขั้นตอนนี้) จากนั้นลูกค้าจะสามารถรับใบรับรองของตนเองด้วยผู้ออก DNCN=Dummy CAไม่ว่าจะสามารถตรวจสอบลายเซ็นได้หรือไม่โดยใบรับรองนั้น (คีย์เดียวกัน) หรือไม่เนื่องจากไม่มีการยืนยันลายเซ็นในขั้นตอนเหล่านี้

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

สิ่งนี้จะทำงานได้ไม่ดีกับไฟล์ แต่คุณสามารถทำได้สำหรับแอปพลิเคชัน (เช่น PHP / CGI / ... แม้กระทั่ง Java หากคุณส่งใบรับรองไปยังเซิร์ฟเวอร์ Java ที่พร็อกซี) หนึ่งในวิธีการขั้นพื้นฐานจะมีรายชื่อก่อนที่รู้จักของกุญแจสาธารณะหรือคุณอาจจะดูที่ความคิดในfoaf + SSL / WebID


2

การใช้SSLVerifyCLient optional_no_ca(แทนrequire) ทำให้ Apache ไม่ต้องตรวจสอบ CA ที่ออก (และไม่จำเป็นต้องใช้ไฟล์ใบรับรองหรือพา ธ CA) มันไม่อนุญาตให้ลูกค้า / ผู้ใช้ไม่ส่งใบรับรองดังนั้นการตรวจสอบว่ามีการใช้ใบรับรองเลยหรือไม่ที่จะต้องทำแยกต่างหาก

(เห็นได้ชัดว่าฉันล้มเหลวในการอ่านmod_sslเอกสารอย่างละเอียด)

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