# RDP Web Gateway HTML5 WebSocket-based gateway for accessing RDP connections through a web browser. This service sits in front of RdpBroker and provides a modern web interface for remote desktop access. ## Features - 🌐 **Browser-Based Access** - Connect to RDP sessions from any modern web browser - 🔒 **Secure WebSocket** - Real-time bidirectional communication - 🎨 **Modern UI** - Clean, responsive interface - 🔑 **User-Specific Targets** - Each user sees only their authorized RDP servers - 📊 **Service Health Monitoring** - Automatic RdpBroker availability checks - 🎯 **Dynamic Target Loading** - Personalized targets from RdpBroker based on user permissions - ⚡ **Low Latency** - Optimized for performance - ☁️ **Kubernetes Native** - Console-only logging for cloud environments - 🔐 **Samba AD Integration** - Authentication via RdpBroker with Samba Active Directory ## Architecture ``` User Browser (HTML5/WebSocket) ↓ RDP Web Gateway (Node.js) ↓ [WebSocket Protocol] ↓ 1. AUTH → receives user-specific targets ↓ 2. SELECT → connects to chosen target ↓ RdpBroker (C) ↓ [Samba AD Auth] ↓ [Target Authorization] ↓ [RDP Forwarding] ↓ Target RDP Servers ``` ## Authentication Flow 1. **User Login** - User enters credentials in web interface 2. **Health Check** - Web-gateway verifies RdpBroker is available 3. **WebSocket Auth** - Credentials sent via WebSocket to RdpBroker 4. **LDAP Authentication** - RdpBroker authenticates against Samba AD 5. **Target Authorization** - RdpBroker determines user's authorized targets based on groups/permissions 6. **Targets Display** - User-specific target list sent back to web-gateway 7. **Target Selection** - User chooses from their authorized servers 8. **RDP Session** - RdpBroker establishes connection to selected target ## Prerequisites - Node.js 18+ - RdpBroker service running - Modern web browser with WebSocket support ## Installation ### Local Development ```bash cd web-gateway # Install dependencies npm install # Copy environment file cp .env.example .env # Edit configuration nano .env # Start development server npm run dev ``` ### Docker Build ```bash docker build -t rdp-web-gateway:latest . ``` ## Configuration Edit `.env` file: ```env PORT=8080 RDP_BROKER_HOST=rdpbroker RDP_BROKER_PORT=3389 NODE_ENV=production # Optional: Pre-configure RDP targets (JSON array) # If not set, RdpBroker will provide targets dynamically RDP_TARGETS=[{"name":"Server1","host":"srv1.example.com","port":3389,"description":"Production Server"}] ``` ### Environment Variables | Variable | Description | Default | |----------|-------------|---------| | `PORT` | Web server listening port | `8080` | | `RDP_BROKER_HOST` | RdpBroker hostname | `rdpbroker` | | `RDP_BROKER_PORT` | RdpBroker port | `3389` | | `RDP_TARGETS` | JSON array of pre-configured targets | `null` | | `NODE_ENV` | Environment mode | `development` | ## Usage ### Access the Web Interface 1. Open your browser to `http://localhost:8080` 2. Enter your credentials (validated against Samba AD via RdpBroker) 3. Select a target from the list 4. Connect and use the remote desktop ### API Endpoints #### GET /health Health check endpoint for monitoring the web gateway. Response: ```json { "status": "healthy", "version": "1.0.0", "uptime": 12345 } ``` #### GET /api/broker-status Check if RdpBroker service is available. Response: ```json { "available": true, "broker": "rdpbroker:3389", "timestamp": "2025-12-04T10:30:00.000Z" } ``` #### GET /api/targets Fetch available RDP targets. **Success Response (200):** ```json { "targets": [ { "name": "Windows Server 2022", "host": "ws2022.example.com", "port": 3389, "description": "Production Windows Server" } ], "timestamp": "2025-12-04T10:30:00.000Z" } ``` **Service Unavailable (503):** ```json { "error": "RdpBroker service is unavailable. Please contact your administrator.", "timestamp": "2025-12-04T10:30:00.000Z" } ``` ### WebSocket Protocol Connect to `ws://localhost:8080/ws/rdp` The protocol follows a two-phase approach: 1. **Authentication Phase**: User authenticates and receives personalized target list 2. **Connection Phase**: User selects target and establishes RDP session #### Phase 1: Authentication **Client → Server - Authenticate:** ```json { "type": "authenticate", "username": "user@domain.com", "password": "password123" } ``` **Server → Client - Authentication Success with Targets:** ```json { "type": "targets", "targets": [ { "name": "Windows Server 2022", "host": "ws2022.example.com", "port": 3389, "description": "Production Windows Server (user-specific)" }, { "name": "Development Server", "host": "dev.example.com", "port": 3389, "description": "Development environment" } ] } ``` **Server → Client - Authentication Failed:** ```json { "type": "error", "error": "Invalid credentials" } ``` #### Phase 2: Connection **Client → Server - Connect to Target:** ```json { "type": "connect", "target": { "name": "Windows Server 2022", "host": "ws2022.example.com", "port": 3389 } } ``` **Server → Client - RDP Session Ready:** ```json { "type": "connected", "target": "Windows Server 2022" } ``` #### Client → Server Messages **Mouse event:** ```json { "type": "mouse", "action": "move|down|up|wheel", "x": 100, "y": 200, "button": 0, "deltaY": 0 } ``` **Keyboard event:** ```json { "type": "keyboard", "action": "down|up", "key": "a", "code": "KeyA", "ctrlKey": false, "altKey": false, "shiftKey": false } ``` **Special command:** ```json { "type": "special", "action": "ctrl-alt-del" } ``` #### Server → Client Messages **Connected:** ```json { "type": "connected", "target": "Server 01" } ``` **Resize canvas:** ```json { "type": "resize", "width": 1920, "height": 1080 } ``` **Error:** ```json { "type": "error", "error": "Error message" } ``` ## Deployment ### Kubernetes with Helm #### Option 1: LoadBalancer (Default) ```bash # Deploy with LoadBalancer service helm install rdp-web-gateway ./chart/rdp-web-gateway \ --namespace rdpbroker \ --create-namespace \ --set service.type=LoadBalancer ``` #### Option 2: Traefik IngressRoute with Let's Encrypt **Recommended for production with automatic HTTPS** 1. **Apply Traefik middlewares** (one time): ```bash kubectl apply -f chart/rdp-web-gateway/examples/traefik-middlewares.yaml -n rdpbroker ``` 2. **Deploy with Traefik IngressRoute**: ```bash # Edit the host in examples/traefik-letsencrypt.yaml # Then deploy: helm install rdp-web-gateway ./chart/rdp-web-gateway \ --namespace rdpbroker \ --create-namespace \ -f chart/rdp-web-gateway/examples/traefik-letsencrypt.yaml ``` Or directly with values: ```bash helm install rdp-web-gateway ./chart/rdp-web-gateway \ --namespace rdpbroker \ --create-namespace \ --set service.type=ClusterIP \ --set traefik.enabled=true \ --set traefik.host=rdp.yourdomain.com \ --set traefik.tls.enabled=true \ --set traefik.tls.certResolver=letsencrypt ``` 3. **Verify deployment**: ```bash # Check IngressRoute kubectl get ingressroute -n rdpbroker # Check certificate (after a few seconds) kubectl get certificate -n rdpbroker # Access your gateway https://rdp.yourdomain.com ``` #### Option 3: Standard Ingress (nginx, etc.) ```bash helm install rdp-web-gateway ./chart/rdp-web-gateway \ --namespace rdpbroker \ --create-namespace \ --set service.type=ClusterIP \ --set ingress.enabled=true \ --set ingress.className=nginx \ --set ingress.hosts[0].host=rdp.example.com \ --set ingress.hosts[0].paths[0].path=/ \ --set ingress.hosts[0].paths[0].pathType=Prefix ``` ### Important Notes for Traefik **WebSocket Support**: Traefik automatically handles WebSocket upgrades, no special configuration needed! **Let's Encrypt Certificate Resolver**: Ensure your Traefik has a certResolver named `letsencrypt` configured. Example: ```yaml # Traefik values.yaml or static config certificatesResolvers: letsencrypt: acme: email: admin@yourdomain.com storage: /data/acme.json httpChallenge: entryPoint: web ``` **Middlewares**: Apply the recommended middlewares for security: - `redirect-to-https` - Force HTTPS - `security-headers` - Security headers including WebSocket support - `rate-limit` - Prevent abuse - `compression` - Reduce bandwidth ## Browser Support - Chrome/Edge 90+ - Firefox 88+ - Safari 14+ - Opera 76+ ## Security Considerations - Use HTTPS/WSS in production - Credentials are passed directly to RdpBroker (no storage in web-gateway) - Implement rate limiting at ingress level - Enable CORS restrictions - Regular security audits - All authentication handled by RdpBroker → Samba ADs - Regular security audits ## Performance Tuning - Configure WebSocket buffer sizes - Use CDN for static assets in production - Enable HTTP compression (already included) - Adjust resource limits in Kubernetes - Use CDN for static assets in production ## Troubleshooting ### Can't connect to RdpBroker Check environment variables: ```bash echo $RDP_BROKER_HOST echo $RDP_BROKER_PORT ``` Test connectivity: ```bash nc -zv rdpbroker 3389 ``` ### WebSocket connection fails Ensure WebSocket upgrade is allowed through proxies/load balancers. **For Traefik**: Already handled automatically! ✅ **For nginx**: ```nginx location /ws/ { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } ``` **For Traefik middlewares**: Ensure security-headers middleware includes: ```yaml customResponseHeaders: Connection: "upgrade" Upgrade: "$http_upgrade" ``` ### High memory usage Adjust resource limits in Kubernetes values.yaml ## Logging All logs go to stdout/stderr for Kubernetes: ```bash # View logs kubectl logs -f deployment/rdp-web-gateway -n rdpbroker # Follow logs for all pods kubectl logs -f -l app=rdp-web-gateway -n rdpbroker ``` Reduce session timeout or implement session limits per user. ## Development ### Running Tests ```bash npm test ``` ### Code Style ```bash npm run lint ``` ## License MIT License - see LICENSE file ## Support For issues and questions, check the logs: ```bash # View logs kubectl logs -f deployment/rdp-web-gateway -n rdpbroker # Check health curl http://localhost:8080/health ```