8 คะแนน โดย GN⁺ 24 일 전 | 2 ความคิดเห็น | แชร์ทาง WhatsApp
  • เป็น ไคลเอนต์ 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 runtime static/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 ความคิดเห็น

 
yeobi222 23 일 전

แต่ผมไม่รู้ข้อดีที่แท้จริงนะ
มันก็เป็นแค่ไคลเอนต์เท่านั้น เลยไม่สามารถบังคับข้อกำหนดอะไรจากฝั่งเซิร์ฟเวอร์ได้
และก็ไม่ได้เข้าถึงได้ด้วยเบราว์เซอร์ล้วน ๆ ด้วย

 
GN⁺ 24 일 전
ความเห็นจาก 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 ก็ช่วยเรื่องความปลอดภัยได้มากแล้ว

    • เราใช้ Apache Guacamole คู่กับ OIDC proxy ของเราสำหรับจุดประสงค์นี้
  • สำหรับ RDP บนเบราว์เซอร์ คลิปบอร์ด เป็นฝันร้ายแบบแอบ ๆ เลย ตัวการเจรจา wire protocol เองทำงานได้ดี แต่ Clipboard API ฝั่งเบราว์เซอร์ถูกผูกกับสิทธิ์และข้อกำหนดเรื่อง user gesture
    ฝั่งการอ่านนั้น เบราว์เซอร์ส่วนใหญ่แทบจะขอให้ผู้ใช้ยืนยันแทบทุกครั้ง ดังนั้นจึงต้องสร้างบัฟเฟอร์คลิปบอร์ดแยกไว้ในหน้า หรือไม่ก็ทำให้การวางเข้าไปใน RDP ลื่นไหล แต่ตอนคัดลอกออกมาจาก RDP ต้องยอมคลิกทุกครั้ง
    ไม่ว่าทางไหนก็ยังห่างจากพฤติกรรมที่คนคาดหวังจาก เว็บ RDP ไคลเอนต์ อยู่ดี ก่อนจะบอกว่าเทียบระดับ native mstsc ได้ ควรเช็กให้แน่ใจว่าพฤติกรรมต่างกันอย่างไรใน Chrome และ Firefox

    • ดูเหมือนจะไม่ถึงกับเป็นแบบนั้นนะ Google Docs, Office 365, Notion ทำงานได้โดยไม่ขอสิทธิ์ซ้ำ ๆ
  • หลังจากที่ 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/

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

    • ไม่ได้ชอบ Windows เป็นพิเศษ แต่ทุกครั้งที่คัดลอก/วางไฟล์ข้าม RDP เซสชันซ้อน 3 ชั้น ได้ ก็ยังรู้สึกเหมือนเวทมนตร์อยู่ดี
    • เราก็กำลังทำ RDP ไคลเอนต์ แบบคัสตอมอยู่ เลยมีประสบการณ์กับการทำอะไรแนวนี้อยู่บ้าง ทำในลักษณะคล้าย ๆ กัน
      การแชร์คลิปบอร์ดและอัปโหลด/ดาวน์โหลดผ่าน shared drive เป็นฟีเจอร์ของ FreeRDP จึงเอามาใช้ต่อได้ค่อนข้างตรงไปตรงมา
      และ การบันทึกเซสชัน เป็นสิ่งที่ต่อรองไม่ได้ในสภาพแวดล้อม PAM
      [1] https://adaptive.live
  • การสเกลเดสก์ท็อป, การรองรับหลายจอ, การส่งไฟล์, การรีไดเร็กต์ไดรฟ์ และการรีไดเร็กต์อุปกรณ์ต่อพ่วง ก็สำคัญทั้งหมด

  • สงสัยว่ามันจะใช้ได้ไหมเวลาเปิดไฟล์ RDP ที่ได้มาจาก CyberArk PAM

  • สงสัยเหมือนกันว่าในแท็บเบราว์เซอร์ Alt-Tab จะถูก RDP ไคลเอนต์ดักจับได้หรือเปล่า
    เมื่อก่อนนั่นเป็นปัญหาใหญ่ที่สุดของ RDP บนเบราว์เซอร์ของ Guacamole

  • น่าสนใจในเชิงเทคนิค แต่ก็ยังไม่ค่อยเข้าใจว่าทำไมถึงจำเป็น ในเมื่อแทบทุกแพลตฟอร์มมี native RDP ไคลเอนต์ อยู่แล้ว

    • ถ้าทำงานในเบราว์เซอร์ได้ ก็ไม่ต้องติดตั้งอะไรเลยบนเครื่อง local สมัยก่อนตอนยังต้องนั่งแหมะอยู่ในคิวบิเคิลที่บริษัท ผมใช้ Apache Guacamole บ่อยมากเพื่อเข้าเครื่องคอมที่บ้าน
      https://guacamole.apache.org/
    • มีผู้มีส่วนร่วม 1 คน คอมมิต 1 ครั้ง และเป็นโปรเจกต์ใหม่ เลยให้ความรู้สึกแบบ vibe-coding อยู่หน่อย
    • เบราว์เซอร์เป็น sandbox แต่ไคลเอนต์เนทีฟส่วนใหญ่มักไม่เป็นแบบนั้น จึงมีข้อดีชัดเจน ทั้งเรื่องการพกพาและการฝังใช้งาน และยังทำให้การตรวจดูทราฟฟิกหรือทำ MITM ง่ายกว่า
    • native RDP/RDG ยังมีตัวเลือก MFA ดี ๆ ไม่มากนัก แต่ถ้ายกขึ้นมาอยู่บนเบราว์เซอร์ ก็สามารถครอบทั้งหมดด้วย OAuth หรือ passkey ได้
    • น่าจะใช้เป็นเว็บไคลเอนต์สำหรับ remote desktop ที่ต่ออยู่กับ ชิป BMC ได้ด้วย