Setting
A small business (too small to justify a Terminal Services Gateway) wants certain users to be able to access their Windows 10 desktops from home.
I have had good luck with Windows Remote Desktop for this purpose, however best practice suggests to not expose the RDP port directly. It is recommended to secure RDP over a VPN, however in the past I have typically setup an SSH tunnel for this purpose, since I was more familiar with that.
I will assume that the client has some computer which can run an SSH server, and will refer to it as SSH_SERVER
. In my case, there is usually a Linux or BSD computer already on-premise, either as a file server or acting as the firewall (eg. FreeNAS, pfSense), if not I typically drop in a rebuilt PC specifically to handle this job.
SSH Port-Forwarding Version
In this section I include the details of how I set up the SSH port-forwarding for a client who needs Windows Remote Desktop access.
- Setup key-only authentication for SSH on
SSH_SERVER
and open the firewall to expose this on some non-standard port,<EXT_SSH_PORT>
. Note: this is the only external port I ever open, all communication to the network is done via port-forwarding over SSH. - For each client that wants to connect remotely, I generate a user on
SSH_SERVER
with shell set to/bin/false
. - Add SSH restrictions allowing the user to port-forward only for the port and device they want to connect to. For example, I add the following to the
/etc/sshd_conf
file:
Match User <USERNAME>
AllowAgentForwarding no
PermitOpen <USER'S_WINDOWS_DESKTOP_IP>:3389
ForceCommand echo 'This account is restricted.'
(more in-depth discussion here).
- For each device that the user wants to connect with, I generate a key pair which is encrypted with a password which I provide them. I then (a) add the public key to the user's
~/.ssh/authorized_keys
file and (b) securely transfer the private key to the user's device. - I create some way of easily setting up the SSH tunnel, either with a simple script which just runs
ssh -L 10000:<USER'S_WINDOWS_DESKTOP_IP>:3389 <OFFICE_EXTERNAL_IP> -p <EXT_SSH_PORT>
or using helper software (eg. for Mac OS, for Windows). - I add a shortcut for an RDP session to
localhost:10000
.
This method has worked well enough, but I always felt it was not "professional" enough, and that someday I should convert these SSH tunnels to VPNs.
VPN Limitations
I was exploring this with L2TP/IPSEC (on a UniFi Dream Machine, although I think the limitations here are not specific to the router) and immediately ran into some limitations:
- The office network must have a different IP subnet than the client subnet. This would be a minor annoyance, but suppose I could do this. On the other hand, I find it rather unsatisfying that you are essentially just hoping that you will pick a subnet which the client will never happen to be on - what if they are visiting some other company and using their wifi, and you just so happened to pick the same subnet as the IT vendor from there?
- Not clear how to restrict communication to a single port for a single PC, per user. I know I can set it up so that VPN users get placed in a separate VLAN and then add firewall rules which limit connections from that VLAN to port 3389 on specific RDP desktops, but that doesn't stop USER_A from trying to connect to USER_B's desktop. If I'm also opening ports other than RDP for some reason, then all VPN users would have access to these ports as well, unless I put each user in their own VLAN, which seems like additional administrative overhead for a feature I basically already have "for free" with SSH.
- No clear per-device security. With the SSH approach I mentioned above, if USER_A has their laptop stolen there's no real concern. For one thing, the private key is encrypted, so unless the laptop was stolen while the user was actively connected they should not be able to access the office network. Furthermore, for added security, I can just remove the key associated with the stolen laptop from
~/.ssh/authorized_keys
, and all the other devices the client owns (eg. a personal desktop) will continue to work with no additional configuration.
TL;DR: Why would someone prefer to use a VPN over SSH port forwarding?
It seems like the only case where a VPN is preferable is when you want all communication going over the office network and you have some level of awareness/control over the remote network. (Site-to-site VPNs fall under this category.)
Am I missing something here? Do VPNs offer more performance and/or security than SSH port forwarding?