Apache จะไม่ขอใบรับรองไคลเอนต์ SSL ของฉัน

ก่อนอื่น โปรดทราบว่าฉันยังใหม่กับการกำหนดค่า SSL ในอดีต ฉันโชคดีเสมอที่มีแผนกไอทีคอยจัดเตรียมเรื่องนั้นให้ฉันล่วงหน้า ดังนั้นจงเตรียมพร้อมสำหรับความเป็นไปได้ที่ฉันอาจจะต้องขอคำชี้แจงในคำตอบบางส่วนของคุณ =)

สิ่งที่ฉันกำลังพยายามทำ

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

ฉันจะมีการตั้งค่าฐานข้อมูล MySQL เพื่อเชื่อมโยงบัญชี "ผู้ใช้" กับ SSL_CLIENT_M_SERIAL และ SSL_CLIENT_I_DN ซึ่งฉันถือว่าจะไม่ซ้ำกันสำหรับใบรับรองไคลเอ็นต์แต่ละรายการ (?) ฉันได้รับแนวคิดนั้นจากบทความนี้: http://cweiske.de/tagebuch/ssl-client-certificates.htm

ครั้งแรกที่ผู้ใช้ไปที่เว็บไซต์ภายใน พวกเขาจะไม่มีใบรับรอง (ฉันไม่ต้องการสร้างใบรับรองด้วยตนเองสำหรับลูกค้า!) ซึ่งในกรณีนี้ $_SERVER["SSL_CLIENT_VERIFY"] == "NONE" หากเป็นเช่นนั้น ระบบจะไปที่หน้าการตั้งค่าบัญชีผู้ใช้ ซึ่งจะรวมขั้นตอนที่ PHP สร้างใบรับรองไคลเอ็นต์ SSL และส่งไปยังเบราว์เซอร์เพื่อให้ผู้ใช้ติดตั้ง ดีและเรียบง่าย จากนั้นผู้ใช้จะติดตั้งใบรับรอง สร้างการเชื่อมโยง และหลังจากรีสตาร์ทเบราว์เซอร์ (เพื่อการวัดผลที่ดี) ผู้ใช้จะกลับไปที่เว็บไซต์ภายใน

ณ จุดนี้ Apache ควรขอใบรับรองไคลเอ็นต์ซึ่งเบราว์เซอร์จะส่งไป จากนั้นสคริปต์ PHP จะแยกวิเคราะห์ตัวแปร $_SERVER ที่จำเป็น เปรียบเทียบกับฐานข้อมูล MySQL และทุกคนต่างก็มีช่วงเวลาดีๆ อีกครั้งที่ดีและเรียบง่าย

สิ่งที่ได้ผลจนถึงขณะนี้

ฉันติดตั้งใบรับรองฝั่งเซิร์ฟเวอร์แล้ว และใช่ พวกเขาลงนามด้วยตนเอง (ด้วยเหตุผลที่ชัดเจน) Apache ได้ติดตั้ง mod_ssl แล้วและทุกอย่างดูเหมือนว่าจะทำงานได้ดี ฉันสร้างสคริปต์ PHP ที่เพิ่งดัมพ์อาร์เรย์ $_SERVER และค่าคีย์ SSL_SERVER_* ทั้งหมดตรงกับใบรับรองที่ฉันสร้างไว้

ปัญหา

ฉันไม่สามารถรับใบรับรองไคลเอ็นต์ให้ทำงานได้! ในสคริปต์ PHP เดียวกันนั้น ไม่ว่าฉันจะทำอะไรก็ตาม SSL_CLIENT_VERIFY == "NONE" และคีย์ SSL_CLIENT_* อื่นๆ หายไป นี่คือสิ่งที่จะเกิดขึ้นหากฉันตั้งค่า SSLVerifyClient เป็นตัวเลือกใน ssl.conf ตามบทช่วยสอนทุกรายการที่ฉันได้อ่าน ทุกคนบอกว่าเว็บเซิร์ฟเวอร์ควรขอใบรับรองไคลเอ็นต์จากเบราว์เซอร์ ประเด็นก็คือ ฉันไม่สามารถทำมันได้! มันตรงไปที่สคริปต์ PHP และถือว่าฉันไม่มีใบรับรองไคลเอนต์เลย สิ่งนี้เกิดขึ้นใน Firefox, Chrome และ IE

ดังนั้นฉันจึงลองตั้งค่า SSLVerifyClient เป็นจำเป็นและรีสตาร์ทเว็บเซิร์ฟเวอร์ ด้วยตัวเลือกนั้น ฉันไม่สามารถสร้างการเชื่อมต่อ SSL ได้ Firefox เพิ่งบอกว่าการเชื่อมต่อถูกรีเซ็ตแล้ว (เบราว์เซอร์อื่นแสดงข้อผิดพลาดในเวอร์ชันของตัวเองเช่นกัน) สิ่งที่แปลกคือบันทึกไม่แสดงกิจกรรมใด ๆ ในความพยายามในการเชื่อมต่อเหล่านี้! เช่น. access_log, error_log, ssl_access_log, ssl_error_log และ ssl_request_log ทั้งหมดไม่แสดงใดๆ; ราวกับว่าความพยายามไม่เคยเกิดขึ้นด้วยซ้ำ สิ่งนี้น่าหงุดหงิดเพราะหมายความว่าฉันไม่มีข้อความแสดงข้อผิดพลาดให้ดำเนินการด้วยซ้ำ แค่เว็บเซิร์ฟเวอร์ที่คอยบอกให้ฉันตกนรก

ฉันพยายามสร้าง/ติดตั้งใบรับรองไคลเอ็นต์ของตัวเองด้วยตนเองโดยใช้ส่วนขยาย OpenSSL ของ PHP ใบรับรองติดตั้งได้ดี แม้ว่าฉันจะไม่พบข้อมูลใด ๆ เกี่ยวกับวิธีเชื่อมโยงใบรับรองนั้นกับเซิร์ฟเวอร์ (สมมติว่าฉันต้องการด้วยซ้ำ) นอกจากนี้ ดูเหมือนจะไม่สำคัญอยู่แล้ว เนื่องจาก Apache ยังคงไม่ขอใบรับรองไคลเอ็นต์ด้วยซ้ำหากตั้งค่าเพิ่มเติมไว้ และถ้ากำหนดไว้ มันก็ระเบิดโดยไม่มีคำอธิบาย ฉันจำเป็นต้องตั้งค่าเป็นตัวเลือกเพื่อให้สคีมานี้ทำงานได้

สิ่งแวดล้อม

ระบบปฏิบัติการ: CentOS 5.7 64 บิต (VirtualBox)

อาปาเช่: 2.2.3

PHP: 5.3.10

ฉันเดาว่าคุณอาจต้องการข้อมูลเพิ่มเติมเพื่อช่วยฉัน ดังนั้นโปรดถาม! ฉันจะจัดหาสิ่งที่คุณต้องการให้คุณ

โดยสรุป ฉันจำเป็นต้องรู้วิธีรับ Apache เพื่อขอใบรับรองไคลเอ็นต์ SSL โดยมีเงื่อนไขที่อธิบายไว้ข้างต้น นอกจากนี้ หากมีการลงนามพิเศษ / ฯลฯ ที่ต้องทำเพื่อทำให้ใบรับรองไคลเอ็นต์ "เข้ากันได้" กับใบรับรองเซิร์ฟเวอร์ (อีกครั้งโดยไม่ต้องทำด้วยตนเองผ่านเชลล์สำหรับใบรับรองไคลเอ็นต์แต่ละอัน!) ฉันจะต้องรู้ว่าเป็น ดี.

ตอนนี้ฉันติดเรื่องนี้ 100% ไม่พบสิ่งใดที่เป็นประโยชน์จากระยะไกลบน Google ความช่วยเหลือใด ๆ ที่คุณสามารถให้ได้จะได้รับการชื่นชมอย่างมาก !! ขอบคุณ! =)


person Kris Craig    schedule 20.04.2012    source แหล่งที่มา
comment
ใบรับรองไคลเอ็นต์ทุกรายการที่สร้างขึ้นเป็นแบบลงนามด้วยตนเองหรือไม่ หรือคุณสร้าง CA ของคุณเองเพื่อลงนามคำขอที่สร้างขึ้น ไคลเอนต์จะแจ้งให้คุณใส่ใบรับรองหากคุณมีใบรับรองที่ติดตั้งซึ่งลงนามจากหน่วยงานที่เชื่อถือได้ (ซึ่งกำหนดโดยร้านค้าที่เชื่อถือได้ของเซิร์ฟเวอร์) หากใบรับรองไคลเอ็นต์แต่ละรายการลงนามด้วยตนเอง คุณจะต้องใช้ใบรับรองที่สร้างขึ้นแต่ละรายการให้อยู่ใน Trust Store ของเซิร์ฟเวอร์ ซึ่งจะเป็นไปไม่ได้   -  person bobz32    schedule 21.04.2012
comment
ฉันพยายามสร้างใบรับรองไคลเอ็นต์บนเซิร์ฟเวอร์โดยใช้ openssl ส่งออกเป็น p12 จากนั้นติดตั้งใน Firefox แต่ตอนนี้ฉันได้รับข้อผิดพลาดใบรับรองผู้ออกใบรับรองท้องถิ่นจาก Apache ไม่ได้ ฉันลงนามใบรับรองไคลเอ็นต์โดยใช้ใบรับรองเซิร์ฟเวอร์ แล้วเหตุใดจึงใช้งานไม่ได้ ฉันพยายามยกเลิกการใส่เครื่องหมายบรรทัด SSLCACertificateFile ใน ssl.conf แต่นั่นก็ทำให้ฉันกลับมาที่ปัญหาแรก ซึ่งเป็นหน้าที่โหลดได้ดี แต่ไม่รู้จักใบรับรองไคลเอ็นต์ แล้วฉันก็กลับมาที่เดิมอีกครั้ง....   -  person Kris Craig    schedule 21.04.2012


คำตอบ (3)


ขั้นแรก คุณต้องกำหนดค่า Apache Httpd เพื่อขอใบรับรองไคลเอ็นต์ สำหรับสิ่งนี้ อย่างน้อยคุณต้องใช้ SSLVerifyClient optional บนตำแหน่ง/ไดเรกทอรีที่คุณต้องการตรวจสอบสิทธิ์ด้วยวิธีนี้

ประการที่สอง ใบรับรองที่ส่งโดยไคลเอ็นต์จะต้องได้รับความเชื่อถือจาก Apache Httpd ด้วยเช่นกัน (โดยหลักการแล้วคุณสามารถใช้ SSLVerifyClient optional_no_ca ปล่อยให้ไคลเอ็นต์ใดๆ รับรองผ่านสแต็ก Apache Httpd SSL/TLS จากนั้นจึงตรวจสอบใบรับรองภายใน PHP เท่านั้น แต่นั่นเป็นงานที่ค่อนข้างยุ่งยาก ซึ่งคุณต้องระมัดระวังให้มากขึ้นอีกเล็กน้อยเนื่องจาก ไม่จำเป็นต้องใช้โค้ดง่ายๆ ที่สำคัญกว่านั้น สิ่งนี้จะไม่มีประโยชน์เลยทีเดียวในบริบทนี้ เนื่องจากคุณอยู่ในสถานการณ์ที่คุณสามารถควบคุม CA ของคุณได้)

เท่าที่ฉันเข้าใจ SSL_CLIENT_VERIFY (ตัวแปรที่ฉันไม่ค่อยได้ใช้ด้วยตัวเอง) ดูเหมือนจะมีประโยชน์จริงๆ กับ SSLVerifyClient optional_no_ca เท่านั้น มันอาจจะใช้ได้กับ SSLVerifyClient optional แต่ฉันสงสัยอย่างนั้น SSLVerifyClient require จะปฏิเสธการเชื่อมต่อโดยใช้ใบรับรองไคลเอ็นต์ที่ไม่น่าเชื่อถือ (โดย CA ตัวใดตัวหนึ่งใน SSLCACertificateFile/SSLCACertificatePath) หรือหากไม่มีใบรับรอง เท่าที่ฉันรู้ SSLVerifyClient optional จะปล่อยให้ไคลเอ็นต์ผ่านไปโดยไม่มีใบรับรองหรือใบรับรองที่เชื่อถือได้ แต่จะปฏิเสธการเชื่อมต่อด้วยหากใบรับรองไม่เชื่อถือ

ในกรณีนี้ การปฏิเสธการเชื่อมต่อ ฉันหมายถึงการปิดการเชื่อมต่อ SSL/TLS อย่างกะทันหันพร้อมกับการแจ้งเตือน ไม่มีโอกาสสร้างหน้าแสดงข้อผิดพลาด HTTP(S) สิ่งที่คุณจะได้รับจากข้อผิดพลาดมาตรฐานของเบราว์เซอร์ ซึ่งอยู่ในบรรทัด ssl_error_unknown_certificate_... (คุณควรพิจารณาสิ่งนี้ในแง่ของการใช้งาน)

ตั้งแต่นั้นเป็นต้นมา สิ่งที่คุณต้องมีคือตั้งค่า CA ของคุณเอง ซึ่งอาจทำงานบนเว็บด้วยการสร้างคีย์ในเบราว์เซอร์และภายในเว็บไซต์เดียวกัน คุณคงไม่ต้องการ SSLVerifyClient require สำหรับสิ่งนั้น เพราะคุณจะต้องให้ผู้ใช้ที่ยังไม่มีใบรับรองเข้ามา (ใช้ optional แทน) ดังที่กล่าวไปแล้ว คำสั่งเหล่านี้ไม่จำเป็นต้องใช้กับโฮสต์ทั้งหมด แต่สามารถเฉพาะเจาะจงกับบางสถานที่/ไดเร็กทอรีได้

การรวม CA บนเว็บของคุณเอง (หรือโดยทั่วไปคือการสร้าง CA ของคุณเอง) ไม่ใช่เรื่องง่ายหากคุณยังใหม่กับเรื่องทั้งหมดนี้ มีเครื่องมือสำเร็จรูปอยู่แล้ว (เช่น OpenCA) หรือคุณสามารถสร้างเครื่องมือของคุณเองโดยใช้บิตต่างๆ ของ JavaScript/ActiveX และคุณจะ ต้องการโค้ดฝั่งเซิร์ฟเวอร์เพื่อจัดการคำขอ SPKAC หรือ PKCS#10 (และเพื่อออกใบรับรองจริง) (เพื่อให้ CA ดังกล่าวมีประโยชน์ คุณคงต้องการให้ผู้ใช้ที่สมัครใบรับรองใหม่แสดงหลักฐานประจำตัวบางส่วน ณ เวลาที่สมัคร ซึ่งอาจรวมถึงรหัสผ่าน)

เมื่อตั้งค่านี้แล้ว คุณควรกำหนดค่า SSLCACertificateFile (หรือ ...Path) ให้ชี้ไปที่ใบรับรอง CA ของ CA ภายในของคุณ (ไม่ว่าจะเป็น CA บนเว็บหรือไม่ก็ตาม บนไซต์เดียวกันหรือไม่ก็ตาม) (แน่นอนว่า เก็บคีย์ส่วนตัวของ CA ของคุณไว้เป็นส่วนตัว ซึ่งอาจกำหนดค่าไว้ภายในแอปพลิเคชันบนเว็บของ CA ของคุณ แต่ Apache Httpd เองก็ไม่จำเป็นต้องรู้เรื่องนี้) เบราว์เซอร์จะแนะนำเฉพาะใบรับรองที่ออกโดย CA หรือตัวกลางเหล่านั้นเท่านั้น (เว้นแต่ คุณได้กำหนดค่า SSLCADNRequestFile ซึ่งจะใช้ในการส่งรายการ CA ที่ยอมรับแทน)

โปรดทราบว่าสองขั้นตอนนี้ (การตั้งค่า CA และการตั้งค่าเว็บไซต์ของคุณเพื่อใช้ใบรับรองไคลเอ็นต์) จริงๆ แล้วมีความเป็นอิสระอย่างแท้จริง ความจริงที่ว่าทั้งสองสามารถเป็นส่วนหนึ่งของไซต์เดียวกันได้ก็สะดวก แต่ก็ไม่จำเป็น คุณสามารถลองใช้การตั้งค่า Apache Httpd โดยไม่ต้องปรับใช้ CA ทั้งหมดบนไซต์ก่อน (ฉันขอแนะนำ แม้ว่าจะเป็นเพียงเพื่อดูว่าคุณกำลังทำอะไรอยู่ก็ตาม) มีเครื่องมือมากมายในการสร้าง CA เล็กๆ ของคุณเองที่สามารถจัดการได้ด้วยใบรับรองจำนวนหนึ่ง: CA.pl ของ OpenSSL หรือ TinyCA เป็นต้น คุณสามารถใช้ ใบรับรองการทดสอบ (localhost และ testclient, testclient_r จะถูกเพิกถอนหากคุณต้องการใช้ CRL ซึ่งอาจไม่จำเป็นในตอนแรก): รหัสผ่านทั้งหมดคือ testtest

ตามที่คุณคาดหวังไว้แล้ว (ด้วย MySQL DB) คุณจะต้องจัดการใบรับรองที่คุณออกและแมปใบรับรองกับผู้ใช้ SSL_CLIENT_M_SERIAL และ SSL_CLIENT_I_DN ไม่ใช่ตัวแปรที่ถูกต้องที่จะใช้ SSL_CLIENT_I_DN คือ DN ผู้ออก (เช่น DN เรื่องของ CA) สิ่งที่คุณกำลังมองหาคือ SSL_CLIENT_S_DN: ใบรับรองไคลเอ็นต์ Subject DN SSL_CLIENT_M_SERIAL คือหมายเลขซีเรียลของใบรับรอง: อย่าใช้ เนื่องจากหมายเลขดังกล่าวไม่ซ้ำกันต่อใบรับรอง: ผู้ใช้ 1 รายสามารถมีใบรับรองได้หลายใบที่มี DN หัวเรื่องเดียวกัน (เช่น หากมีใบรับรองหมดอายุหรือถูกเพิกถอน)


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

  • ประการแรก ผู้ใช้ควรปกป้องใบรับรองของตนเองด้วยรหัสผ่านอยู่แล้ว ฉันคิดว่าสิ่งที่คุณต้องการจริงๆ คือรูปแบบการลงชื่อเพียงครั้งเดียว (SSO)

  • ประการที่สอง ขึ้นอยู่กับระดับความรู้คอมพิวเตอร์ของผู้ใช้ ใบรับรองอาจเป็นเรื่องยากในการจัดการ

    ความจริงที่ว่าคำว่า "ใบรับรอง" หากพูดอย่างเคร่งครัดนั้นไม่ได้รวมคีย์ส่วนตัวไว้เลย แต่บางครั้งก็บอกเป็นนัยว่าการใช้คีย์ส่วนตัวอาจทำให้บางคนสับสนได้ ในด้านหนึ่ง บางครั้งคุณอาจได้ยินว่า "นำเข้าใบรับรองของคุณไปยังเบราว์เซอร์ของคุณ" และ "ใช้ใบรับรองของคุณเพื่อเข้าสู่ระบบ"; ในทางกลับกัน คุณยังสามารถได้ยินว่า "ส่งใบรับรองของคุณมาให้ฉัน" แบบแรกหมายถึงการใช้งานและความพร้อมใช้งานของคีย์ส่วนตัว ("ใบรับรอง" อาจหมายถึง .p12 ในนิพจน์เหล่านี้) อย่างหลังไม่ควรเกี่ยวข้องกับรหัสส่วนตัวอย่างแน่นอน

    อินเทอร์เฟซผู้ใช้ของเบราว์เซอร์ค่อนข้างแย่หรือสับสนในการจัดการใบรับรองหรือออกจากระบบ ขอย้ำอีกครั้ง หากระบบไม่รู้จักใบรับรอง การเชื่อมต่อ SSL/TLS จะไม่ถูกสร้างขึ้น ดังนั้นเว็บเซิร์ฟเวอร์จึงไม่มีโอกาสแสดงหน้าข้อผิดพลาด HTML ไม่ว่าจะประเภทใดก็ตาม

บางทีคุณอาจพิจารณา SSO รูปแบบอื่นๆ ก็ได้ (เช่น CAS, บางอย่างที่ใช้ SAML หรือ Kerberos/SPNEGO)

person Bruno    schedule 21.04.2012

ฉันมีปัญหาที่คล้ายกันกับ:

  • เซนโอเอส 6.3
  • อาปาเช่ 2.2.15

หลังจากลองมาบ้างฉันก็พบปัญหาของฉัน

หากฉันตั้งค่า SSLVerifyClient optional หรือ SSLVerifyClient optional_no_ca และฉันระบุ SSLCACertificateFile หรือ SSLCACertificatePath ด้วย Apache จะได้รับใบรับรองไคลเอ็นต์ก็ต่อเมื่อมีการเผยแพร่จาก CA ที่พบในไฟล์อ้างอิง CA/เส้นทางที่ระบุในการกำหนดค่า

person lgaggini    schedule 25.01.2013

คุณอาจดู apache doc หากยังไม่ได้ดำเนินการ

หลักการทั่วไปคือคุณสร้างใบรับรองที่ลงนามด้วยตนเองและตรวจสอบก่อนลองใช้

ดูเหมือนว่าไคลเอ็นต์จะเชื่อมต่อกับไซต์อินทราเน็ตของคุณผ่าน http จากที่นั่น มีหลายวิธีในการสลับไปใช้ https โดยใช้ใบรับรอง SSL ของคุณ วิธีที่ง่ายที่สุดคือใช้โมดูลการเขียนใหม่ของ apache แต่ในกรณีของคุณ ขณะที่คุณกำลังตรวจสอบ php/mysql คุณอาจเปลี่ยนเส้นทางไคลเอ็นต์ของคุณจาก http ไปยัง https ซึ่งไม่ใช่วิธีง่ายๆ

ในทั้งสองกรณี (apache เปลี่ยนเส้นทางอัตโนมัติผ่าน mod_rewrite หรือเปลี่ยนเส้นทางโดยการทดสอบแบบเรียงซ้อน (php/javascript/html) คุณจะต้องตั้งค่า vhost 2 เครื่องของคุณ (หนึ่งรายการสำหรับ http และอีกรายการสำหรับ https) ในวิธีที่เหมาะสม แต่ถือว่าถือว่า สมมติฐานบางอย่าง

ตัวอย่างเช่น (debian - apache 2.2) นี่คือการเปลี่ยนเส้นทางอัตโนมัติที่ทำโดย Apache (เช่นกรณีที่ 1 ที่อธิบายไว้ข้างต้น):

cat /etc/apache2/sites-available/test.cat

# VHOST test

<VirtualHost *:80>

    DocumentRoot /home/www/test
    ServerName www.test.dev

    # ######################
    # Redirect commons
    # ######################
    RewriteEngine on
    # Case of vhosts
    RewriteOptions Inherit

    # ######################
    # Redirect (empty index)
    # ######################

    # Condition 1 to redirect : request matching with the server
    RewriteCond %{HTTP_HOST}   ^www\.test\.dev [NC]

    # Condition 2 to redirect : non empty HOST
    RewriteCond %{HTTP_HOST}   !^$

    # Automatic Empty requests Redirect
    RewriteRule ^(.*)/$ /index.php


    # ######################
    # Redirect to SSL
    # ######################
    RewriteCond %{HTTP_HOST}   ^www\.test\.dev [NC]
    RewriteCond %{HTTP_HOST}   !^$
    RewriteCond %{SERVER_PORT} ^80$
    RewriteCond %{REQUEST_URI} /

    # Redirection
    RewriteRule ^/(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]

</VirtualHost>

โฮสต์เสมือนที่สองสำหรับ SSL : cat /etc/apache2/sites-available/test-ssl

# VHOST for ssl

DocumentRoot "/home/www/test"
ServerName www.test.dev

    # SSL
    SSLEngine on
    SSLCACertificateFile /etc/apache2/ssl/cur_cert/ca.pem
    SSLCertificateFile /etc/apache2/ssl/cur_cert/serveur.pem
    SSLCertificateKeyFile /etc/apache2/ssl/cur_cert/serveur.key


    <Directory "/home/www/test">
        Options FollowSymLinks MultiViews
        AllowOverride None
        Order allow,deny
        Allow from 127.0.0.1 192.168.0.0/16
    </Directory>


    <Directory "/home/www/test/cgi-bin">
        Options FollowSymLinks MultiViews
        AllowOverride None
        Order allow,deny
        Allow from 127.0.0.1 192.168.0.0/16
        Options +ExecCGI
        AddHandler cgi-script .cgi
    </Directory>

</VirtualHost>

Your case might defer slightly from this, eg you will not have the redirect portion in the 1st vhost, but only a simple vhost and the second one for https (ssl). The redirection will be done by php/javascript once you have achieved your mysql checks.

นี่คือตัวอย่างนามธรรมจากคลาส php สำหรับวิธีเรียงซ้อนสวิตช์จาก http เป็น https โดยใช้ php จากนั้น javascript จากนั้น html :

public function Redirect($url){

    if (TRUE !== Validator::isValidURL($url))
        die ("FATAL ERR: url not valid");

    // PHP ABSOLUTE URL REDIRECT (HTTP1.1)
    if (!headers_sent()) {

        header("Status: 200");
        header("Cache-Control: no-cache, must-revalidate"); // required for HTTP/1.1
        header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // past Date
        header("Pragma: no-cache");
        header('Location: '.$url); // note: 302 code return by default with "Location"
        flush();
        exit();

        // if headers are already sent... do javascript redirect... if javascript is disabled, do html redirect.
    } else {

        // Js redirect
        echo '<script type="text/javascript">';
        //echo "<!--";
        echo 'document.location="'. $url .'";';
        //echo "//-->";
        echo '</script>';

        // HTML redirect if js disabled
        echo '<noscript>';
        echo '<meta http-equiv="refresh" content="0;url="'.$url.'" />';
        echo '</noscript>';

        exit();
    }

    return FALSE;

} /* end of method (redirect) */

หวังว่าจะช่วยให้คุณเข้าใจวิธีดำเนินการและปรับแนวทางนี้ให้เหมาะกับกรณีของคุณได้ดีขึ้น

person hornetbzz    schedule 20.04.2012
comment
แต่ปัญหาที่ฉันมีไม่ได้เกี่ยวกับการเปลี่ยนเส้นทาง ฉันกำลังเข้าถึงเพจโดยตรงผ่าน https เช่น. ในเบราว์เซอร์ ฉันใช้ https:// ดังนั้นพอร์ต 80 จึงไม่เป็นปัญหา - person Kris Craig; 21.04.2012
comment
ฉันพยายามสร้างใบรับรองไคลเอ็นต์บนเซิร์ฟเวอร์โดยใช้ openssl ส่งออกเป็น p12 จากนั้นติดตั้งใน Firefox แต่ตอนนี้ฉันได้รับข้อผิดพลาดใบรับรองผู้ออกใบรับรองท้องถิ่นจาก Apache ไม่ได้ ฉันลงนามใบรับรองไคลเอ็นต์โดยใช้ใบรับรองเซิร์ฟเวอร์ แล้วเหตุใดจึงใช้งานไม่ได้ ฉันพยายามยกเลิกการใส่เครื่องหมายบรรทัด SSLCACertificateFile ใน ssl.conf แต่นั่นก็ทำให้ฉันกลับมาที่ปัญหาแรก ซึ่งเป็นหน้าที่โหลดได้ดี แต่ไม่รู้จักใบรับรองไคลเอ็นต์ - person Kris Craig; 21.04.2012
comment
ขออภัย ฉันเข้าใจประเด็นของคุณดีขึ้นแล้ว และไม่มีวิธีอื่นใดที่ง่ายไปกว่าการเชื่อมต่อ http และสลับ https เมื่อการตรวจสอบ mysql เสร็จสิ้นหลังจากเข้าสู่ระบบ ซึ่งดูเหมือนเป็นแนวทางที่ปลอดภัยกว่าสำหรับฉัน แต่เป็นผู้บริโภคโค้ดรายใหญ่จากประสบการณ์ - person hornetbzz; 21.04.2012
comment
สิ่งนี้ไม่เกี่ยวข้องกับคำถาม - person paf.goncalves; 19.06.2014