Squid ตอบสนองคำขอ CONNECT ด้วยบรรทัด http_access แรกที่ตรงกัน และบรรทัดนั้นอาจเป็นการปฏิเสธ ข้อเท็จจริงข้อเดียวนี้อธิบายว่าทำไมข้อยกเว้นสำหรับจุดปลาย VPN จึงมักล้มเหลวตั้งแต่ความพยายามครั้งแรก เพราะคำขอไม่เคยไปถึงการอนุญาตที่ใครบางคนเพิ่มไว้ท้ายสุด การแก้ไขแบบแคบยังคงรักษาการป้องกันพอร์ตที่มีอยู่และสอนให้รู้จักต้นทาง จุดหมาย และพอร์ตเดียวที่ผ่านการตรวจทาน สิ่งอื่นทั้งหมดบนพร็อกซียังคงทำงานเหมือนเดิมทุกประการ

Squid ตัดสินคำขอ CONNECT อย่างไร

คำขอ CONNECT ระบุโฮสต์และพอร์ต และ Squid จะไล่ไปตามบรรทัด http_access ตามลำดับจนกว่าจะมีบรรทัดหนึ่งตรงกัน การปฏิเสธที่ตรงกันจะยุติการประเมินทันทีและไคลเอนต์ได้รับ 403 จากพร็อกซี นี่คือเหตุผลว่าทำไมตำแหน่งของกฎจึงสำคัญกว่าถ้อยคำ การเลื่อนบรรทัดเดิมขึ้นหนึ่งขั้นสามารถเปลี่ยนผลลัพธ์ได้ทั้งหมด

การป้องกันแบบเดิมปฏิเสธทุกสิ่งนอก Safe_ports และปฏิเสธ CONNECT นอก SSL_ports ชื่อเหล่านั้นเป็น ACL ที่กำหนดในคอนฟิกูเรชันของคุณเอง เนื้อหาจึงเป็นของคุณไม่ใช่ของโปรโตคอล ดิสทริบิวชันบางตัวอาจอนุญาตช่วงพอร์ตที่กว้างเป็น Safe_ports ขณะจำกัด CONNECT แยกต่างหาก อ่านค่าจริงก่อนสันนิษฐานว่าพอร์ตถูกบล็อกโดยการออกแบบ

ยืนยันว่าพร็อกซีเป็นองค์ประกอบที่ปฏิเสธคำขอ 403 ที่ Squid สร้างขึ้นไม่เหมือนการแจ้งเตือน TLS จากเซิร์ฟเวอร์ VPN เลย และการรวมทั้งสองเป็นปัญหาเดียวทำให้เสียชั่วโมงแรกไป ตรวจสอบบรรทัดบันทึกการเข้าถึงของคำขอ เพราะบันทึกทั้งการกระทำและกฎที่ทำให้เกิดขึ้น

สร้างการจับคู่แบบรวมหนึ่งรายการแทน ACL แยกสามรายการ

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

รูปแบบด้านล่างใช้ช่วงจากเอกสารที่ต้องแทนที่ด้วยค่าที่ตรวจทานแล้ว Squid ไม่ได้สงวนชื่อใดเหล่านี้ไว้เอง คุณจึงเป็นผู้เลือกและผู้รักษาความสอดคล้อง สูตรนี้จำกัดเฉพาะ Squid 6 และ 7 ซึ่งคอนฟิกูเรชันที่มีเอกสารรองรับกลุ่ม all-of เอกสารอ้างอิงปัจจุบันระบุว่าคำสั่งเหล่านั้นไม่พร้อมใช้ใน Squid 8 จึงควรถือว่านี่เป็นสูตรที่ผูกกับเวอร์ชัน ไม่ใช่เส้นทางการย้ายระบบ และตรวจสอบคำสั่งในเอกสารอ้างอิงของเวอร์ชันคุณเองก่อนนำไปใช้

acl pvpn_src src 192.0.2.128/25
acl pvpn_dst dst 198.51.100.77/32
acl pvpn_port port 1194
acl pvpn_ok all-of CONNECT pvpn_port pvpn_dst pvpn_src

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

ดัดการป้องกันพอร์ตโดยไม่ต้องลบออก

ที่ตำแหน่งปัจจุบัน บรรทัดป้องกันแบบเดิมสองบรรทัดมีลักษณะเช่นนี้ โดยปกติจะอยู่หลังการยืนยันตัวตนและก่อนบรรทัดนโยบายที่อนุญาตทุกอย่าง

http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports

เพิ่มการจับคู่แบบรวมที่ถูกปฏิเสธให้แต่ละบรรทัด เพื่อให้ข้อยกเว้นที่ตรงกันอยู่รอดผ่านการป้องกันที่จะปฏิเสธมันในกรณีอื่น เฉพาะบรรทัดป้องกันเท่านั้นที่เปลี่ยน และเปลี่ยนเพียงหนึ่งเงื่อนไขต่อบรรทัด

http_access deny CONNECT !SSL_ports !pvpn_ok
http_access deny !Safe_ports !pvpn_ok

เงื่อนไขในบรรทัดการเข้าถึงเดียวจะถูกรวมกัน บรรทัดจึงปฏิเสธเฉพาะคำขอที่ล้มทั้งการตรวจเดิมและข้อยกเว้น คำขอไปยังจุดปลายที่อนุมัติจะผ่านไป และคำขออื่นทุกรายการยังคงพฤติกรรมพอร์ตเดิม นี่คือ แคบกว่าการเพิ่มพอร์ตลงในรายการ SSL_ports ระดับโลก ซึ่งจะอนุญาตพอร์ตนั้นแก่ทุกจุดหมาย หากพอร์ตมีอยู่ในรายการนั้นแล้ว ACL นี้ไม่ได้ทำให้แคบลงเลย และการอนุญาตเดิมที่กว้างกว่ายังใช้กับจุดหมายอื่น ดังนั้นอ่านรายการจริงก่อนอ้างว่าข้อยกเว้นเปิดพอร์ตให้ นอกจากนี้ยังย้อนกลับได้ เพราะสองบรรทัดกลับไปสู่รูปแบบเดิม เอกสารอ้างอิงการควบคุมการเข้าถึง อธิบายลำดับและการป้องกันแบบเดิมที่การเปลี่ยนแปลงนี้อาศัยอยู่

ตำแหน่งที่ห้ามวางข้อยกเว้น

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

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

พิจารณาว่าจุดปลายเป็น TCP หรือไม่ ข้อยกเว้น CONNECT พากระแส TCP และโปรไฟล์ OpenVPN ที่ใช้ UDP จะไม่สามารถเข้าถึงได้ผ่านข้อยกเว้นนี้ เปลี่ยนโปรไฟล์เป็น TCP เฉพาะเมื่อเซิร์ฟเวอร์รับฟังเช่นนั้นและผู้ดูแลยอมรับความแตกต่างของพฤติกรรม

ตรวจสอบขอบเขตด้วยตัวแยกวิเคราะห์และคำขอจริง

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

จากนั้นโหลดใหม่และส่ง CONNECT จริงหนึ่งรายการผ่านพร็อกซีจากต้นทางที่อนุมัติ การรันตัวแยกวิเคราะห์มาก่อน เพราะการโหลดใหม่ที่มีการพิมพ์ผิดไม่ได้สอนอะไรเกี่ยวกับนโยบาย

squid -k parse
squid -k reconfigure
curl -v -p -x http://proxy.lab.internal:3128 https://vpn.lab.internal:1194/ --max-time 5

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

บทความที่เกี่ยวข้อง