1 điểm bởi GN⁺ 9 giờ trước | 1 bình luận | Chia sẻ qua WhatsApp
  • Đây là ứng dụng khách RDP nền web cho phép kết nối tới Windows Remote Desktop chỉ bằng trình duyệt và hoạt động không cần plugin
  • Giải pháp tách riêng Go WebAssembly chạy trong trình duyệt và proxy WebSocket-to-TCP phía máy chủ, để thay thế việc trình duyệt không thể trực tiếp mở kết nối TCP của RDP
  • Kết nối đi theo luồng Browser -> WebSocket -> proxy -> TCP -> RDP Server; sau khi kết nối, màn hình từ xa được hiển thị trên canvas và truyền tiếp thao tác bàn phím, chuột
  • Thiết bị nhập liệu hỗ trợ bàn phím dựa trên RDP scan codes và chuột gồm di chuyển, nhấp, cuộn bánh xe; âm thanh từ xa được nhận qua RDPSND và phát bằng Web Audio API
  • Vì proxy cho phép mọi origin, chỉ nên chạy trong mạng đáng tin cậy, hoặc cần đặt thêm HTTPS/WSS và lớp xác thực trước khi công khai ra bên ngoài

Tổng quan dự án

  • Hoạt động như một ứng dụng khách RDP nền web để kết nối tới Windows Remote Desktop từ trình duyệt không cần plugin
  • Việc triển khai được xây dựng bằng sự kết hợp giữa Go WebAssembly và grdp, với kiến trúc tách biệt giữa phần chạy trong trình duyệt và phần proxy trung gian
  • Vì trình duyệt không thể tự mở raw TCP socket, cần thêm một proxy Go gọn nhẹ để nối kết WebSocket sang cổng TCP của máy chủ RDP

Kiến trúc và cách hoạt động

  • Toàn bộ đường đi diễn ra theo thứ tự Browser (WASM) -> WebSocket -> proxy (Go) -> TCP -> RDP Server
  • Trong trình duyệt, binary WASM được thực thi; còn proxy đồng thời đảm nhiệm vai trò cầu nối WebSocket-to-TCP và máy chủ phục vụ tệp tĩnh
  • Kết quả của make all được chia thành static/main.wasm chạy trong trình duyệt, tệp hỗ trợ runtime Go static/wasm_exec.js, và máy chủ proxy proxy/proxy
  • Nhờ cấu trúc này, phía trình duyệt xử lý kết nối bằng công nghệ web tiêu chuẩn, còn proxy đảm nhiệm giao tiếp TCP thực tế với máy chủ RDP

Luồng sử dụng và giao diện người dùng

  • Mở http://localhost:8080 trên trình duyệt, nhập Host, Port, Domain, User, Password, Width, Height vào biểu mẫu kết nối rồi nhấn Connect để bắt đầu phiên
  • Giá trị mặc định của Port là 3389, còn Domain có thể để trống khi dùng tài khoản cục bộ
  • Khi kết nối hoàn tất, desktop từ xa sẽ hiển thị trên canvas; để nhận nhập liệu bàn phím, cần nhấp vào canvas
  • Nhấn Disconnect để kết thúc phiên

Hỗ trợ thiết bị nhập và âm thanh

  • Mọi thao tác bàn phím chuẩn đều được truyền tới desktop từ xa thông qua RDP scan codes
  • Chuột hỗ trợ di chuyển, nhấp nút và cả bánh xe cuộn
  • Tab trình duyệt phải có focus thì sự kiện bàn phím mới được truyền; nếu nhập phím bị dừng, cần nhấp lại vào vùng canvas
  • Âm thanh từ xa được stream qua RDPSND và phát trong trình duyệt bằng Web Audio API
    • Định dạng âm thanh được nêu là PCM 44100 Hz, stereo, 16-bit signed little-endian

Điều kiện vận hành và lưu ý bảo mật

  • Yêu cầu là Go 1.24 trở lên và một máy chủ RDP có thể truy cập; máy đích có thể là Windows hoặc host tương thích RDP
  • Proxy cho phép kết nối từ mọi origin, nên chỉ nên chạy trong mạng đáng tin cậy hoặc phải thêm lớp xác thực trước khi đưa ra Internet
  • Thông tin xác thực được truyền từ trình duyệt tới proxy qua WebSocket, nên trong mạng không đáng tin cậy cần dùng HTTPS/WSS
    • README cũng đề cập cách đặt reverse proxy kết thúc TLS như nginx hoặc Caddy

Hình thức chạy và thông tin bổ sung

  • Có thể chạy bằng make serve hoặc ./proxy/proxy -listen :8080 -static static
  • Tùy chọn proxy dùng -listen để chỉ định địa chỉ và cổng lắng nghe, -static để chỉ định thư mục tệp tĩnh
  • Các target dành cho phát triển được tách thành make wasm để chỉ build lại WASM, make proxy để chỉ build lại proxy, make wasm_exec để cập nhật wasm_exec.js, và make clean để xóa sản phẩm đầu ra
  • Giấy phép là GPLv3 và có kèm tham chiếu tới grdp LICENSE

1 bình luận

 
Ý kiến trên Hacker News
  • Trông khá hay. Nếu có thêm hỗ trợ ghi lại phiên làm việcxác thực SSO thì có thể dùng ngay như một RDP jump host
    Tôi đã dùng Azure Bastion theo cách tương tự: đăng nhập vào Azure Portal bằng phương thức xác thực đã cấu hình cho tenant, sau đó kết nối RDP từ trình duyệt vào VM, rồi đăng nhập bằng tài khoản cục bộ phía VM. Xử lý tệp và clipboard cũng khá ổn, và còn hỗ trợ cả phiên console ngay trong trình duyệt
    Tôi không rõ phía Windows/RDP có làm được không vì chưa dùng, nhưng SSH trên trình duyệt của GCP là một trong những thứ được làm tốt nhất mà tôi từng thấy
    Ngay cả trên Linux, đôi khi tôi cũng thấy xrdp tốt hơn các lựa chọn khác
    Một trong những giá trị lớn mà thứ này giải quyết là tách biệt giao diện quản trị của VM/server. Chỉ riêng việc dịch vụ quản trị của máy chủ web không nằm trên cùng IP/domain/giao diện với dịch vụ HTTP cũng đã cải thiện bảo mật đáng kể

    • Bên tôi dùng Apache Guacamole gắn với proxy OIDC của mình cho mục đích này
  • Clipboard trong RDP trên trình duyệt là một cơn ác mộng âm ỉ. Thương lượng giao thức wire thì tự nó vẫn ổn, nhưng Clipboard API phía trình duyệt lại bị ràng buộc bởi quyền và yêu cầu thao tác người dùng
    Phía đọc thì hầu hết trình duyệt gần như lần nào cũng yêu cầu người dùng xác nhận. Vì vậy либо phải tạo một bộ đệm clipboard riêng trong trang, hoặc việc dán vào trong RDP sẽ mượt nhưng khi sao chép ra ngoài RDP thì phải chấp nhận bấm xác nhận mỗi lần
    Cả hai cách đều khá xa so với hành vi mà mọi người kỳ vọng ở một web RDP client. Trước khi nói nó đạt mức như mstsc native, nhất định phải kiểm tra nó hoạt động khác nhau thế nào trên Chrome và Firefox

    • Có lẽ không hẳn vậy. Google Docs, Office 365, Notion hoạt động mà không liên tục xin quyền lặp đi lặp lại
  • Kể từ khi HP ngừng Anyware / Teradici / PCoIP, đã có khá nhiều người đi tìm giải pháp thay thế. Nhu cầu đặc biệt lớn là phía hỗ trợ đa màn hình độ phân giải cao, 60fps, phát lại độ sâu bit cao, hỗ trợ bảng vẽ Wacom, và đủ cả 3 hệ điều hành
    Bên trả phí thì có Parsec và DCV, còn những nỗ lực mã nguồn mở thì rất đáng mừng. Có các dự án như rustdesk, kyber, teraguchi, nên có vẻ cộng đồng thực sự cần một lựa chọn mã nguồn mở hiệu năng cao
    https://github.com/rustdesk/rustdesk
    https://github.com/thedepartmentofexternalservices/teraguchi
    https://kyber.tech/

    • Nhân tiện, DCV miễn phí trên EC2, và ngay cả ở môi trường khác thì cảnh báo khi không có license cũng khá nhẹ nhàng
  • Trông khá thú vị, nhưng lạ là tính năng quan trọng nhất lại không được nhắc tới. Tôi rất muốn biết chia sẻ clipboard thực tế hoạt động tốt đến mức nào

    • Dù không đặc biệt thích Windows, tôi vẫn thấy như phép màu mỗi khi có thể sao chép/dán tệp qua lại giữa 3 phiên RDP lồng nhau
    • Bên tôi cũng đang làm một RDP client tùy chỉnh nên có chút kinh nghiệm triển khai kiểu này. Chúng tôi cũng triển khai theo cách tương tự
      Chia sẻ clipboard, tải lên/tải xuống qua ổ đĩa dùng chung là các tính năng của FreeRDP nên tương đối có thể tận dụng ngay
      ghi hình phiên làm việc là thứ không thể thỏa hiệp trong môi trường PAM
      [1] https://adaptive.live
  • Desktop scaling, hỗ trợ đa màn hình, truyền tệp, chuyển hướng ổ đĩa và chuyển hướng thiết bị ngoại vi đều rất quan trọng

  • Tôi cũng muốn biết liệu cái này có hoạt động khi mở tệp RDP nhận từ CyberArk PAM hay không

  • Tôi cũng tò mò liệu Alt-Tab trong tab trình duyệt có thể bị RDP client chặn lại hay không
    Ngày trước đó là vấn đề lớn nhất của RDP trên trình duyệt trong Guacamole

  • Về mặt kỹ thuật thì thú vị, nhưng hầu như nền tảng nào cũng đã có native RDP client, nên tôi không thật sự hiểu tại sao lại cần nó

    • Nếu chạy trong trình duyệt thì không cần cài gì lên máy cục bộ cả. Hồi trước khi còn bị kẹt trong ô làm việc ở công ty, tôi hay dùng Apache Guacamole để truy cập máy tính ở nhà
      https://guacamole.apache.org/
    • 1 người đóng góp, 1 commit, dự án mới, nên hơi có cảm giác vibe-coding
    • Trình duyệt là sandbox còn native client thì thường không phải vậy, nên đây là một lợi thế rõ ràng. Nó cũng tiện cho tính di động và nhúng, và cũng đơn giản hơn để kiểm tra lưu lượng hoặc làm MITM
    • Native RDP/RDG không có nhiều lựa chọn MFA đủ ổn. Đưa nó lên trình duyệt thì có thể bọc toàn bộ bằng OAuth hoặc passkey
    • Có vẻ cũng có thể dùng làm web client cho desktop từ xa gắn với chip BMC