การส่งต่อ SSH แบบไดนามิกเป็นพร็อกซี SOCKS บน VPN ของคุณ
แอปที่พูดได้แค่ SOCKS ไม่มีปลายทางพร็อกซีบน VPN ธรรมดา สองฮอป ตัวรับฟังบนลูปแบ็กหนึ่งตัว และการค้นหาชื่อหนึ่งครั้งที่เซิร์ฟเวอร์ SSH ต้องทำเอง
แอปที่พูดได้แค่ SOCKS ไม่มีอะไรให้คุยบน VPN ธรรมดา เพราะอุโมงค์ขนส่งแพ็กเก็ต แต่แอปต้องการปลายทางพร็อกซี OpenSSH สามารถให้ปลายทางนั้นได้เมื่อเจ้าของการเข้าถึงอนุญาต เพราะการส่งต่อแบบไดนามิกเปลี่ยนเซสชัน SSH หนึ่งเซสชันให้เป็นพร็อกซีภายในเครื่อง จากนั้นมีสองฮอปที่ต้องแยกให้ชัด คืออุโมงค์ที่ไปถึงโฮสต์ SSH และการเชื่อมต่อที่โฮสต์นั้นเปิดต่อไป การแยกสองสิ่งนี้อธิบายทั้งเหตุผลที่รูปแบบนี้ทำงาน และสิ่งที่มันจะไม่มีวันทำ
ตัวรับฟัง SSH กลายเป็นอะไรและไม่เป็นอะไร
การส่งต่อแบบไดนามิกบังคับให้ไคลเอนต์ SSH รับฟังในเครื่องและพูด SOCKS4 หรือ SOCKS5 กับทุกอย่างที่เชื่อมต่อเข้ามา แต่ละคำขอระบุปลายทาง และเซิร์ฟเวอร์ SSH เปิดการเชื่อมต่อต่อไป นี่คือเหตุผลที่การค้นหาปลายทางเกิดขึ้นที่ฝั่งไกลได้ นี่คือการส่งต่อ TCP ระดับแอปพลิเคชัน ไม่ใช่ VPN สำหรับทั้งอุปกรณ์ มันไม่พา UDP แบบเชื่อมโยง ไม่พา ICMP และไม่พาอะไรให้แอปที่เพิกเฉยต่อการตั้งค่าพร็อกซีทั้งหมด ฮอปจากเซิร์ฟเวอร์ SSH ไปยังแอปก็ไม่ได้อยู่ในอุโมงค์ของคุณ ซึ่งสำคัญเมื่อปลายทางรับทราฟฟิกจากเครือข่ายที่รู้จักเท่านั้น
ข้อกำหนดเบื้องต้นเป็นของจริง คือเส้นทางไปยังโฮสต์ SSH บัญชีที่ได้รับอนุญาต คีย์โฮสต์ของเซิร์ฟเวอร์ที่ตรวจสอบแล้ว และสิทธิ์ในการส่งต่อ ไม่มีข้อใดถูกสร้างโดยพร็อกซี และข้อสุดท้ายมักหายไปก่อน ยืนยันทั้งสี่ข้อก่อนแก้ปัญหาอย่างอื่น เพราะจากฝั่งไคลเอนต์ ความล้มเหลวดูเหมือนกันไม่ว่าข้อใดจะหาย
เริ่มมันบนลูปแบ็กด้วยพอร์ตที่ระบุชัดเจน
เลือกพอร์ตภายในที่ยังไม่ถูกใช้ และผูกกับลูปแบ็กอย่างชัดเจนแทนที่จะปล่อยที่อยู่ว่างไว้ สามตัวเลือกด้านล่างมีอยู่ด้วยเหตุผลข้อละหนึ่ง
ssh -D 127.0.0.1:1080 -NT -o ControlPath=none -o ExitOnForwardFailure=yes \
[email protected]
-N ข้ามคำสั่งระยะไกล และ -T ข้ามเทอร์มินัลเทียม ดังนั้นเซสชันจึงมีอยู่เพียงเพื่อส่งต่อ ExitOnForwardFailure ทำให้ไคลเอนต์ออกเมื่อสร้างตัวรับฟังไม่ได้ แทนที่จะทำงานโดยไม่มีการส่งต่อที่คุณขอ ControlPath=none เก็บเซสชันไว้นอกการเชื่อมต่อแบบมัลติเพล็กซ์ที่มีอยู่ ซึ่งอาจเพิ่มการส่งต่อของตัวเอง ลูปแบ็กเก็บตัวรับฟังไว้นอก LAN แต่บนเครื่องที่ใช้ร่วมกันมันไม่ใช่ขอบเขตการอนุญาต เพราะโปรเซสภายในอื่นก็เข้าถึงได้เช่นกัน เอกสารอ้างอิงไคลเอนต์ OpenSSH อธิบายแฟล็กทั้งหมดนี้ และคำเตือนเรื่องลูปแบ็กเกิดจากสิ่งที่ซ็อกเก็ตที่รับฟังเป็น
ส่งชื่อผ่านพร็อกซี ไม่ใช่อ้อมมัน
ไคลเอนต์ SOCKS5 สามารถแก้ไขปลายทางเองหรือขอให้พร็อกซีทำ และตัวเลือกนั้นกำหนดว่าตัวแก้ชื่อใดจะตอบ ด้วย socks5h curl ส่งชื่อโฮสต์ผ่านพร็อกซี การค้นหาจึงเกิดขึ้นบนเซิร์ฟเวอร์ SSH ด้วย socks5 ธรรมดา แล็ปท็อปแก้ไขก่อนและมีเพียงการเชื่อมต่อที่เดินทาง ซึ่งทำลายจุดประสงค์อย่างเงียบ ๆ เมื่อชื่อเป็นชื่อภายใน คำขอด้านล่างยังล้างรายการยกเว้นพร็อกซี เพื่อให้ค่าที่สืบทอดมาจาก NO_PROXY ไม่สามารถพามันอ้อมพร็อกซีได้
curl -sS --noproxy '' --proxy socks5h://127.0.0.1:1080 https://app.corp.example/health
การตรวจสอบใบรับรองและการเข้าสู่ระบบของแอปเองยังใช้บังคับ เพราะพร็อกซีไม่ได้แทนที่ทั้งสองอย่าง ยังเหลือการค้นหาสองครั้ง คือแล็ปท็อปต้องไปถึงโฮสต์ SSH ผ่านเส้นทาง VPN และ DNS ที่อนุญาต และเซิร์ฟเวอร์ SSH ต้องแก้ชื่อแอปเอง อย่างที่สองทดสอบแยกได้ก่อนที่ทราฟฟิกใดจะผ่านพร็อกซี
ssh [email protected] getent hosts app.corp.example
พิสูจน์ปลายทางที่อนุญาตหนึ่งแห่ง แล้วปิดเซสชัน
ทดสอบปลายทางที่นโยบายอนุญาต และอีกแห่งที่ควรถูกปฏิเสธ เพราะการส่งต่อที่ทำงานได้พิสูจน์เพียงว่าตัวรับฟังทำงาน และไม่มากกว่านั้น แอปเห็นที่อยู่ต้นทางที่เซิร์ฟเวอร์ SSH เลือก และนั่นไม่ใช่ที่อยู่ของอุโมงค์แล็ปท็อปคุณ เมื่อปลายไกลบันทึกการเชื่อมต่อตามต้นทาง ความต่างนั้นคือสิ่งแรกที่ต้องตรวจเมื่อคำขอถูกปฏิเสธ
หยุดเซสชันผ่านโปรเซสที่เป็นเจ้าของ แทนการฆ่าเชลล์ที่ไม่เกี่ยวข้อง จากนั้นยืนยันว่าตัวรับฟังหายไป เพราะพอร์ตที่ยังตอบอยู่คือเซสชันที่คุณยังไม่ได้ปิดจริง ลบเฉพาะการตั้งค่าพร็อกซีที่แบบฝึกหัดนี้นำเข้ามา และปล่อยส่วนที่เหลือของการกำหนดค่าแอปไว้ เทอร์มินัลที่ไม่มีผู้ดูแลและถือกฎการส่งต่อไม่ใช่บริการ และ พร็อกซีถาวรต้องมีวงจรชีวิตที่ได้รับอนุมัติ ไม่ใช่หน้าต่างที่ถูกลืม
ss -ltn | grep 1080
ความล้มเหลวที่รูปแบบนี้แก้ไม่ได้
บางอาการชี้ตรงไปที่ขีดจำกัดข้างต้น และการรู้จักแต่เนิ่น ๆ ช่วยประหยัดบ่ายทั้งบ่ายในการแก้พร็อกซี ตารางจับคู่สิ่งที่คุณเห็นกับสิ่งที่มันมักหมายถึง ทุกอย่างในคอลัมน์สุดท้ายเป็นคำถามการออกแบบ ไม่ใช่ข้อผิดพลาดในการกำหนดค่า
| What you see | What it usually means | Where to look |
|---|---|---|
| The app connects and nothing follows | It ignores proxy settings entirely | Its own network settings, not the SSH session |
| A name resolution error for the destination | The SSH server cannot resolve it | Server resolver and search domains |
| A UDP-only application fails | Dynamic forwarding carries TCP only | This arrangement cannot serve it |
| curl works, the browser does not | The browser is not using the socks5h endpoint | Browser proxy configuration |
| The listener answers after the session ended | Another process owns port 1080 | The ss output, then the owning process |
สามแถวแรกคือแถวที่ผู้คนวินิจฉัยผิด เพราะแต่ละอย่างสร้างความพยายามเชื่อมต่อแทนที่จะเป็นข้อผิดพลาดเกี่ยวกับพร็อกซีเอง ชื่อที่แก้ได้บนแล็ปท็อปไม่ได้บอกอะไรเกี่ยวกับตัวแก้ชื่อของเซิร์ฟเวอร์ และความล้มเหลวถูกอ่านเป็นปัญหาใบรับรองหรือหมดเวลาแทน แอปที่ใช้เฉพาะ UDP อยู่นอกการออกแบบ ไม่ได้เสียอยู่ข้างใน และไม่มีตัวเลือก ssh เพิ่มเติมใดเปลี่ยนสิ่งนั้น แถวของเบราว์เซอร์คือการเตือนตามปกติว่าการตั้งค่าพร็อกซีเป็นรายแอป แถวสุดท้ายคือเหตุผลที่การตรวจตอนปิดมีอยู่ พอร์ตที่ยังรับฟังอยู่หมายความว่าตอนนี้มีอย่างอื่นเป็นเจ้าของ