💻 Prerequisites
Before you start, make sure you have:
- A Cloudflare account.
- A domain name added to your Cloudflare account and using Cloudflare’s nameservers.
- SSH server running on your local PC (e.g., OpenSSH on Linux/macOS, or an SSH server on Windows) on the default port 22 (or your custom port).
- On my local/host server firewall is inactive, if you have enable then add rules for tcp(22,3389 and 3000) ports.
- Running Node app locally on 3000 port.
I am gonna do ssh, access remote desktop (RDP) and access localhost:3000 app on my local pc form anywhere on internet (different network).
what is Cloudflare Tunnel?
Cloudflare Tunnel is a secure way to connect your local server or device to the internet through Cloudflare without exposing your IP address or opening ports. It creates an outbound-only encrypted connection from your server to Cloudflare, which then safely routes internet traffic to your server. This improves security by keeping your server hidden behind a firewall and simplifies remote access without complex network setups.
Host Setup – The Local Linux Server
The Host Machine is your local PC that you want to access remotely.
Install Cloudflare Tunnel (cloudflared) on you local/host server
The cloudflared daemon is the service that creates the secure tunnel.
- Download and Install: Use the appropriate package manager for your Linux distribution (e.g., Debian/Ubuntu): On the Host Machine
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb sudo dpkg -i cloudflared-linux-amd64.deb - Verify Path: Confirm the installation path.
which cloudflared
- Expected output: /usr/local/bin/cloudflared
Install and Verify Services (SSH & RDP) on you local/host server
We must ensure the services are installed and listening locally before the tunnel can expose them.
OpenSSH Server
- Install OpenSSH server:
sudo apt update sudo apt install openssh-server -y - Enable and start the SSH service:
sudo systemctl enable --now ssh - Verify SSH service status:
You should see the service as active (running).sudo systemctl restart ssh # OR sudo systemctl restart sshd
XRDP - for remote desktop access
- Install xrdp:
sudo apt update sudo apt install xrdp -y - Add xrdp user to ssl-cert group for certificate access:
sudo adduser xrdp ssl-cert - Enable and start the xrdp service:
sudo systemctl enable --now xrdp - Verify xrdp service status:
You should see it active (running).sudo systemctl status xrdp
This will set up SSH server for remote terminal access on port 22 and xrdp for remote desktop protocol (RDP) access on port 3389 on your linux machine. Both services will be enabled to start automatically on system boot.|
Run the following command to check the service on specifed port.
sudo ss -tuln | grep -E ':22 |:3389 |:3000 '
sudo ss -tuln | grep 22
Create the Named Tunnel and Configuration**
- Authenticate Cloudflared:
This opens a browser. Log in to your Cloudflare account, authorize and save cert.pem.
cloudflared tunnel login - Create a new tunnel. You can name it whatever you like (
remote-ssh):cloudflared tunnel create remote-ssh
This generates your UUID (tunnel ID) (e.g., bbfb870f-c972-…) and JSON credentials inside /home/USERNAME/.cloudflared/.
- Create/Edit
config.yml: Define the hostnames and the services they map to.
Paste your configuration (substituting your UUID):nano ~/.cloudflared/config.yml#tunnel: YOUR_TUNNEL_ID tunnel: bbfb870f-c972-4653-97af-41667bd5cb71 # Your Tunnel UUID #credentials-file: /home/YOUR_USERNAME/.cloudflared/YOUR_TUNNEL_ID.json credentials-file: /home/janak/.cloudflared/bbfb870f-c972-4653-97af-41667bd5cb71.json # Give path acccording to yours ingress: - hostname: ssh.janakkumarshrestha0.com.np # for ssh server service: ssh://localhost:22 - hostname: desktop.janakkumarshrestha0.com.np # For remote desktop service: tcp://localhost:3389 - hostname: localnode.janakkumarshrestha0.com.np # For node app service: http://localhost:3000 #If you have any other services on local host, go on like this... - service: http_status:404
DNS Configuration - Create DNS Records (Cloudflare)
You need to tell Cloudflare to route traffic from your chosen hostname to the tunnel.
-
Using the cloudflared CLI (Recommended) - The easiest way to create the correct DNS record is by running the command from your terminal
cloudflared tunnel route dns remote-ssh ssh.janakkumarshrestha0.com.np # for ssh server
cloudflared tunnel route dns remote-ssh desktop.janakkumarshrestha0.com.np # For remote desktop
cloudflared tunnel route dns remote-ssh localnode.janakkumarshrestha0.com.np # For node app
This command automatically creates the correct CNAME record in your Cloudflare DNS, pointing your all hostname to the tunnel named remote-ssh.
OR
-
Alternatively - Adding dns record manually
Go to your Cloudflare DNS settings and add the CNAME records.
- Add CNAME for SSH:
- Name:
ssh - Target:
[YOUR-TUNNEL-UUID].cfargotunnel.com - Proxy Status: Proxied (Orange Cloud)
- Name:
- Add CNAME for RDP:
- Name:
desktop - Target:
[YOUR-TUNNEL-UUID].cfargotunnel.com - Proxy Status: Proxied (Orange Cloud)
- Name:
- Add CNAME for local node app:
- Name:
localnode - Target:
[YOUR-TUNNEL-UUID].cfargotunnel.com - Proxy Status: Proxied (Orange Cloud)
- Name:
Run the Tunnel
Start the tunnel service so it can connect to the Cloudflare network and begin listening for traffic:
cloudflared tunnel run remote-ssh # Replace with you tunnel name
- Keep this process running, as it maintains the connection between your local PC and the Cloudflare edge.
After you run the cloudflared tunnel the you can immedaiately
Access your node app running on 3000 port is accessible form the internet / any networks
localnode.janakkumarshrestha0.com.np
Client Configuration the SSH Client (Client Machine on different network)
On the PC you’re connecting from (your remote client or there pc on different networks), you need to install cloudflared and configure your SSH client to use it as a proxy.
sudo apt update
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared-linux-amd64.deb
which cloudflared
Edit your SSH configuration file (on Linux/macOS, or a similar configuration on Windows tools like PuTTY).
-
Edit
~/.ssh/config:nano ~/.ssh/config -
Add SSH Configuration:
Host remote-ssh-janak # Give host name you like Hostname ssh.janakkumarshrestha0.com.np # Replace with you actual host name. # The key line that uses cloudflared to proxy the connection ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h User janak # Replace with the username on the local server / host machine. # (Optional) Use a specific port if your server isn't on default port, otherwise, this line isn't necessary # Port 22- The
ProxyCommandtells the SSH client to route the connection throughcloudflared, which handles the tunnel authentication. Replace or match the ouptput formwhich cloudflaredcommand in/usr/local/bin/cloudflaredpath. Note: Make sure the path to cloudflared (/usr/local/bin/cloudflared) is correct for your client machine’s installation. Check using this commandwhich cloudflaredand match.
- The
-
Connect via SSH
You can now connect to your local PC from anywhere on the internet using the simplified SSH command from the client machine:
ssh remote-ssh-janak
# or
ssh -vvv remote-ssh-janak # for more details
- The first time, you may be prompted to authenticate with Cloudflare Access (e.g., a browser login). After that, you will be prompted for your local PC’s SSH password or key.
SSH connect directly using a single command without having to rely on the configuration block in your ~/.ssh/config file.
To connect directly while still using the Cloudflare Tunnel as a proxy, you need to embed the ProxyCommand directly into the ssh command using the -o (Option) flag.
Here is the format you would use:
ssh [email protected] \
-o ProxyCommand="/usr/local/bin/cloudflared access ssh --hostname %h"
- Breakdown of the Command
| Part of Command | Purpose |
|---|---|
ssh janak@... | Specifies the user (janak) and the destination host (ssh.janakkumarshrestha0.com.np). |
-o ProxyCommand="..." | The -o flag overrides or sets an option usually found in ~/.ssh/config. |
"/usr/local/bin/cloudflared access ssh --hostname %h" | This is the command that initiates the tunnel connection. |
%h | This is a placeholder that is replaced by the actual hostname (ssh.janakkumarshrestha0.com.np) at runtime. |
- Security Note
Since you have set up Cloudflare Access and disabled password login, the connection sequence will be:
- The command runs the
ProxyCommand. - Your browser opens to verify your identity (Cloudflare Access).
- Once verified, the SSH client uses your private key (
~/.ssh/id_ed25519or similar) to complete the login without asking for a password.
- Alternative: Simplify the Command
If you want to make this long command easier to type repeatedly without using your ~/.ssh/config file, you could create a shell alias in your shell startup file (~/.bashrc or ~/.zshrc):
# Add this line to ~/.bashrc or ~/.zshrc
alias remote-ssh='ssh [email protected] -o ProxyCommand="/usr/local/bin/cloudflared access ssh --hostname %h"'
After reloading your shell (source ~/.bashrc), you could simply type:
remote-ssh
Stronger Authentication (SSH Keys)
Relying on a password is less secure than using SSH keys. Since your SSH server is now running, you should configure key-based authentication.
On the Client Machine (Your Laptop):
-
Generate a new SSH key pair (if you don’t already have one):
ssh-keygen -t ed25519 -
Copy the public key to your remote server:
ssh-copy-id remote-ssh-janakThis command will prompt for your server password one last time and then install your public key (
~/.ssh/id_ed25519.pub) into the~/.ssh/authorized_keysfile on the remote server.
After this, when you run ssh remote-ssh-janak, you will no longer be asked for a password, as your secure SSH key will handle the final authentication step automatically.
Disabling Password-Based SSH Login
You need to edit the configuration file for the SSH server (sshd) on your host machine.
sudo nano /etc/ssh/sshd_config
- Modify the Authentication Directives
Scroll through the file (or use Ctrl+W to search) and ensure the following two directives are set exactly as shown below. Make sure to uncomment the lines (remove the # symbol) if they are commented out.
| Directive | Value | Purpose |
|---|---|---|
PasswordAuthentication | no | This is the main directive that blocks all password logins. |
PubkeyAuthentication | yes | This ensures SSH key-based login remains active (it’s usually yes by default). |
- Restart the SSH Service
sudo systemctl restart ssh
# OR
sudo systemctl restart sshd
- Confirm Security Settings On your Local PC (the Host/Server):
# Verify password authentication is disabled
grep -E 'PasswordAuthentication|PubkeyAuthentication' /etc/ssh/sshd_config
- Expected Output:
PubkeyAuthentication yes PasswordAuthentication no
Prepare your host Deskop for remote desktop (RDP)
This step fixes the common issue where RDP connects but immediately closes or shows a blank screen on KDE/Plasma environments.
-
Modify the xRDP Startup Script: This tells xRDP exactly which desktop environment to launch.
sudo nano /etc/xrdp/startwm.sh -
Edit the Script: Scroll to the bottom and comment out the two default startup lines, then add the
startplasma-x11command:# test -x /etc/X11/Xsession && exec /etc/X11/Xsession # exec /bin/sh /etc/X11/Xsession # Add these lines for KDE startplasma-x11 -
Create
.xinitrcFile: This ensures the session environment is initialized correctly for your user.nano ~/.xinitrcPaste:
#!/bin/sh exec startplasma-x11 -
Restart xRDP Service: Apply the session changes.
sudo systemctl restart xrdp -
Reconnect
- Ensure the
cloudflared access tcpproxy is running on your client. - Connect your RDP client to
rdp://[email protected]:33389. - Enter your username and password.
This combination of the explicit
startplasma-x11command in bothstartwm.shand the newly created~/.xinitrcis the most reliable way to forcexrdpto launch a functional KDE session. - Ensure the
Run the Cloudflared Client in TCP Mode (Client Machine)
You need to run a separate cloudflared command on the client machine that listens on a local port (e.g., 33389), performs the Cloudflare Access handshake, and forwards all traffic to your tunnel hostname.
-
Open a New Terminal on your Client Machine.
-
Run the RDP Proxy Command: On the Client Machine (Keep this terminal open)
/usr/local/bin/cloudflared access tcp --hostname desktop.janakkumarshrestha0.com.np --url 127.0.0.1:33389access tcp: Tellscloudflaredto act as a TCP proxy client.--hostname: Specifies the remote hostname to connect to (your tunnel endpoint).--url 127.0.0.1:33389: Tellscloudflaredto listen on your local machine at port33389and forward any traffic it receives.
Connect the RDP Client
Once the browser authentication is complete, your local proxy is running!
- Open your RDP Client (e.g., Remmina and KRDC).
- Connect to the local proxy address:
- Host/IP:
127.0.0.1(orlocalhost) - Port:
33389(The local port specified in thecloudflaredcommand)
- Host/IP:
Your RDP client connects locally to 33389, cloudflared forwards the traffic securely through the tunnel, and you should see the RDP login screen for your host machine.
-
On the host machine, you have atleast 2 user one for current login session and other for remote desktop, because same luser cat login in 2 platform. Local user is still logged in, creating a conflict. Log out of your current session on the physical host machine. Do not just lock the screen—log out completely.
-
Enter your login credential: username and password
If you are Windows OS user:
💻 Phase 1: Windows Client Setup
1. Install Cloudflared on Windows
You need the cloudflared client on your Windows machine to handle the secure tunneling and Cloudflare Access authentication.
- Download: Download the latest
cloudflaredexecutable file from Cloudflare Download page - Rename & Place: Rename the downloaded file to just
cloudflared.exeand place it in a simple location, likeC:\Cloudflared\. - Add to Path (Optional but Recommended): Add
C:\Cloudflaredto your Windows System Environment Variables PATH so you can run the command from any terminal (PowerShell or Command Prompt).
🔒 Phase 2: SSH Access (Using PowerShell/CMD)
For SSH, you’ll use the built-in OpenSSH Client in Windows (or PuTTY/Git Bash).
2. Run the SSH Command
Since Windows SSH clients don’t use the simple ~/.ssh/config file in the same way, you must include the ProxyCommand directly in your terminal, or use a tool like Git Bash which supports the Linux-style configuration.
In PowerShell or Command Prompt: Run this command to SSH:
ssh janak@ssh.janakkumarshrestha0.com.np -o ProxyCommand="C:\Cloudflared\cloudflared.exe access ssh --hostname %h"
Connection Flow:
- The command runs, executing the
ProxyCommand. - A browser window opens, prompting you to log in for Cloudflare Access authentication.
- Once authenticated, the terminal prompts you to accept the host key, and then logs you in using your SSH Key (if previously set up).
🖥️ Phase 3: RDP Access (Using Remote Desktop Client)
For RDP, you must use the same local proxy method used on your Linux client, as the RDP client cannot run the authentication command itself.
3. Start the Cloudflared RDP Proxy
You need to run the cloudflared command in a separate, dedicated terminal window on your Windows machine.
-
Open PowerShell/Command Prompt (as a normal user).
-
Run the RDP Proxy Command: Keep this terminal window open for the entire session.
C:\Cloudflared\cloudflared.exe access tcp --hostname desktop.janakkumarshrestha0.com.np --url 127.0.0.1:33389This command will prompt for Cloudflare Access authentication in a browser.
4. Connect with Microsoft Remote Desktop
- Open the Microsoft Remote Desktop Connection (MSTSC) client (or another RDP client like Remmina).
- Connect to the local proxy address:
- Computer/Host:
127.0.0.1:33389
- Computer/Host:
- Once the connection establishes, the RDP client will show the login prompt for your remote Linux host machine.
If you want to Make the Tunnel Permanent/auto start on boot (Host Machine)
Manual Systemd Service Creation
We will create a service file that explicitly tells the operating system to run cloudflared using your user’s configuration file.
1. Stop the Foreground Tunnel (If Running)
Make sure you’ve pressed Ctrl + C in the terminal where the tunnel was running.
2. Create the Service File
You need to create a new file for the service definition.
On the Host Machine:
sudo nano /etc/systemd/system/cloudflared-remote.service
3. Paste the Service Configuration
Paste the following configuration into the file. This file is configured specifically for your setup:
- It uses your username (
janak). - It points directly to your configuration file (
/home/janak/.cloudflared/config.yml). - It uses the correct tunnel name (
remote-ssh).
[Unit]
Description=Cloudflare Tunnel Remote SSH Service
After=network.target
[Service]
# Set the user and group to run the tunnel as
User=janak #Your hostmachine's username
# The main executable. We use 'tunnel run' with the name of your tunnel.
ExecStart=/usr/local/bin/cloudflared tunnel run remote-ssh
# Ensure the service restarts if it fails
Restart=always
# Point the service to your existing config file
Environment="CLOUDFLARED_OPTS=--config /home/janak/.cloudflared/config.yml"
# Give up waiting if start takes too long
TimeoutStopSec=5
[Install]
WantedBy=multi-user.target
Note: Make sure to verify the username janak is correct.
Save the file and exit the editor.
4. Manage the cloudflared-remote Service
Now, tell systemd about the new service file, enable it for boot, and start it.
On the Host Machine:
# Reload the systemd manager configuration
sudo systemctl daemon-reload
# Enable the service to start automatically on boot
sudo systemctl enable cloudflared-remote.service
# Start the tunnel service
sudo systemctl start cloudflared-remote.service
# Stop the tunnel service
sudo systemctl stop cloudflared-remote.service
# Disable this service on startup
sudo systemctl disable cloudflared-remote.service
# Check the status
sudo systemctl status cloudflared-remote.service
You should see “Active: active (running)”. You can now close your host terminal, and the tunnel will remain active.
Apply Zero Trust Access Policies
You must secure both new hostnames in your Cloudflare Zero Trust Dashboard $\to$ Access $\to$ Applications, creating a separate Self-hosted Application for:
ssh.janakkumarshrestha0.com.npdesktop.janakkumarshrestha0.com.nplocalnode.janakkumarshrestha0.com.np
For both, set the Access Policy to Allow only your verified Email Address.