Files
rdpgw/CHANGELOG.md
Bolke de Bruin 7d1b9af858 Drop baked-in TLS cert, run as 1001, refuse known placeholder secrets
The dev container image generated a TLS keypair at build time and
shipped it inside the image, so every pull of the same image tag was
serving the same private key. The entrypoint also reverted to USER 0
to support a dead `createusers.txt` loop and a `chmod u+s` that was a
no-op (set on a binary owned by 1001). Net result was that any RCE
in the gateway landed as root and the wire-trust posture relied on a
shared private key.

Stop generating the cert at build time: the runtime image now carries
openssl and the entrypoint mints an ephemeral self-signed cert at
first start when no cert is mounted at the configured path. Each
container instance gets its own key. Drop USER 0 entirely; the
entrypoint runs as 1001 throughout. Prune the dead createusers loop
and the `chmod u+s`.

Separately, the README and the dev compose files publish a small set
of literal placeholder values for SessionKey, SessionEncryptionKey,
and the various Token*Key fields. Operators copy-paste these into
real deployments. Refuse to start when any of those literals appear
in the corresponding config field.
2026-04-30 19:09:15 +02:00

2.5 KiB

Changelog

All user-visible changes to rdpgw will be documented in this file.

The format is based on Keep a Changelog, and the project adheres to Semantic Versioning.

[Unreleased]

Changed

  • The dev container image no longer ships a baked-in TLS key/cert. The runtime image carries openssl and the entrypoint generates an ephemeral self-signed cert at first start if none is mounted at the configured path; each container instance gets its own key. The entrypoint also runs entirely as UID 1001 (no more USER 0).
  • rdpgw refuses to start when any of Server.SessionKey, Server.SessionEncryptionKey, Security.PAATokenSigningKey, Security.PAATokenEncryptionKey, Security.UserTokenSigningKey, Security.UserTokenEncryptionKey, or Security.QueryTokenSigningKey matches a published placeholder value from README.md / the dev compose files. See UPGRADING.md for the full list.
  • rdpgw-auth now creates its socket with mode 0660 and accepts only connections whose peer UID is on an allow-list (default: the daemon's own UID). Operators running rdpgw and rdpgw-auth as different users must list the gateway's UID via --allow-uid or share a group via --allow-gid. See UPGRADING.md.
  • X-Forwarded-For is now honored only when the request arrives from a Server.TrustedProxies CIDR. The default Server.TrustedProxies is empty, so by default the request's RemoteAddr (host portion) is the source of AttrClientIp. See UPGRADING.md if your deployment relies on a fronting proxy stamping XFF.
  • server.hostselection: any now refuses destinations that resolve to loopback, RFC1918, link-local, IPv6 ULA, unspecified, or multicast addresses, and only forwards to ports in Server.AllowedDestinationPorts (default [3389]). Operators that need the old behavior can opt back in with Server.AllowPrivateDestinations: true and an extended port list. See UPGRADING.md for migration notes. The other host-selection modes (roundrobin, signed, unsigned) already used the operator-curated Server.Hosts list and are unaffected.

Added

  • rdpgw-auth --allow-uid and --allow-gid flags (repeatable).
  • Server.TrustedProxies ([]string, CIDR, default empty).
  • Server.AllowedDestinationPorts ([]int, default [3389]).
  • Server.AllowPrivateDestinations (bool, default false).