Configure your Server for SSH through Access

Cloudflare Access controls who can reach your web application, API, or server. To protect a server you need to reach over SSH, you first need to expose that machine to the Cloudflare network using Argo Tunnel.

Argo Tunnel connects your server to Cloudflare without the need to configure firewall ports or ACLs. Configuring a tunnel ensures that Cloudflare evaluates all requests to your machine for security benefits like web application firewall and unmetered DDOS mitigation. The tunnel also applies the identity policies you configure in Cloudflare Access to control who is allowed to reach the server.

In this tutorial, we’ll use a sample domain, “vm.example.com”, to represent a VM deployed behind Cloudflare Access.

Requirements

  • A Cloudflare account
  • The cloudflared daemon
  • An active zone on Cloudflare
  • An active subscription to Argo which you can enable in the Cloudflare dashboard in the traffic tab
  • A client configured to connect via Access

Known Limitations

  • If you have an origin that serves both SSH and HTTP/S requests, you will need to place those at separate domains or subdomains. Otherwise, errors will occur when attempting to reach the machine over different protocols. For example, requests made in a web browser will be routed over SSH and fail.

1. Add a Domain to Cloudflare

Cloudflare Access enforces policy controls at a hostname in your Cloudflare account. To begin, you will need a domain, also referred to as a zone, active in Cloudflare that uses Cloudflare’s authoritative DNS. Follow the instructions here to add a domain to Cloudflare.

You do not need to configure any DNS records at this time. Argo Tunnel will create records for you at a subdomain of the hostname added. For reference, only “example.com” needs to be added to begin.

2. Enable Access and Lock Down the Hostname

To reach a destination behind Cloudflare Access over SSH, you’ll need to assign that destination a subdomain. In this example, the subdomain is “vm.example.com” and represents a VM deployed in our infrastructure. You do not need to configure the subdomain yet, but first you will need to ensure that access to the subdomain is locked down once it is available.

Navigate to the Access tab in the dashboard. To begin, create a policy for the subdomain that prevents any traffic to that hostname from reaching your server. You will configure policies to allow traffic once your setup is complete.

Create at least one policy that controls who can reach that subdomain. For example, you can begin by selecting an Allow policy with an Include rule that covers anyone with your corporate email domain.

3. Install Argo Tunnel

Next, you will need to install Argo Tunnel on your server. Argo Tunnel exposes servers securely to the internet, without opening up firewall ports and configuring ACLs. A lightweight Cloudflare daemon, cloudflared, makes outbound calls to the Cloudflare network for the assigned hostname. Argo Tunnel then ensures that requests route through Cloudflare before reaching the server, allowing administrators to lock down all ingress and control access with the configured identity provider.

Follow the instructions provided here to install Argo Tunnel on the target server.

4. Authenticate the Machine

Argo Tunnel uses your Cloudflare account login to generate a certificate that includes of an origin certificate for your hostname and an API key tied to your user and account.

Use the following command to authenticate the instance of cloudflared on your machine:

$ cloudflared login

The command will generate a link that you can visit in a browser to login with your Cloudflare account. Once authenticated, select the hostname added previously - in this case, “example.com”. You can return to the server; cloudflared will proceed to download the certificate and print a confirmation.

5. Configure SSH through Access

To reach the server over SSH, Cloudflare Access opens a secure connection to proxy SSH traffic through Cloudflare’s network using Argo Tunnel.

On the machine, run the following command to assign the subdomain that will represent the server. Access will default to port 22 for SSH connections.

$ cloudflared tunnel --hostname vm.example.com --url ssh://localhost:22

This command will create a proxy to forward traffic at port 22 from the hostname “vm.example.com”.

For demo or test purposes, you can use the following command to ensure that the cloudflared process running Argo Tunnel continues to function after you leave the session.

$ nohup cloudflared tunnel --hostname vm.example.com --url ssh://localhost:22 &

In production, you will likely want to run this process as a systemd operation so that the Tunnel persists after your session concludes. You can read more guidelines on running cloudflared in production environments here.

6. Disable Network Ingress

cloudflared makes outbound calls to the Cloudflare network and proxies responses to your machine. You can ensure that requests only reach that machine after being authenticate by Cloudflare Access by disabling ingress to the server over any protocol.

With ingress traffic disabled, malicious users could discover the external IP of the server and still be prevented from reaching the destination.

7. Connecting to the server over SSH

Clients connecting to the server using Cloudflare Access need to be configured to do so. You can find details on configuring your client here.