RDP Gateway TLS Certificate Renewal Without Breaking Remote Access

RD Gateway certificates are one of those dependencies that nobody looks at for two years and then everyone looks at at 9am on a Monday, usually while users are failing to connect in. The failure modes are consistent: the certificate expired, the binding was updated on one server and not on the other, the new certificate was issued by a CA the clients do not trust, or the gateway is presenting a certificate for the wrong name. All four are preventable with a rollover procedure that is rehearsed rather than improvised.

This article covers the mechanics of certificate templates, the binding order between IIS and RD Gateway, how client trust propagates, and a safe sequence for swapping the certificate without a support queue. It assumes you already have a working RD Gateway deployment and are renewing, not building one from scratch.

Know exactly which certificate the gateway presents

RD Gateway uses a certificate bound through its own management console or through the RDGATEWAY WMI/RPC interfaces, and the certificate is presented on the HTTPS listener that clients hit for the RDP-over-HTTPS path. In many deployments IIS is also installed on the same server for other purposes, which is where confusion starts: IIS has its own binding store (the SSLCert hash under the HTTP.sys configuration), and RD Gateway has its own certificate setting. These are related but not identical, and updating one does not always update the other.

Before changing anything, establish the current truth. On the gateway, list what HTTP.sys is actually bound to per IP and port, and list what is in the machine’s Personal store. Check the subject alternative names on the certificate that clients are receiving, using a client-side connection, not the server-side store — the server may hold several certificates and present only one.

netsh http show sslcert
Get-ChildItem Cert:\LocalMachine\My |
  Select Subject,NotBefore,NotAfter,Thumbprint,
    @{n='SAN';e={($_.Extensions | Where-Object {$_.Oid.FriendlyName -like '*Alternative*'}).Format($false)}}
Get-NetTCPConnection -LocalPort 443 | Select LocalAddress,State,OwningProcess

The SAN list is the part that breaks. If clients connect to rdg.contoso.com and the certificate only carries the NetBIOS name of the server, it will fail validation on clients that do not have the internal name in their DNS suffix search — and it will work in testing where the hosts file has an entry. Always include the externally published name, plus any internal name the clients use, plus the server FQDN.

Use a template that produces the right certificate

If you are issuing from an internal CA, use a template rather than requesting a certificate ad hoc. The template should request the subject from Active Directory (so the FQDN is populated automatically), include SANs for every name clients use, and — critically — allow the private key to be exported only if you have a reason and a protected store for it. For a gateway that terminates TLS, non-exportable keys with the certificate enrolled directly on the gateway are the simpler and safer default.

For public clients, use a certificate from a publicly trusted CA for the external name, and keep that certificate on the gateway rather than behind an internal CA that external devices will not trust. Mixing the two — a public name served by an internal certificate — is the most common reason “it works for domain machines and fails for everyone else.” If you are choosing hosting for the gateway, our notes on running a Windows VPS as an RD Gateway cover the network requirements.

Binding order: HTTP.sys first, then RD Gateway

The sequence that avoids an outage is to make the new certificate available to everything that can present it before you take the old one away. Do not remove the old certificate from the store, and do not let it expire mid-change. Import the new one, verify its thumbprint and that the private key is present and readable by the account the service runs under, then update the HTTP.sys binding, then the RD Gateway setting.

When rebinding HTTP.sys, remember that netsh http update sslcert preserves the existing session configuration while changing the certificate, whereas deleting and re-adding the binding can reset ClientCertificateNegotiation and other flags. If you must delete and re-add, capture the current output of show sslcert first and recreate the binding with the same parameters, because a silently reset negotiation setting will break certificate-based client authentication in a way that looks like a trust failure.

# Update the existing HTTP.sys binding in place
$new = (Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -like '*rdg.contoso.com*'}).Thumbprint
netsh http update sslcert hostnameport=rdg.contoso.com:443 certhash=$new appid="{4dc3e181-e14b-4a21-b022-59fc669b0914}" certstorename=MY

Then, in the RD Gateway console, set the certificate explicitly to the new one. Confirm both surfaces agree afterwards: the HTTP.sys binding and the gateway’s own setting should reference the same thumbprint. A mismatch produces intermittent behaviour that depends on which path a client takes, and it is very hard to diagnose from a user’s “sometimes it fails” report.

Client trust propagation

For publicly trusted certificates, trust “propagation” is mostly about caches: clients cache the certificate chain, and some clients and proxies cache the TLS session or the certificate itself. Expect a small percentage of clients to hold a stale chain after the swap; the fix is to reconnect after clearing the cached credential or waiting out the session lifetime. Document it so the service desk does not treat it as an incident.

For internally issued certificates, the root must be in the client’s Trusted Root store and, where the client validates revocation, the CRL or OCSP endpoint must be reachable from wherever the client is — including from outside the corporate network for remote users. This is the detail that turns a renewal into an outage: a CRL distribution point on an internal HTTP server that remote clients cannot reach. Check it with a client on the public internet, not from a domain-joined desktop.

The safe rollover sequence

Sequence matters more than any individual step. The pattern that reliably works is: overlap, verify, switch, observe, retire. Overlap means both certificates are valid and present at once. Verify means you check the new certificate from a real client before anyone depends on it. Switch means you change the binding and the gateway setting in a single change, with a rollback that is one command away. Observe means you watch connection success for a defined window. Retire means you remove the old certificate only after that window passes quietly.

  • Stage the new certificate with a validity window that overlaps the old one by at least a week.
  • Verify SANs, key usage and chain from a client outside the network.
  • Update HTTP.sys binding and RD Gateway setting in the same window.
  • Test: gateway connection, published resource launch, and at least one client from a remote, non-domain-joined device.
  • Keep the old certificate for the rollback; remove it only after the observation window.

Set a calendar reminder at roughly two-thirds of the new certificate’s lifetime, not at expiry. A renewal you do with a month of headroom is a routine change; the same renewal done a day before expiry is an emergency with no room to roll back. If the gateway is part of a farm, do one node at a time and confirm the load balancer is draining correctly before moving on. And if the certificate is used by more than RD Gateway — IIS sites, RDS web access, a reverse proxy — inventory those bindings now, because finding the fourth place it was pinned during an outage is the classic version of this task. Our Windows Server operations guides cover the surrounding deployment patterns.

What to monitor so you never do this under pressure again

Two monitors remove almost all of the surprise. The first is a certificate inventory that reports days-to-expiry for every certificate in the machine store across your servers, with alerts at 30 and 14 days. The second is an external TLS check against the published gateway name that fails if the certificate does not match the expected name or chain — this catches the case where someone “fixed” the binding and broke the name on a Friday.

Both are simple to build and neither requires a commercial product. What they require is that you write them down and that the alert reaches someone who can act on it. A renewal process that depends on a person remembering is not a process; it is a hope with a date attached.

Leave a Comment