At the beginning of 2025, Cloudflare announced a new solution to allow the connection via browser to Windows RDP servers not exposed over the Internet in a totally secure way. Since Windows NT4 RDP has been the way to interact with Windows servers, but it’s always been an unsecure protocol. Exposing it directly over the Internet is historically a huge risk, and the only possible solution is usually to use VPN. But VPN’s are not always easy to setup, they require a client-server component that may be blocked in hardened laptops, and they use tcp/upd ports that may be blocked by firewalls. Using a browser is a much easier solution, and Cloudflare made exactly this.
I found around many articles about this solution, but many of them were missing some fundamental steps in their how-to guides, so as I spent myself half a day to implement it for my home lab, I decided to record all the steps I’ve done.
Step 1: create an account in Cloudflare
That’s a very obvious step, but obviously much needed 🙂
Step 2: configure a public hostname
People may want to jump immediately to the creation of the connection tunnel; this is what I did too, just to realize that its configuration cannot be completed without creating first a dns record for it. Here we have two ways: if we have a domain already hosted and managed by Cloudflare DNS, we can create a new record for the tunnel. If we don’t and we don’t want to pass an entire DNS zone to Cloudflare, we can do a Partial setup. This solution however is only available on the higher paid plans:

I have a free plan, and since I was already planning to leverage Cloudflare DNS services more and more, I decided to move one of my DNS zones to them. Once the zone is managed by Cloudflare, we can create a new hostname for the tunnel, like homelab.domain.com. The cool thing here is that we don’t need to setup any specific IP address for the host, we can use the configuration suggested by Cloudflare. The used ip address comes from a Class E address space, does not need to point to any active destination IP address or hostname; the DNS record just needs to be valid. Cloudflare’s RDP proxy will handle the routing to the correct RDP target.

Step 3: create e Cloudflare tunnel
The technology used by Cloudflare is very clever and easy to understand. On their infrastructure we create a tunnel receiver that listens to incoming connections from a “tunnel client” (I’m using my own terms to explain it); this one is deployed in a Windows server in our private network. In this way, the server is not exposed over the Internet, and it uses an outgoing connection so no holes in the home firewall needs to be made.
The tunnel has to be created in the Zero Trust area of Cloudflare, where all the security services are available. A Free account is enough:

From the left menu we open Zero Trust, we select Networks and then Connectors. In this area, we hit the button Create a tunnel.
When we are asked to select the tunnel type, we choose Cloudflared.
We give a name to the tunnel, like HomeLab.
We choose the platform where we want to install the service:

As you can see, the solution supports a wide range of operating systems. I’m using Windows in my example, but you can connect to different systems.
We download and install the latest version of the cloudflared client, we then open an elevated shell (cmd or powershell) and run the command prompted there. You should copy it using the dedicated button since the entire token is way longer than what’s shown on screen. After completing the wizard and returning the the Tunnels page, we will see the tunnel is already established:

In the configuration section of the tunnel (either during the wizard or by editing it later), we go into the CIDR section and configure the subnet where the RDP server runs, like 172.27.217.0/24 in my case.
Step 4: create a target
As the name says, here we configure the single resource in our infrastructure that we will connect to through Cloudflare.
Again in the Cloudflare console, we go to Access controls > Targets, and we select Add a target.
In the hostname, we give it a friendly name. It doesn’t have to be the real hostname of the machine. It can be jumphost, homeserver, or anything you prefer.
In IP addresses, enter the IP of the RDP server. The dropdown menu will populate once we wrote the address:

If you don’t see the IP appearing, you need to go to Networks > Routes and validate the CIDR you created before, to be sure it contain the subnet you need to access.
Step 5: create an access application
Once networking is configured, we create the application. We do this by going in Access controls > Applications, select Add an application, select Self-hosted.
We give the application a name, decide how long a session token should last (I’ve set mine to 12 hours, hard to use the lab from remote for a longer period of time).
We select add a public hostname (this is the mandatory choice for RDP), in the Domain dropdown list we select the domain we used to create the hostname, and we write that hostname in the dedicated box.

Expand Browser rendering settings and configure it like this:

After setting the application we need to add an access policy. This can be done during the wizard or in a different moment, by accessing the dedicated node of Access controls. We can then attach it to the application. When we create a basic policy, the type has to be allow as we want to let a user enter the portal and then the application. OTP via email is already available by default to any Cloudflare user, so we only need to specify the user we want to use with no additional authentication method:
We then attach this policy to the application.
Still in the Application configuration, we open the tab Login methods, and we can simply accept any method, as OTP (via email) is the one we have already. Obviously, people may want to use more sophisticated methods if available:

One last step, under Experience Settings we flag Show application in App Launcher:

Step 6: publish the application
Ok, we have the tunnel, we have the target, we have the application and we configured it to be visible in the App Launcher. We only need one more thing, that is to configure App Launcher. This is the portal to publish securely self-hosted and other types of application. Under Access Control -> Access Settings we can open its configuration.
In the policies tab we attach again the same policy we created before, that allows our user (identified by our email) to login and see all the published application it has access to. We configure login methods in the same way we did for the Application.
Step 7: let’s access the portal
Time to test if all the configuration we did is correct. To do so, we access the App Lancher; it’s url is always https://<your-team-name>.cloudflareaccess.com. You can find your team name in Cloudflare One under Settings.
We hit the Login button, and in the following box we enter the email address we configured in the access policy. We hit the button Send me a Code and in a few seconds we’ll have the OTP code in our inbox:

We hit the Login button, and in the following box we enter the email address we configured in the access policy. We hit the button Send me a Code and in a few seconds we’ll have the OTP code in our inbox:

Once we login, the App Launcher shows us the button to start the connection to our RDP server:

We click on the button, we are asked to login to the RDP server using its credentials, and in our browser the Windows console appears!
