SSH Tunnel ท่าไหนดี
หลังจากที่คุยเรื่อง SSH Tunnel แบบ -D ไปมีน้องมาถามเพิ่มฮะ รอบนี้เลยอธิบายเพิ่มอีกหน่อยนึงหล่ะกันนะ
SSH Tunnel จะมีท่าอยู่ 3 ท่า
- Local Port Forwarding — เปิด Port ในเครื่องตัวเองเพื่อ Forward ไปที่เครื่องหรือ Network ปลายทาง
- Remote Port Forwarding — เปิด Port ที่เครื่องปลายทาง เพื่อ Forward มาให้ที่เครื่องตัวเอง
- Dynamic Port — เปิด Port เพื่อต่อไปที่ไหนก็ได้ใน Network ปลายทาง ผ่าน SOCK protocol
1. Local Port Forwarding
เมื่อสั่ง ssh ด้วย -L เช่น
ssh -L 3001:localhost:3000 user@testserver.net
เราจะสามารถใช้งาน remote port 3000 ได้ผ่าน port 3001 ในเครื่องตัวเอง เช่น
เราสามารถที่จะเปิดเว็บ ผ่าน
http://localhost:3001
ตัวอย่างที่เหมาะสำหรับกรณีนี้คือ สถานการณ์ที่เราสามารถเชื่อมเข้าสู่ระบบปลายทางได้ผ่าน ssh เท่านั้น แค่ Service ที่เหลือซึ่งเป็นระบบภายในไม่สามารถเชื่อมต่อจากข้างนอกได้
เช่นจากรูปตัวอย่าง ถ้าเราต้องการเชื่อมต่อกับ port 3389 ซึ่งเป็น Port สำหรับทำ Windows Remote Desktop ของเครื่องภายในที่สามารถเชื่อมต่อได้จาก Server A เท่านั้น ใน Server A เราก็จะสั่ง ssh ไปหา Server B โดยพิมพ์ว่า
ssh -L 1.2.3.4:1234:localhost:3389 B
port 3389 ก็จะสามารถเข้าถึงได้ ผ่าน Server A ที่ 1.2.3.4:1234 ได้
อย่างไรก็ตาม การใส่ Binding Address เป็นสิ่งที่ต้องระมัดระวัง โดยเฉพาะในกรณีที่ A เป็นเซิร์ฟเวอร์ที่สามารถ เข้าถึงได้จากสาธารณะ
นอกจากนี้ เราไม่จำเป็นที่จะต้องเข้าเฉพาะ Server ที่ทำการ ssh ได้เท่านั้น เราสามารถเชื่อมกับ Server/Port ที่สามารถเข้าถึงได้จาก Server ที่เรา ssh ไปได้ด้วย เช่น
ถ้าในเครือข่ายของเซิร์ฟเวอร์ B มี เซิร์ฟเวอร์ C อยู่ด้วย และเปิด Port 3389 เช่นเดียวกัน เราก็สามารถเข้าถึง Server C ได้เช่นเดียวกัน
A$ ssh -L 1234:C:3389 B
2. Remote Port Forwarding
ในบางครั้งระบบเครือข่ายก็มีความปลอดภัยจนไม่สามารถที่จะเชื่อมได้จากภายนอกเลย แล้วถ้าจำเป็นต้องให้มีการเชื่อมต่อกับระบบในกรณีฉุกเฉินจะทำยังไงได้บ้าง
ssh -R จะทำหน้าที่แตกต่างออกไป กล่าวคือ เมื่อเรียก Parameter นี้ ssh จะไปเปิด port ที่ server ปลายทาง เมื่อมีใครมาเชื่อมต่อกับ port ที่ server ปลายทาง จะมีการ forward กลับมาที่เครื่องต้นทาง ใน port ที่กำหนด
เมื่อผู้ใช้ที่เครื่อง B อยากให้ ผู้ใช้ที่ เครื่อง A ใช้งาน port 3389 ที่เครื่อง B แต่เนื่องจาก Firewall รอบนี้แข็งแกร่งมา ไม่อนุญาตให้เปิดรับ connection ใดๆจากภายนอก สิ่งที่เราจะทำก็คือ เราจะ ssh จากเครื่อง B ไปหาเครื่อง A แล้วสั่ง เปิด port 1234 เพื่อรับ connection แล้ว forward มาที่ port 3389 ของเครื่อง B นั่นเอง
B$ ssh -R 1234:localhost:3389 A
โดยสิ่งที่แตกต่างจาก Local Forward คือ port ที่จะถูกเปิดจะเป็น port ของเครื่องปลายทาง ไม่ใช่เครื่องตัวเองเหมือน การใช้ -L
และ parameter ส่วนหลังที่เป็น localhost:3389 ก็จะหมายถึงเครื่องตัวเอง เป็นสิ่งที่จะแสดงให้เห็นถึงพฤติกรรมว่า เป็นการเปิด port ที่ปลายทางแล้ว forward กลับมาหาตัวเอง จึงเรียกว่า Remote Forwarding
3. Dynamic Forwarding
ในการใช้งาน จาก 2 แบบข้างต้นจะเป็นสิ่งที่เรียกว่า Port Forwarding ซึ่งจะเห็นว่า ในการเรียกใช้งาน เราอาจจะต้องเปลี่ยนชื่อ host หรือ port ที่ต้องการเชื่อมต่อ เป็น port ของ tunnel ซึ่งวิธีการนี้อาจจะมีข้อจำกัดในบางกรณี โดยเฉพาะกรณีที่เราจำเป็นที่จะต้องรักษา hostname หรือ IP address ให้เป็นเหมือนเดิม ไม่สามารถเปลี่ยนค่าได้
นอกจากนี้อาจจะมีเรื่องของ Port ที่ต้อง Map เพื่อทำการ Forward ที่อาจะเป็น Dynamic จนเราไม่แน่ใจว่าจะไล่รายการมาครบไหม เราจึงต้องใช้ท่าที่สนับสนุนการใช้ Port ใดๆ โดยไม่ต้องประกาศน่าจะเป็นวิธีที่ดีกว่า
การใช้ -D จึงเป็นอีกวิธีหนึ่งที่น่าจะช่วยแก้ปัญหานี้ได้ โดยสิ่งที่ -D ทำคือการเปิด Port เพื่อรองรับ SOCK Protocol โดย SOCK Protocol นั้นจะทำหน้าที่เป็น Application Proxy ในการเข้าถึง เครื่องปลายทาง
A$ ssh -D 1234 B
หลังจากที่ใช้คำสั่งนี้ เครื่องของเราจะเปิด port สำหรับ SOCKS เราก็ไปตั้งค่า SOCKS ให้เรียบร้อย ก็จะสามารถเชื่อมต่อระบบได้ครับ ยกตัวอย่างเช่น ในวงภายใน มีเครื่องชื่อ internal.server.com เราก็สามารถเข้าถึงเครื่องนี้จากการพิมพ์
http://internal.server.com
ได้ทันที โดยไม่ต้องเปลี่ยนเป็น localhost แต่อย่างใด
อย่างไรก็ตาม บางระบบก็ไม่ได้สนับสนุน SOCKS เราอาจจะจำเป็นที่ต้องใช้ proxy มาช่วย ก็ขอให้กลับไปดูในบทความก่อน ที่พูดถึง การใช้ web proxy ผ่าน ssh ครับ
นอกเหนือจากนี้ใครสนใจท่า Advance อะไรก็แล้วแต่ ลองดูใน man ssh
ซึ่งจะมีรายละเอียดเกี่ยวกับการวาง parameter มากกว่าที่ทางผมได้เขียนไว้ครับ
ก็หวังว่าจะเป็นประโยชน์ครับ สวัสดีครับ