แอปที่พูดได้แค่ 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 seeWhat it usually meansWhere to look
The app connects and nothing followsIt ignores proxy settings entirelyIts own network settings, not the SSH session
A name resolution error for the destinationThe SSH server cannot resolve itServer resolver and search domains
A UDP-only application failsDynamic forwarding carries TCP onlyThis arrangement cannot serve it
curl works, the browser does notThe browser is not using the socks5h endpointBrowser proxy configuration
The listener answers after the session endedAnother process owns port 1080The ss output, then the owning process

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

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