---
title: Connect with self-managed SSH keys · Cloudflare Zero Trust docs
description: If you want to manage your own SSH keys, you can use Cloudflare
  Tunnel to create a secure, outbound-only connection from your server to
  Cloudflare's global network. This requires running the cloudflared daemon on
  the server (or any other host machine within the private network). Users with
  SSH keys that are trusted by the SSH server can access the server by
  installing the Cloudflare WARP client on their device and enrolling in your
  Zero Trust organization. Remote devices will be able to connect as if they
  were on your private network. By default, all devices enrolled in your
  organization can SSH to the server unless you build policies to allow or block
  specific users.
lastUpdated: 2025-10-14T21:15:19.000Z
chatbotDeprioritize: false
source_url:
  html: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/use-cases/ssh/ssh-warp-to-tunnel/
  md: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/use-cases/ssh/ssh-warp-to-tunnel/index.md
---

If you want to manage your own SSH keys, you can use Cloudflare Tunnel to create a secure, outbound-only connection from your server to Cloudflare's global network. This requires running the `cloudflared` daemon on the server (or any other host machine within the private network). Users with SSH keys that are trusted by the SSH server can access the server by installing the [Cloudflare WARP client](https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/) on their device and enrolling in your Zero Trust organization. Remote devices will be able to connect as if they were on your private network. By default, all devices enrolled in your organization can SSH to the server unless you build policies to allow or block specific users.

Note

If you want to create more granular access policies, allow Cloudflare to manage SSH keys for you, or to obtain command logs, consider using [Access for Infrastructure](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/use-cases/ssh/ssh-infrastructure-access/) instead.

This example walks through how to set up an SSH server on a Google Cloud Platform (GCP) virtual machine (VM), but you can use any machine that supports SSH connections.

## 1. Create an SSH key pair

Before creating your VM instance you will need to create an SSH key pair.

1. Open a terminal and type the following command:

   ```sh
   ssh-keygen -t rsa -f ~/.ssh/gcp_ssh -C <username in GCP>
   ```

2. Enter your passphrase when prompted. It will need to be entered twice.

   Two files will be generated: `gcp_ssh` which contains the private key, and `gcp_ssh.pub` which contains the public key.

3. In the command line, enter:

   ```sh
   cat ~/.ssh/gcp_ssh.pub
   ```

4. Copy the output. This will be used when creating the VM instance in GCP.

## 2. Create a VM instance in GCP

Now that the SSH key pair has been created, you can create a VM instance.

1. In your [Google Cloud Console](https://console.cloud.google.com/), [create a new project](https://developers.google.com/workspace/guides/create-project).
2. Go to **Compute Engine** > **VM instances**.
3. Select **Create instance**.
4. Name your VM instance, for example `ssh-server`.
5. Scroll down to **Advanced options** > **Security** > **Manage Access**.
6. Under **Add manually generated SSH keys**, select **Add item** and paste the public key that you have created.
7. Select **Create**.
8. Once your VM instance is running, open the dropdown next to **SSH** and select *Open in browser window*.

Note

In order to be able to establish an SSH connection, do not enable [OS Login](https://cloud.google.com/compute/docs/oslogin) on the VM instance.

## 3. Connect the server to Cloudflare

1. In [Zero Trust](https://one.dash.cloudflare.com), go to **Networks** > **Tunnels**.

2. [Create a new tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/get-started/create-remote-tunnel/) or edit an existing `cloudflared` tunnel.

1) In the **CIDR** tab for the tunnel, enter the private IP or CIDR address of your server. In GCP, the server IP is the **Internal IP** of the VM instance.

2) (Optional) [Set up Zero Trust policies](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/private-net/cloudflared/#4-recommended-filter-network-traffic-with-gateway) to fine-tune access to your server.

## 4. Set up the client

To connect your devices to Cloudflare:

1. [Deploy the WARP client](https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/deployment/) on your devices in Gateway with WARP mode or [generate a proxy endpoint](https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/agentless/pac-files/) and deploy a PAC file.
2. [Create device enrollment rules](https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/deployment/device-enrollment/) to determine which devices can enroll to your Zero Trust organization.

## 5. Route private network IPs through WARP

By default, WARP excludes traffic bound for [RFC 1918 space](https://datatracker.ietf.org/doc/html/rfc1918), which are IP addresses typically used in private networks and not reachable from the Internet. In order for WARP to send traffic to your private network, you must configure [Split Tunnels](https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/configure-warp/route-traffic/split-tunnels/) so that the IP/CIDR of your private network routes through WARP.

1. First, check whether your [Split Tunnels mode](https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/configure-warp/route-traffic/split-tunnels/#change-split-tunnels-mode) is set to **Exclude** or **Include** mode.

2. Edit your Split Tunnel routes depending on the mode:

   * Exclude IPs and domains

     If you are using **Exclude** mode:

     a. [Delete the route](https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/configure-warp/route-traffic/split-tunnels/#remove-a-route) containing your private network's IP/CIDR range. For example, if your network uses the default AWS range of `172.31.0.0/16`, delete `172.16.0.0/12`.

     b. [Re-add IP/CIDR ranges](https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/configure-warp/route-traffic/split-tunnels/#add-a-route) that are not explicitly used by your private network. For the AWS example above, you would add new entries for `172.16.0.0/13`, `172.24.0.0/14`, `172.28.0.0/15`, and `172.30.0.0/16`. This ensures that only traffic to `172.31.0.0/16` routes through WARP.

     You can use the following calculator to determine which IP addresses to re-add:

     Calculator instructions

     1. In **Base CIDR**, enter the RFC 1918 range that you deleted from Split Tunnels.
     2. In **Excluded CIDRs**, enter the IP/CIDR range used by your private network.
     3. Re-add the calculator results to your Split Tunnel Exclude mode list.

     By tightening the private IP range included in WARP, you reduce the risk of breaking a user's [access to local resources](https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/configure-warp/warp-settings/#allow-users-to-enable-local-network-exclusion).

   * Include IPs and domains

     If you are using **Include** mode:

     1. Add the required [Zero Trust domains](https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/configure-warp/route-traffic/split-tunnels/#cloudflare-zero-trust-domains) or [IP addresses](https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/configure-warp/route-traffic/split-tunnels/#cloudflare-zero-trust-ip-addresses) to your Split Tunnel include list.
     2. [Add a route](https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/configure-warp/route-traffic/split-tunnels/#add-a-route) to include your private network's IP/CIDR range.

## 6. Connect as a user

Once you have set up the application and the user device, the user can now SSH into the machine using its private IP address. If your SSH server requires an SSH key, the key should be included in the command.

```sh
ssh -i ~/.ssh/gcp_ssh <username>@<server IP>
```
