Files
rdpgw/docs/ms-app-proxy-deployment.md
2025-09-18 23:11:31 +02:00

259 lines
6.6 KiB
Markdown

# Microsoft Azure Application Proxy Deployment Guide
This guide provides step-by-step instructions for deploying RDPGW behind Microsoft Azure Application Proxy with Conditional Access Policy enforcement.
## Architecture Overview
```
Internet → Azure AD (Auth + CAP) → App Proxy → RDPGW (Internal) → RDP Hosts
```
**Authentication Flow:**
- **Web requests** (`/connect`): Full Azure AD authentication with headers
- **RDP protocol** (`/remoteDesktopGateway/`): Passthrough with token validation
## Prerequisites
- Azure AD Premium P1/P2 (for Conditional Access)
- Azure AD Application Proxy connector installed
- RDPGW deployed internally
- Network connectivity from connector to RDPGW
## Step 1: Azure AD App Registration
```powershell
# Create app registration
$app = New-AzADApplication -DisplayName "RDPGW-AppProxy" `
-HomePage "https://rdpgw.yourdomain.com" `
-IdentifierUris "https://rdpgw.yourdomain.com"
# Note the Application ID
Write-Host "Application ID: $($app.ApplicationId)"
```
## Step 2: Configure Application Proxy
### Portal Configuration
1. **Navigate to**: Azure AD → Enterprise Applications → New Application
2. **Select**: On-premises application
3. **Configure**:
- **Name**: RDPGW
- **Internal URL**: `http://rdpgw-server:80`
- **External URL**: `https://rdpgw.yourdomain.com`
- **Pre-authentication**: Azure Active Directory
- **Connector Group**: Select appropriate connector
### Advanced Configuration
```json
{
"application": {
"name": "RDPGW",
"internalUrl": "http://rdpgw-server",
"externalUrl": "https://rdpgw.yourdomain.com",
"preAuthentication": "aadPreAuthentication",
"externalAuthenticationType": "aadPreAuthentication",
"applicationProxyUrlSettings": {
"externalUrl": "https://rdpgw.yourdomain.com",
"internalUrl": "http://rdpgw-server",
"isTranslateHostHeaderEnabled": true,
"isTranslateLinksInBodyEnabled": false,
"isOnPremPublishingEnabled": true
}
}
}
```
## Step 3: Configure Passthrough for RDP Endpoint
**Critical**: Configure App Proxy to bypass authentication for RDP connections:
### PowerShell Configuration
```powershell
# Get the application
$app = Get-AzADApplication -DisplayName "RDPGW-AppProxy"
# Configure passthrough paths (if available via API)
# Note: This may need to be configured via Support ticket
$passthroughPaths = @("/remoteDesktopGateway/*")
```
### Support Request
If passthrough configuration isn't available in portal:
1. **Open Azure Support Ticket**
2. **Request**: Passthrough configuration for `/remoteDesktopGateway/*` path
3. **Provide**: Application ID and external URL
4. **Reason**: RDP client compatibility requirements
## Step 4: RDPGW Configuration
### Complete Configuration File
```yaml
# rdpgw.yaml
Server:
Authentication:
- header
Tls: disable
GatewayAddress: https://rdpgw.yourdomain.com
Port: 80
Hosts:
- server1.internal.domain:3389
- server2.internal.domain:3389
- "{{ preferred_username }}-desktop:3389" # Dynamic host mapping
Header:
UserHeader: "X-MS-CLIENT-PRINCIPAL-NAME"
UserIdHeader: "X-MS-CLIENT-PRINCIPAL-ID"
EmailHeader: "X-MS-CLIENT-PRINCIPAL-EMAIL"
Security:
VerifyClientIp: false
PAATokenSigningKey: "your-32-character-signing-key-here"
PAATokenEncryptionKey: "your-32-character-encryption-key"
Caps:
TokenAuth: true
IdleTimeout: 60
Client:
UsernameTemplate: "{{ username }}\x1f{{ token }}"
```
### Docker Deployment
```yaml
# docker-compose.yml
services:
rdpgw:
image: bolkedebruin/rdpgw:latest
ports:
- "80:443"
volumes:
- ./rdpgw.yaml:/app/rdpgw.yaml:ro
environment:
- RDPGW_SERVER__TLS=disable
- RDPGW_SERVER__PORT=443
networks:
- internal
networks:
internal:
driver: bridge
```
## Step 5: Conditional Access Policy
### Create CAP for RDPGW
```powershell
# PowerShell example (simplified)
$conditions = @{
"applications" = @{
"includeApplications" = @($app.ApplicationId)
}
"users" = @{
"includeGroups" = @("rdp-users-group-id")
}
"locations" = @{
"includeLocations" = @("AllTrusted")
}
}
$grantControls = @{
"operator" = "OR"
"builtInControls" = @("mfa", "compliantDevice")
}
```
### Portal Configuration
1. **Navigate to**: Azure AD → Security → Conditional Access
2. **Create Policy**:
- **Name**: RDPGW Access Control
- **Users**: Select appropriate groups
- **Cloud apps**: Select RDPGW application
- **Conditions**: Configure as needed (device, location, etc.)
- **Grant**: Require MFA + Compliant Device
- **Session**: Configure session lifetime
## Step 6: Testing
### Test Web Authentication
```bash
# Test /connect endpoint
curl -v https://rdpgw.yourdomain.com/connect
# Should redirect to Azure AD login
```
### Test RDP Connection
1. **Access web interface**: `https://rdpgw.yourdomain.com/connect`
2. **Authenticate**: Complete Azure AD login + MFA
3. **Download RDP file**: Should contain token-based credentials
4. **Connect via RDP client**: Should work without additional authentication
### Verify Headers
Check that App Proxy forwards correct headers:
```bash
# From internal network, test RDPGW directly
curl -H "X-MS-CLIENT-PRINCIPAL-NAME: user@domain.com" \
http://rdpgw-server/connect
```
## Troubleshooting
### Common Issues
1. **RDP Client Won't Connect**:
- Verify passthrough configuration for `/remoteDesktopGateway/*`
- Check token generation in downloaded RDP file
- Ensure `TokenAuth: true` in configuration
2. **Authentication Loop**:
- Verify header configuration matches App Proxy headers
- Check `VerifyClientIp: false` setting
- Validate App Proxy connector connectivity
3. **CAP Not Enforced**:
- Verify policy targets correct application
- Check user/group assignments
- Review conditional access logs
### Debug Commands
```bash
# Check RDPGW logs
docker logs rdpgw-container
# Test internal connectivity
curl -H "X-MS-CLIENT-PRINCIPAL-NAME: test@domain.com" \
http://rdpgw-internal/connect
# Verify token generation
curl -v https://rdpgw.yourdomain.com/connect
```
### Azure AD Logs
Monitor these logs for authentication issues:
- **Sign-ins**: User authentication events
- **Conditional Access**: Policy evaluation results
- **Application Proxy**: Connector and application events
## Security Considerations
- **Network Isolation**: Deploy RDPGW in private network
- **Connector Security**: Ensure App Proxy connector is secured
- **Token Validation**: Monitor for token replay attacks
- **Audit Logging**: Enable comprehensive logging for compliance
- **Certificate Management**: Ensure proper TLS certificate chain