Devolutions Gateway
A blazing fast relay server adaptable to different protocols and desired levels of traffic inspection.
Use cargo build --release to build a release version of devolutions-gateway locally.
Configuration
Devolutions Gateway is configured using a JSON document.
The file must be named gateway.json and exist under the following path:
%ProgramData%\Devolutions\Gateway\under Windows,/Library/Application Support/devolutions-gateway/under MacOS, or/etc/devolutions-gateway/under Linux.
This path may be overriden using the DGATEWAY_CONFIG_PATH environment variable.
A default template with minimal options is generated in this location if the file doesn't exist yet.
Currently stable options are:
-
Id: this Gateway's unique ID, -
Hostname: this Gateway's hostname (used when inferring external URLs), -
ProvisionerPublicKeyFile: path to the provisioner public key (used to verify tokens without any specfic restriction), -
SubProvisionerPublicKey: a JSON object describing the sub provisioner public key (may only be used to verify tokens when establishing a session). The schema is:Id: the key ID for this subkey,Value: the binary-to-text-encoded key data,Format: the format used for the key data (SpkiorRsa),Encoding: the binary-to-text encoding used for the key data (Multibase,Base64,Base64Pad,Base64Url,Base64UrlPad),
-
DelegationPrivateKeyFile: path to the delegation private key (used to decypher sensitive data from tokens), -
TlsCertificateFile: path to the certificate to use for TLS, -
TlsPrivateKeyFile: path to the private key to use for TLS, -
Listeners: array of listener URLs. Each element has the following schema:InternalUrl: internal URL for this listener,ExternalUrl: external URL for this listener.
Host segment may be abridged with
*. -
Subscriber: subscriber configuration:Url: HTTP URL where notification messages are to be sent,Token: bearer token to use when making HTTP requests.
Sample Usage
RDP routing
Devolutions Gateway can redirect RDP traffic authorized by a JWT (Json Web Token) both signed (JWS) and encrypted (JWE).
The key used to sign must be known by the Gateway.
This key is provided through the ProvisionerPublicKeyFile option in the configuration file.
The provisioner can then use its private key to sign a JWT and authorize RDP routing.
Similarly, The key used for token decryption is provided through the DelegationPrivateKeyFile option.
The public counterpart of the delegation key must then be used for token encryption.
JWT structure and claims
Devolutions Gateway is expecting a nested JWT.
- A set of claims are signed using JWS (Json Web Signature) into a compact JWT. Use of RSASSA-PKCS-v1_5 using SHA-256 (
RS256) is recommended. - This signed token is then wrapped inside another token using JWE (Json Web Encryption) in compact form as well.
Use of RSAES OAEP using SHA-256 and MGF1 with SHA-256 (
RSA-OAEP-256) and AES GCM using 256-bit key (A256GCM) is recommended.
Required claims for both RDP-TCP and RDP-TLS modes:
dst_hst(String): target RDP hostjet_cm(String): identity connection mode used for Jet association This must be set tofwd.jet_ap(string): application protocol used over Jet transport. This must be set tordp.exp(Integer): a UNIX timestamp for "expiration"nbf(Integer): a UNIX timestamp for "not before"
Required claims for RDP-TLS mode:
-
Proxy credentials (client
↔ jet)prx_usr(String): proxy username,- and
prx_pwd(String): proxy password
-
Target credentials (jet
↔ server)dst_usr: (String): host username,- and
dst_pwd: (String): host password
If any claim required for RDP-TLS is missing RDP routing will start in RDP-TCP mode with no TLS inspection and thus no credentials proxying.
If all the optional claims are provided RDP routing will start in RDP-TLS mode with TLS inspection and credentials proxying (
Token generation utilities
JWT generation should be facilitated by a provisioner (such as Devolutions Server or Devolutions Password Hub).
However, you can easily generate a JWT for testing purposes by using CLI tools provided in /tools folder.
tokengen
A native CLI. No binary provided; you will need a Rust toolchain to build yourself. See Install Rust.
$ cargo build --package tokengen --release
The binary is produced inside a target/release folder.
RDP-TCP example:
$ ./tokengen --provisioner-key /path/to/provisioner/private/key.pem forward --dst-hst 192.168.122.70 --jet-ap rdp
RDP-TLS example:
$ ./tokengen --provisioner-key /path/to/provisioner/private/key.pem --delegation-key /path/to/delegation/public/key.pem rdp-tls --dst-hst 192.168.122.70 --prx-usr proxy_username --prx-pwd proxy_password --dst-usr host_username --dst-pwd host_password
Inject token in RDP connection using MSTSC
-
Open MSTSC
-
Enter a JET address in the "computer" field
-
Press the "Save As..." button under the "Connection settings" panel to save ".RDP" file to you PC
-
Open saved ".RDP" file with a text editor
-
Append string "pcb:s:" to the end of the file (e.g: pcb:s:eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOj...)
-
Save file
-
In MSTSC press "Open..." and select your edited file
-
Done. You can start the connection
Inject token in RDP connection using FreeRdp
Using FreeRDP, token can be provided using /pcb argument with xfreerdp.
(e.g: /pcb:eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOj...)
Troubleshooting
Connection from Microsoft Windows 7/8/8.1/Server 2008/Server 2012 clients
-
For Window 7 and Windows Server 2008: Install latest updates. Make sure to install the update that adds support for TLS 1.1 and TLS 1.2. This is not required for newer Windows editions - they support TLS 1.1 and TLS 1.2 by default.
-
Add following cipher suites to the SSL Cipher Suite order:
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384.
To add cipher suites, use the group policy setting SSL Cipher Suite Order under Computer Configuration > Administrative Templates > Network > SSL Configuration Settings. TLS Cipher Suites in Windows 7.
Redirection to Microsoft Windows 7/8/8.1/Server 2008/Server 2012 server
Unfortunately, Microsoft Windows 7/8/8.1/Server 2008/Server 2012 machines cannot accept connections from rustls client. Support for required cipher suits was not implemented until Windows 10.
Continuous Integration and Delivery
See the dedicated README in the workflows directory.