ทำไม 403 จากเว็บไซต์ VPN จึงไม่ใช่ความล้มเหลวของพร็อกซี
403 จากต้นทาง CONNECT ที่ถูกปฏิเสธ และการท้าทาย 407 บ่งชี้ขอบเขตที่ต่างกัน เปรียบเทียบเส้นทางออกของพร็อกซีก่อนกับที่อยู่ VPN ของเบราว์เซอร์
ผู้ใช้ตัดการเชื่อมต่อ VPN แล้วเจอ 403 บนเว็บไซต์ภายในและรายงานว่าพร็อกซีเสีย สามสิ่งแยกกันสามารถสร้างหน้านั้นได้: ต้นทางปฏิเสธคำขอ พร็อกซีขาไปปฏิเสธที่จะเปิดอุโมงค์ หรือพร็อกซีเรียกดูข้อมูลรับรองของตัวเอง แต่ละอย่างเป็นคำตอบที่ถูกต้องสำหรับคำถามที่ต่างกัน และการทำให้แบนราบเป็นหน้าแสดงความล้มเหลวทั่วไปเพียงหน้าเดียวจะทำลายหลักฐานเดียวที่คุณมี จัดเรียงการปฏิเสธตามองค์ประกอบที่สร้างมันขึ้นมา แล้วเปรียบเทียบเส้นทางเครือข่ายที่แต่ละองค์ประกอบใช้จริง
ระบุองค์ประกอบที่สร้าง 403
รหัสสถานะ HTTP เป็นของฝ่ายที่ส่งมัน เมื่อต้นทางส่งคืน 403 แสดงว่ามันแยกวิเคราะห์คำขอและตัดสินว่าผู้เรียกอาจไม่มีทรัพยากร ซึ่งเป็นคำตอบด้านการอนุญาตไม่ใช่ปัญหาในการขนส่ง เมื่อพร็อกซีขาไปตอบ 403 ต่อ CONNECT แสดงว่าปฏิเสธที่จะสร้างอุโมงค์เลยและไม่มีการติดต่อสิ่งใดเหนือขึ้นไป เมื่อมันตอบ 407 แสดงว่าต้องการข้อมูลรับรองของตัวเอง ซึ่งไม่เกี่ยวกับการเข้าสู่ระบบของแอปพลิเคชัน
| What you observe | What it means |
|---|---|
| Origin replies 403 | The origin understood the request and denied it |
| Proxy refuses CONNECT with 403 | The proxy declined to open that tunnel |
| Proxy replies 407 | Proxy authentication is required first |
| Gateway replies 502 or 504 | Upstream failure or timeout, not a permission decision |
RFC 9110 กำหนดบทบาทเหล่านี้ รวมถึงการท้าทายเฉพาะพร็อกซี อ่านสถานะของคำตอบเองและส่วนหัว Proxy-Authenticate ก่อนอ่านเนื้อหา เพราะหน้าแสดงข้อผิดพลาด HTML ที่เป็นมิตรมักซ่อนว่าองค์ประกอบใดเป็นผู้เขียน
สิ่งที่อุโมงค์ CONNECT ซ่อนจากรีเลย์ไบต์
เมื่อพร็อกซีส่งคืน 200 ต่อ CONNECT มันกำลังรีเลย์ไบต์และเบราว์เซอร์เก็บเซสชัน TLS ของตัวเองไว้กับต้นทาง ดังนั้นพร็อกซีที่รีเลย์ไบต์จึงอ่าน 403 ที่เข้ารหัสภายในเซสชันนั้นไม่ได้ และมันไม่เคยกลายเป็นผู้เขียนการปฏิเสธ การปฏิเสธก่อนที่อุโมงค์จะเปิดเป็นเหตุการณ์ที่ต่างออกไปโดยสิ้นเชิง ซึ่งเกิดขึ้นในชั้นที่ต่ำกว่าหนึ่งชั้น
พร็อกซีย้อนกลับที่สิ้นสุด TLS อยู่ในตำแหน่งที่ต่างออกไป: มันเป็นเจ้าของขอบเขต TLS แยกวิเคราะห์ HTTP และสามารถเขียนใหม่หรือดักจับคำตอบได้อย่างชอบธรรม ความสามารถนั้นเป็นการเลือกการกำหนดค่า ไม่ใช่คุณสมบัติของพร็อกซีโดยทั่วไป และไม่ได้ให้อำนาจในการข้ามนโยบายการเข้าถึงของแอปพลิเคชัน การอ่านคำตอบเป็นความสามารถ ส่วนการตัดสินว่าผู้เรียกเห็นอะไรได้ยังคงเป็นงานของต้นทาง
ผลในทางปฏิบัติคือคุณต้องรู้ว่ากำลังใช้รูปแบบใดในสามแบบก่อนตีความ 403 การเพิ่มกฎตรวจสอบ HTTP ให้พร็อกซีแบบสตรีมไม่ได้ทำให้มันมองเห็นได้ และการคาดหวังให้รีเลย์ไบต์อธิบายการปฏิเสธของต้นทางจะทำให้คุณไปดูบันทึกผิดที่
เปรียบเทียบเส้นทางออกของพร็อกซีกับที่อยู่ของอุโมงค์ในเบราว์เซอร์
เบราว์เซอร์ที่เชื่อมต่อ VPN ไม่ได้ย้ายเซิร์ฟเวอร์พร็อกซีแยกต่างหากไปยังอุโมงค์นั้นโดยอัตโนมัติ ต้นทางเห็น ที่อยู่ขาออกของพร็อกซี และหากพร็อกซียังออกผ่านเส้นทางค่าเริ่มต้นในเครื่อง เว็บไซต์ที่ได้รับการป้องกันจะเห็นที่อยู่ที่ไม่เคยถูกกำหนดค่าให้ไว้วางใจ ที่อยู่ VPN ภายในบนแล็ปท็อปนั้นมองไม่เห็นจากต้นทางนั้น นี่คือสาเหตุที่พบบ่อยที่สุดที่อุโมงค์ที่ทำงานอยู่ยังคงให้ 403 จากเว็บไซต์ที่ทำงานถูกต้องกับคนอื่นทั้งหมด
ทดสอบทั้งสองเส้นทางแยกกันเพื่อไม่ให้ที่อยู่สับสน
curl -sS -o /dev/null -w 'status=%{http_code}\n' --noproxy '*' https://198.51.100.20/private
curl -sS -o /dev/null -w 'status=%{http_code}\n' -x http://203.0.113.10:3128 https://198.51.100.20/privateคำขอแรกแสดงสิ่งที่ต้นทางตอบกับที่อยู่ของคุณเอง คำขอที่สองแสดงสิ่งที่มันตอบกับที่อยู่ของพร็อกซี 403 ที่ตรงกันคู่หนึ่งชี้ไปที่กฎการอนุญาตของต้นทาง 200 ที่ตามด้วย 403 ชี้ไปที่เส้นทางของพร็อกซี ถามเจ้าของต้นทางว่าชุดกฎยอมรับที่อยู่ต้นทางใดจริง ๆ แทนที่จะถือว่ามีกลุ่ม VPN รวมอยู่
ทดสอบแต่ละขอบเขตด้วยคำขอที่แยกมันออกมา
แยกชั้นพร็อกซีออกโดยขอสิ่งที่มันปฏิเสธไม่ได้ด้วยเหตุผลของแอปพลิเคชัน CONNECT ไปยังโฮสต์ที่พร็อกซีได้รับอนุญาตให้เข้าถึง โดยทิ้งเอาต์พุต จะบอกคุณว่าการรับเข้าอุโมงค์ทำงานได้หรือไม่
curl -sSv -o /dev/null -x http://203.0.113.10:3128 https://198.51.100.20/ 2>&1 | grep -E 'CONNECT|HTTP/1.1|Proxy-Authenticate'
หากมันพิมพ์ 200 สำหรับ CONNECT แล้วตามด้วยการจับมือ TLS การรับเข้าของพร็อกซีก็ปกติ และ 403 ที่ตามมาภายหลังมาจากต้นทาง หากมันพิมพ์ 407 ให้ระบุข้อมูลรับรองพร็อกซีด้วย --proxy-user แล้วทำซ้ำก่อนสรุปสิ่งใดเกี่ยวกับเว็บไซต์ หากมันพิมพ์ 403 บนบรรทัด CONNECT แสดงว่ารายการอนุญาตของพร็อกซีเองคือขอบเขตที่ต้องตรวจสอบ และแอปพลิเคชันไม่ได้เกี่ยวข้อง
เก็บข้อมูลรับรองออกจากประวัติเชลล์และออกจากบันทึกที่วางไว้ รหัสผ่านพร็อกซีที่พิมพ์ในบรรทัดคำสั่งนั้นมองเห็นได้โดยผู้ใช้ในเครื่องอื่น และร่องรอย CONNECT ที่ถูกบันทึกพร้อมข้อมูลรับรองนั้นแย่กว่าไม่มีร่องรอยเลย
เก็บคำตัดสินให้อ่านได้แทนการเขียนหน้าใหม่
เมื่อรู้ว่าองค์ประกอบใดปฏิเสธ ให้รักษาคำตอบนั้นไว้ พร็อกซีย้อนกลับที่เปลี่ยนชื่อ 403 ของต้นทางเป็นหมดเวลา 504 หรือแทนที่ด้วยหน้าสำเร็จ จะซ่อนการตัดสินด้านการอนุญาตไว้เบื้องหลังเรื่องราวความพร้อมใช้งานและส่งผู้ตอบคนถัดไปไปยังทีมที่ผิด หน้าแสดงข้อผิดพลาดที่กำหนดเองนั้นดีเมื่อมันรักษาสถานะและเพิ่มบริบท
แคชสมควรได้รับการดูแลแบบเดียวกัน RFC 9111 ควบคุมว่าแคชที่ใช้ร่วมกันสามารถนำคำตอบกลับมาใช้ซ้ำได้อย่างไร และการปฏิเสธที่สร้างขึ้นสำหรับผู้เรียกคนหนึ่งต้องไม่ถูกส่งต่อให้อีกคนราวกับเป็นการอนุญาต หากมีการจัดเก็บคำตอบการปฏิเสธเลย ให้เก็บไว้เป็นส่วนตัวและจำกัดขอบเขต และอย่าเพิ่มกฎความสดใหม่แบบสาธารณะเพียงเพื่อลดทราฟฟิกขาเข้า
จบด้วยคำตัดสินเป็นลายลักษณ์อักษรที่ระบุองค์ประกอบ สถานะที่มันสร้าง และที่อยู่ต้นทางที่ต้นทางเห็น บันทึกคำขอที่แน่นอน การตั้งค่าพร็อกซีที่ใช้อยู่ และเวลา เพื่อให้รายงานถัดไปจับคู่กับหลักฐานเดียวกันได้แทนที่จะอนุมานใหม่จากความจำ บันทึกนั้นตอบรายงานถัดไปได้ในไม่กี่วินาทีและหยุดไม่ให้ 403 เดียวกันถูกวินิจฉัยซ้ำว่าเป็น VPN ล่ม