Remote Desktop Protocol (RDP) matcher #219
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
The PR title seems to be self-explanatory. With this
rdp
matcher layer4 module allows Caddy to multiplex RDP connections. What is more, itscookie_hash
option allows to matchmstshash
optional cookie value, andcookie_ips
andcookie_ports
options provide formsts
optional cookie value matching (see important caveats in the comments to the matcher code). This way, if Microsoft Terminal Services Client (mstsc.exe) is used, Caddy may also route RDP connections to different servers based on the username, which is truncated to 9 characters to becomemstshash
. In addition, this matcher addscookie_hash
,cookie_ip
,cookie_port
andcorrelation_id
to the replacer, if provided in the first packet. Last but not least, caddyfile support is included.Config examples
Simple RDP multiplexing
Same as above, but route RDP to 2 machines depending on
cookie_hash
, with a fallback mechanismSame as above, but route RDP to 2 machines depending on
custom_info_regexp
, with a fallback mechanismTesting
Tested on my machines having Windows 11 with a native server/client. Moreover, tested on MacOS Sonoma 14.5 with Jump Desktop 8.10.4 and Microsoft Remote Desktop 10.9.6 as clients, and iOS 17.5.1 with Microsoft Remote Desktop 10.5.9 as a client. For express testing you may use pre-compiled docker images vnxme/caddy:layer4-rdp. They have a minimum of the latest Caddy, and layer4 module with RDP matcher.
Note for testers leveraging mstsc.exe as a client and using
cookie_hash
option: this program seems to have a bug related tomstshash
cookie update. When you open it and only fill host:port field (leave username and password empty), it sends a RDP Connection Request without a cookie - it's correct. Next, if you fill both the host:port field and username fields, it takes the first 9 characters of the username you provided asmstshash
cookie value to include into the RDP Connection Request - it's correct again. However, if you cancel connection and change the username, it won't updatemstshash
cookie value, i.e. the RDP Connection Request will include 9 characters of the username you provided before the change - that's where the bug occurs which leads to Caddy misrouting RDP connections. Reopening the client resolves the problem.Note for testers leveraging Apache Guacamole and using
cookie_hash
option: this program ignores any domain name, so it's only username value that's included into RDP CR packet asmstshash
. What's great about this client is that it has a custom load balance info/cookie field, which takes precedence over standard cookie payload. Thus, you can effectively usecustom_info
orcustom_info_regexp
option of this matcher for RDP connections routing.Note for testers using other RDP clients: it's unclear why some clients include usernames as cookie hashes while others don't. It seems this part of RDP is not fully standardised, so each group of developers decide what to do. For example, Microsoft Remote Desktop clients on MacOS and iOS don't send cookie hashes at all. If this matcher doesn't work for you as expected, the best way to debug is to capture the first packet with Wireshark.