ไคลเอนต์ RDP แบบเว็บที่สร้างด้วย Go WebAssembly และ grdp
(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 ขณะที่พร็อกซีทำหน้าที่ทั้งเป็นสะพาน WebSocket-to-TCP และเป็นเซิร์ฟเวอร์ไฟล์สแตติก
- ผลลัพธ์จาก
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 ว่างได้เมื่อใช้บัญชีภายในเครื่อง - เมื่อเชื่อมต่อสำเร็จ เดสก์ท็อประยะไกลจะแสดงบน 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สำหรับล้างไฟล์ผลลัพธ์ - ใบอนุญาตคือ 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/