mirror of
https://github.com/bolkedebruin/rdpgw.git
synced 2026-05-16 21:29:59 +00:00
EnrichContext used to copy the first X-Forwarded-For entry into the request identity unconditionally. The resulting AttrClientIp drives client-IP comparisons later in the gateway-access flow, and a direct caller could set XFF to anything they liked. Add a small package-level allow-list: * InitTrustedProxies(cidrs) parses operator-supplied CIDRs once at startup. A bad CIDR is fatal, an empty list disables XFF entirely. * EnrichContext takes the client IP from r.RemoteAddr (host portion) and only swaps in the first X-Forwarded-For entry when r.RemoteAddr itself sits in a trusted-proxy CIDR. AttrProxies is set from the remaining XFF entries on the same condition. Wire Server.TrustedProxies through configuration.go to web.
74 lines
2.5 KiB
Markdown
74 lines
2.5 KiB
Markdown
# Upgrading
|
|
|
|
## Unreleased
|
|
|
|
### `X-Forwarded-For` is no longer trusted by default
|
|
|
|
Previously rdpgw read the first `X-Forwarded-For` entry into the
|
|
request identity unconditionally. The resulting client IP attribute is
|
|
later compared against the value embedded in the gateway access
|
|
cookie, so any caller reaching rdpgw directly could set
|
|
`X-Forwarded-For` to any value and steer that binding.
|
|
|
|
After upgrading, `X-Forwarded-For` is honored only when the request
|
|
arrives from a `Server.TrustedProxies` CIDR. Otherwise the client IP
|
|
comes from `r.RemoteAddr`. The default `Server.TrustedProxies` is
|
|
empty, so by default `X-Forwarded-For` is ignored entirely.
|
|
|
|
If your deployment fronts rdpgw with a reverse proxy or load balancer
|
|
on a known subnet, list it:
|
|
|
|
```yaml
|
|
Server:
|
|
TrustedProxies:
|
|
- 10.0.0.0/8 # the proxy's egress subnet
|
|
```
|
|
|
|
If no proxy fronts rdpgw, leave `TrustedProxies` empty -- the
|
|
request's `RemoteAddr` is the right source for client identity in
|
|
that case.
|
|
|
|
### `hostselection: any` now refuses non-routable destinations and non-RDP ports by default
|
|
|
|
Previously, when `server.hostselection: any` was set, rdpgw forwarded
|
|
to whatever `?host=` value the request carried with no check on the
|
|
target. The gateway would happily relay TCP traffic to loopback,
|
|
RFC1918, link-local, or arbitrary high-numbered ports on public hosts.
|
|
|
|
After upgrading, `any` mode rejects any destination that resolves to a
|
|
loopback / RFC1918 / link-local / IPv6 ULA / unspecified / multicast
|
|
address, and any port that is not in `AllowedDestinationPorts`. The
|
|
default port allow-list is `[3389]`.
|
|
|
|
If your deployment legitimately reaches private destinations or extra
|
|
ports through `any` mode, opt back in:
|
|
|
|
```yaml
|
|
Server:
|
|
HostSelection: any
|
|
AllowedDestinationPorts:
|
|
- 3389
|
|
- 5985 # add what you actually need
|
|
AllowPrivateDestinations: true
|
|
```
|
|
|
|
The other host-selection modes (`roundrobin`, `signed`, `unsigned`)
|
|
already use the operator-curated `Server.Hosts` allow-list and are
|
|
unaffected by this change.
|
|
|
|
# Upgrading from 1.X to 2.0
|
|
|
|
In 2.0 the options for configuring client side RDP settings have been removed in favor of template file.
|
|
The template file is a RDP file that is used as a template for the connection. The template file is parsed
|
|
and a few settings are replaced to ensure the client can connect to the server and the correct domain is used.
|
|
|
|
The format of the template file is as follows:
|
|
|
|
```
|
|
# <setting>:<type i or s>:<value>
|
|
domain:s:testdomain
|
|
connection type:i:2
|
|
```
|
|
|
|
The filename is set under `client > defaults`.
|