Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
R

rdpgw

> 编程语言
Open source

Remote Desktop Gateway in Go for deploying on Linux/BSD/Kubernetes

1.1K stars0 likes1 views
WebsiteGitHub

About

Remote Desktop Gateway in Go for deploying on Linux/BSD/Kubernetes

GO Remote Desktop Gateway

:star: Star us on GitHub — it helps!

RDPGW is an implementation of the Remote Desktop Gateway protocol. This allows you to connect with the official Microsoft clients to remote desktops over HTTPS. These desktops could be, for example, XRDP desktops running in containers on Kubernetes.

AIM

RDPGW aims to provide a full open source replacement for MS Remote Desktop Gateway, including access policies.

Security requirements

Several security requirements are stipulated by the client that is connecting to it and some are enforced by the gateway. The client requires that the server's TLS certificate is valid and that it is signed by a trusted authority. In addition, the common name in the certificate needs to match the DNS hostname of the gateway. If these requirements are not met the client will refuse to connect.

The gateway has several security phases. In the authentication phase the client's credentials are verified. Depending the authentication mechanism used, the client's credentials are verified against an OpenID Connect provider, Kerberos, a local PAM service, a local database, or extracted from HTTP headers provided by upstream proxy services.

If OpenID Connect is used the user will need to connect to a webpage provided by the gateway to authenticate, which in turn will redirect the user to the OpenID Connect provider. If the authentication is successful the browser will download a RDP file with temporary credentials that allow the user to connect to the gateway by using a remote desktop client.

If Kerberos is used the client will need to have a valid ticket granting ticket (TGT). The gateway will proxy the TGT request to the KDC. Therefore, the gateway needs to be able to connect to the KDC and a krb5.conf file needs to be provided. The proxy works without the need for an RDP file and thus the client can connect directly to the gateway.

If local authentication is used the client will need to provide a username and password that is verified against PAM. This requires, to ensure privilege separation, that rdpgw-auth is also running and a valid PAM configuration is provided per typical configuration.

If NTLM authentication is used, the allowed user credentials for the gateway should be configured in the configuration file of rdpgw-auth.

Finally, RDP hosts that the client wants to connect to are verified against what was provided by / allowed by the server. Next to that the client's ip address needs to match the one it obtained the gateway token with if using OpenID Connect. Due to proxies and NAT this is not always possible and thus can be disabled. However, this is a security risk.

Configuration

The configuration is done through a YAML file. The configuration file is read from rdpgw.yaml by default. At the bottom of this README is an example configuration file. In these sections you will find the most important settings.

Authentication

RDPGW wants to be secure when you set it up from the start. It supports several authentication mechanisms such as OpenID Connect, Kerberos, PAM, NTLM, and header-based authentication for proxy integration.

Technically, cookies are encrypted and signed on the client side relying on Gorilla Sessions. PAA tokens (gateway access tokens) are generated and signed according to the JWT spec by using jwt-go signed with a 256 bit HMAC.

Multi Factor Authentication (MFA)

RDPGW provides multi-factor authentication out of the box with OpenID Connect integration. Thus you can integrate your remote desktops with Keycloak, Okta, Google, Azure, Apple or Facebook if you want.

Mixing authentication mechanisms

It is technically possible to mix authentication mechanisms. Currently, you can mix local with Kerberos or NTLM. If you enable OpenID Connect it is not possible to mix it with local or Kerberos at the moment.

OpenID Connect

For detailed OpenID Connect setup with providers like Keycloak, Azure AD, Google, and others, see the OpenID Connect Authentication Documentation.

Kerberos

For detailed Kerberos setup including keytab generation, DNS requirements, and KDC proxy configuration, see the Kerberos Authentication Documentation.

PAM/Local Authentication

For detailed PAM setup including LDAP integration, container deployment, and compatible clients, see the PAM Authentication Documentation.

NTLM Authentication

For detailed NTLM setup including user management, security considerations, and deployment options, see the NTLM Authentication Documentation.

Header Authentication (Proxy Integration)

RDPGW supports header-based authentication for integration with reverse proxy services (Azure App Proxy, Google IAP, AWS ALB, etc.) that handle authentication upstream and pass user identity via HTTP headers.

For detailed configuration and examples, see the Header Authentication Documentation.

TLS

The gateway requires a valid TLS certificate. This means a certificate that is signed by a valid CA that is in the store of your clients. If this is not the case particularly Windows clients will fail to connect. You can either provide a certificate and key file or let the gateway obtain a certificate from letsencrypt. If you want to use letsencrypt make sure that the host is reachable on port 80 from the letsencrypt servers.

For letsencrypt:

yaml
Tls: auto

for your own certificate:

yaml
Tls: enable
CertFile: server.pem 
KeyFile: key.pem

NOTE: You can disable TLS on the gateway, but you will then need to make sure a proxy is run in front of it that does TLS termination.

Example configuration file for Open ID Connect

…

How to build & install

NOTE: a docker image is available on docker hub, which removes the need for building and installing go.

Ensure that you have make (comes with standard build tools, like build-essential on Debian), go (version 1.19 or above), and development files for PAM (libpam0g-dev on Debian) installed.

Then clone the repo and issues the following.

bash
cd rdpgw
make
make install

Testing locally

A convenience docker-compose allows you to test the RDPGW locally. It uses Keycloak and xrdp and exposes it services on port 9443. You will need to allow your browser to connect to localhost with and self signed security certificate. For chrome set chrome://flags/#allow-insecure-localhost. The username to login to both Keycloak and xrdp is admin as is the password.

NOTE: The redirecting relies on DNS. Make sure to add 127.0.0.1 keycloak to your /etc/hosts file to ensure that the redirect works.

NOTE: The local testing environment uses a self signed certificate. This works for MAC clients, but not for Windows. If you want to test it on Windows you will need to provide a valid certificate.

bash
# with open id
cd dev/docker
docker-compose -f docker-compose.yml up

# or for arm64 with open id
docker-compose -f docker-compose-arm64.yml up

# or for local or pam
docker-compose -f docker-compose-local.yml up

You can then connect to the gateway at https://localhost:9443/connect for the OpenID connect flavors which will start the authentication flow. Or you can connect directly with the gateway set and the host set to xrdp if using the local flavor. You can login with 'admin/admin'. The RDP file will download and you can open it with a remote desktop client. Also for logging in 'admin/admin' will work.

Use

Point your browser to https://your-gateway/connect. After authentication and RDP file will download to your desktop. This file can be opened by one of the remote desktop clients and it will try to connect to the gateway and desktop host behind it.

Overriding RDP options from the URL

The /connect endpoint can apply caller-supplied RDP setting overrides from URL query parameters when (and only when) the operator explicitly opts in. This lets users vary settings such as multi-monitor, audio mode or clipboard redirection without maintaining separate RDP templates.

The query parameter name is the underlying RDP key with whitespace removed and lowercased. For example:

RDP key (in the file) Query parameter
use multimon usemultimon
audiomode audiomode
redirectclipboard redirectclipboard
screen mode id screenmodeid

Values are validated against the field type: booleans accept 0/1 or true/false, integers must parse as base-10 numbers, strings are taken verbatim. Unknown query parameters are ignored so the existing host, etc. continue to work.

To enable, list the keys you want to expose under client.rdpoverridablekeys in your YAML configuration (or via the RDPGW_CLIENT__RDPOVERRIDABLEKEYS environment variable as a space-separated list):

yaml
client:
  rdpoverridablekeys:
    - use multimon
    - audiomode

With the snippet above, https://your-gateway/connect?usemultimon=1 adds use multimon:i:1 to the generated RDP file. Keys that are not on the allow-list are rejected with 400 Bad Request. Authoritative settings controlled by the gateway (gateway address, access token, full address, username) always win over URL parameters even if an operator adds those keys to the allow-list — but adding sensitive keys is still discouraged.

Integration

The gateway exposes an endpoint for the verification of user tokens at https://yourserver/tokeninfo . The query parameter is 'access_token' so you can just do a GET to https://yourserver/tokeninfo?access_token= . It will return 200 OK with the decrypted token.

In this way you can integrate, for example, it with pam-jwt.

Client Caveats

The several clients that Microsoft provides come with their own caveats. The most important one is that the default client on Windows mstsc does not support basic authentication. This means you need to use either OpenID Connect, Kerberos or ntlm authentication.

In addition to that, mstsc, when configuring a gateway directly in the client requires you to either:

  • "save the credentials" for the gateway
  • or specify a (random) domain name in the username field (e.g. .\\username) when prompted for the gateway credentials,

otherwise the client will not connect at all (it won't send any packages to the gateway) and it will keep on asking for new credentials.

Finally, mstsc requires a valid certificate on the gateway.

Additionally, mstsc is more restrictive about SSL cipher suites compared to other RDP clients. When using a reverse proxy like nginx for TLS termination, you may need to configure specific cipher suites that mstsc supports. A working configuration for nginx ssl_ciphers is:

ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256

mstsc also requires server names rather than IP addresses for connections, despite Microsoft's documentation suggesting otherwise. When configuring hosts in the rdpgw configuration, ensure you use hostnames.

Furthermore, the mstsc client sends the hostname including the port number when establishing connections. To ensure proper host verification, configure your hosts in the rdpgw configuration file with the port numbers included (e.g., myserver:3389 even for the default RDP port 3389).

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

Gogatewaygolang-applicationrdprdp-gateway

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言