grdpwasm - ไคลเอนต์ RDP แบบเว็บ
(github.com/nakagami)- เป็น ไคลเอนต์ RDP แบบเว็บ ที่สามารถเชื่อมต่อกับ Windows Remote Desktop ได้ด้วยเบราว์เซอร์เพียงอย่างเดียว และทำงานได้โดย ไม่ต้องใช้ plugin
- แยกส่วน Go WebAssembly ฝั่งเบราว์เซอร์และ พร็อกซี WebSocket-to-TCP ฝั่งเซิร์ฟเวอร์ เพื่อจัดการการเชื่อมต่อ RDP TCP แทนเบราว์เซอร์ที่ไม่สามารถเปิดการเชื่อมต่อดังกล่าวได้โดยตรง
- การเชื่อมต่อทำงานตามลำดับ
Browser -> WebSocket -> proxy -> TCP -> RDP Serverและหลังจากเชื่อมต่อแล้ว หน้าจอรีโมตจะแสดงบน canvas พร้อมส่งต่ออินพุตจากคีย์บอร์ดและเมาส์ - อุปกรณ์อินพุตรองรับคีย์บอร์ดที่อิงตาม RDP scan codes และเมาส์ที่รองรับการเลื่อน การคลิก และล้อเมาส์ ส่วนเสียงรีโมตรับผ่าน RDPSND และเล่นด้วย Web Audio API
- เนื่องจากโครงสร้างพร็อกซีอนุญาตทุก origin จึงควรรันเฉพาะใน เครือข่ายที่เชื่อถือได้ หรือวาง HTTPS/WSS และชั้นยืนยันตัวตน ไว้ก่อนเปิดให้เข้าถึงจากภายนอก
ภาพรวมโครงการ
- ทำงานเป็น ไคลเอนต์ RDP แบบเว็บ สำหรับเชื่อมต่อกับ Windows Remote Desktop จากเบราว์เซอร์โดย ไม่ต้องใช้ plugin
- การใช้งานถูกสร้างด้วย Go WebAssembly ร่วมกับ grdp และมีโครงสร้างที่แยกส่วนรันบนเบราว์เซอร์ออกจากส่วนพร็อกซีกลาง
- เนื่องจากเบราว์เซอร์ไม่สามารถเปิด raw TCP socket ได้โดยตรง จึงต้องมี พร็อกซี Go แบบเบา เพิ่มเติมเพื่อเชื่อมต่อ WebSocket ไปยังพอร์ต TCP ของเซิร์ฟเวอร์ RDP
สถาปัตยกรรมและวิธีการทำงาน
- เส้นทางทั้งหมดทำงานตามลำดับ
Browser (WASM) -> WebSocket -> proxy (Go) -> TCP -> RDP Server - ฝั่งเบราว์เซอร์จะรัน WASM binary ขณะที่พร็อกซีทำหน้าที่ทั้งเป็นสะพาน WebSocket-to-TCP และเป็น static file server
- ผลลัพธ์จาก
make allแยกเป็นstatic/main.wasmที่รันในเบราว์เซอร์, ไฟล์สนับสนุน Go runtimestatic/wasm_exec.js, และพร็อกซีเซิร์ฟเวอร์proxy/proxy - ด้วยโครงสร้างนี้ ฝั่งเบราว์เซอร์จึงจัดการการเชื่อมต่อด้วยเทคโนโลยีเว็บมาตรฐาน ขณะที่การสื่อสาร TCP จริงกับเซิร์ฟเวอร์ RDP เป็นหน้าที่ของพร็อกซี
ขั้นตอนการใช้งานและส่วนติดต่อผู้ใช้
- เปิด
http://localhost:8080ในเบราว์เซอร์ กรอกค่า Host, Port, Domain, User, Password, Width, Height ในฟอร์มเชื่อมต่อ แล้วกด Connect เพื่อเริ่มเซสชัน - ค่าเริ่มต้นของ Port คือ
3389และสามารถเว้น Domain ว่างไว้ได้เมื่อใช้บัญชี local - เมื่อเชื่อมต่อสำเร็จ เดสก์ท็อประยะไกลจะแสดงบน canvas และต้องคลิกที่ canvas ก่อนจึงจะรับอินพุตจากคีย์บอร์ดได้
- กด Disconnect เพื่อจบเซสชัน
อุปกรณ์อินพุตและการรองรับเสียง
- อินพุตจากคีย์บอร์ดมาตรฐานทั้งหมดจะถูกส่งไปยังเดสก์ท็อประยะไกลผ่าน RDP scan codes
- เมาส์รองรับการเคลื่อนที่ การคลิกปุ่ม และล้อเลื่อน
- แท็บของเบราว์เซอร์ต้องมีโฟกัสจึงจะส่งอีเวนต์คีย์บอร์ดได้ และหากการพิมพ์หยุดทำงาน ต้องคลิกบริเวณ canvas อีกครั้ง
- เสียงรีโมตสตรีมผ่าน RDPSND และเล่นในเบราว์เซอร์ด้วย Web Audio API
- ระบุรูปแบบเสียงเป็น PCM 44100 Hz, stereo, 16-bit signed little-endian
เงื่อนไขการใช้งานและข้อควรระวังด้านความปลอดภัย
- ข้อกำหนดคือ Go 1.24 ขึ้นไป และมีเซิร์ฟเวอร์ RDP ที่เข้าถึงได้หนึ่งตัว โดยเซิร์ฟเวอร์ปลายทางอาจเป็น Windows หรือโฮสต์ที่เข้ากันได้กับ RDP
- พร็อกซีอนุญาตการเชื่อมต่อจากทุก origin ดังนั้นควรรันเฉพาะใน เครือข่ายที่เชื่อถือได้ หรือเพิ่มชั้นยืนยันตัวตนก่อนเปิดใช้งานบนอินเทอร์เน็ต
- เนื่องจากข้อมูลรับรองจะถูกส่งจากเบราว์เซอร์ไปยังพร็อกซีผ่าน WebSocket จึงจำเป็นต้องใช้ HTTPS/WSS บนเครือข่ายที่ไม่น่าเชื่อถือ
- README ยังระบุวิธีวาง reverse proxy แบบ TLS termination เช่น nginx หรือ Caddy ไว้ด้วย
รูปแบบการรันและข้อมูลเพิ่มเติม
- สามารถรันได้ด้วย
make serveหรือ./proxy/proxy -listen :8080 -static static - ตัวเลือกของพร็อกซีกำหนดที่อยู่และพอร์ตรับฟังด้วย
-listenและกำหนดไดเรกทอรีไฟล์สแตติกด้วย-static - เป้าหมายสำหรับการพัฒนาจะแยกเป็น
make wasmสำหรับ build WASM ใหม่เท่านั้น,make proxyสำหรับ build พร็อกซีใหม่เท่านั้น,make wasm_execสำหรับอัปเดตwasm_exec.js, และmake cleanสำหรับลบผลลัพธ์การ build - ใบอนุญาตคือ GPLv3 และมีลิงก์อ้างอิง grdp LICENSE แนบไว้ด้วย
2 ความคิดเห็น
แต่ผมไม่รู้ข้อดีที่แท้จริงนะ
มันก็เป็นแค่ไคลเอนต์เท่านั้น เลยไม่สามารถบังคับข้อกำหนดอะไรจากฝั่งเซิร์ฟเวอร์ได้
และก็ไม่ได้เข้าถึงได้ด้วยเบราว์เซอร์ล้วน ๆ ด้วย
ความเห็นจาก Hacker News
ดูค่อนข้างเจ๋งทีเดียว ถ้ารองรับ การบันทึกเซสชัน และ การยืนยันตัวตนแบบ SSO เพิ่มเข้ามาได้ ก็น่าจะเอาไปใช้เป็น RDP jump host ได้เลย
เคยใช้ Azure Bastion ในลักษณะคล้ายกัน โดยล็อกอินเข้า Azure portal ด้วยวิธีการยืนยันตัวตนที่ตั้งไว้ใน tenant จากนั้นต่อ RDP ไปยัง VM ผ่านเบราว์เซอร์ แล้วค่อยล็อกอินด้วยบัญชี local ฝั่ง VM ได้ การจัดการไฟล์และคลิปบอร์ดก็ทำได้ค่อนข้างดี และยังรองรับคอนโซลเซสชันภายในเบราว์เซอร์ด้วย
ฝั่ง Windows/RDP ยังไม่เคยลองเลยไม่แน่ใจว่าเป็นอย่างไร แต่ browser SSH ของ GCP เป็นหนึ่งในงานที่ทำออกมาดีที่สุดเท่าที่เคยเห็น
แม้บน Linux บางครั้งก็รู้สึกว่า xrdp ดีกว่าทางเลือกอื่น
คุณค่าหลักอย่างหนึ่งที่สิ่งนี้แก้ได้คือ การแยกอินเทอร์เฟซสำหรับการจัดการ ของ VM/เซิร์ฟเวอร์ แค่ไม่ให้บริการจัดการของเว็บเซิร์ฟเวอร์อยู่บน IP/โดเมน/อินเทอร์เฟซเดียวกับบริการ HTTP ก็ช่วยเรื่องความปลอดภัยได้มากแล้ว
สำหรับ RDP บนเบราว์เซอร์ คลิปบอร์ด เป็นฝันร้ายแบบแอบ ๆ เลย ตัวการเจรจา wire protocol เองทำงานได้ดี แต่ Clipboard API ฝั่งเบราว์เซอร์ถูกผูกกับสิทธิ์และข้อกำหนดเรื่อง user gesture
ฝั่งการอ่านนั้น เบราว์เซอร์ส่วนใหญ่แทบจะขอให้ผู้ใช้ยืนยันแทบทุกครั้ง ดังนั้นจึงต้องสร้างบัฟเฟอร์คลิปบอร์ดแยกไว้ในหน้า หรือไม่ก็ทำให้การวางเข้าไปใน RDP ลื่นไหล แต่ตอนคัดลอกออกมาจาก RDP ต้องยอมคลิกทุกครั้ง
ไม่ว่าทางไหนก็ยังห่างจากพฤติกรรมที่คนคาดหวังจาก เว็บ RDP ไคลเอนต์ อยู่ดี ก่อนจะบอกว่าเทียบระดับ native mstsc ได้ ควรเช็กให้แน่ใจว่าพฤติกรรมต่างกันอย่างไรใน Chrome และ Firefox
หลังจากที่ HP ยุติ Anyware / Teradici / PCoIP ก็มีคนจำนวนไม่น้อยที่กำลังมองหาทางเลือกใหม่ โดยเฉพาะฝั่งที่ต้องการรองรับมัลติมอนิเตอร์ความละเอียดสูง, 60fps, การเล่นภาพที่มี bit depth สูง, การรองรับแท็บเล็ต Wacom และรองรับครบทั้ง 3 OS
ฝั่งเสียเงินก็มี Parsec กับ DCV และก็ยินดีที่ได้เห็นความพยายามแบบโอเพนซอร์ส มีโปรเจกต์อย่าง rustdesk, kyber, teraguchi อยู่ ซึ่งดูเหมือนชุมชนจำเป็นต้องมีตัวเลือกโอเพนซอร์สประสิทธิภาพสูง
https://github.com/rustdesk/rustdesk
https://github.com/thedepartmentofexternalservices/teraguchi
https://kyber.tech/
ดูน่าสนใจในเชิงแนวคิด แต่แปลกใจที่ไม่ได้พูดถึงฟีเจอร์ที่สำคัญที่สุด อยากรู้ว่า การแชร์คลิปบอร์ด ทำได้ดีแค่ไหนในการใช้งานจริง
การแชร์คลิปบอร์ดและอัปโหลด/ดาวน์โหลดผ่าน shared drive เป็นฟีเจอร์ของ FreeRDP จึงเอามาใช้ต่อได้ค่อนข้างตรงไปตรงมา
และ การบันทึกเซสชัน เป็นสิ่งที่ต่อรองไม่ได้ในสภาพแวดล้อม PAM
[1] https://adaptive.live
การสเกลเดสก์ท็อป, การรองรับหลายจอ, การส่งไฟล์, การรีไดเร็กต์ไดรฟ์ และการรีไดเร็กต์อุปกรณ์ต่อพ่วง ก็สำคัญทั้งหมด
สงสัยว่ามันจะใช้ได้ไหมเวลาเปิดไฟล์ RDP ที่ได้มาจาก CyberArk PAM
สงสัยเหมือนกันว่าในแท็บเบราว์เซอร์ Alt-Tab จะถูก RDP ไคลเอนต์ดักจับได้หรือเปล่า
เมื่อก่อนนั่นเป็นปัญหาใหญ่ที่สุดของ RDP บนเบราว์เซอร์ของ Guacamole
น่าสนใจในเชิงเทคนิค แต่ก็ยังไม่ค่อยเข้าใจว่าทำไมถึงจำเป็น ในเมื่อแทบทุกแพลตฟอร์มมี native RDP ไคลเอนต์ อยู่แล้ว
https://guacamole.apache.org/