Cloudflare Docs
Cloudflare Zero Trust
Visit Cloudflare Zero Trust on GitHub
Set theme to dark (⇧+D)

SSH with short-lived certificates

Cloudflare Access can secure resources that users connect to over SSH. Cloudflare’s network will enforce Zero Trust rules and prompt users to authenticate with your organization’s identity provider and multifactor options.

Additionally, Access can help your team replace long-lived SSH keys with short-lived certificates. The certificates are generated from the user’s login to your identity provider and will authorize the user to the SSH server.

slc-overview

Replacing long-lived API keys with short-lived certificates offers the following advantages:

  • API keys are not left lingering on machines
  • Revocation at the identity provider extends to SSH key
  • The keys used to authenticate are automatically rotating
  • Users do not have to add SSH keys to their onboarding; instead, only the identity provider is required

This tutorial covers how to:

  • Connect a host to Cloudflare’s network that users can reach over SSH
  • Build Zero Trust rules to protect that resource
  • Replace long-lived SSH keys with short-lived certificates to authenticate users to the host

Time to complete:

45 minutes

​​ Before you start

  1. Add a website to Cloudflare
  2. Change your domain nameservers to Cloudflare

​​ Build a Zero Trust policy

First, build a Zero Trust policy to enforce rules whenever any user attempts to connect to the resources being protected. Building the Zero Trust policy first ensures that resources are not connected to Cloudflare for a period of time before a Zero Trust policy can be added.

In Zero Trust, open the Applications page of the Access section. Select the “Self-hosted” option.

Name the application using a subdomain of a domain active in your Cloudflare account. This will be the host that users configure in their SSH configuration file to reach the protected resources.

Name App

Build a policy to determine who will be able to reach these resources. You can use Access Groups to build reuseable policies. In this case, the group specified includes rules that enforce Okta group membership and country location.

Rules

​​ Connect a host to Cloudflare

You can now connect the host to Cloudflare with Cloudflare Tunnel. Cloudflare Tunnel, powered by its cloudflared daemon, will create an outbound-only connection from your environment and send SSH connections from users to protected resources once authorized.

First, install and authenticate an instance of cloudflared in a location that can address the resources you are connecting to Cloudflare.

Next, create a new Tunnel with the following command. You can replace ssh-pool with any name.

$ cloudflared tunnel create ssh-pool

cloudflared will create the Tunnel and generate a UUID and corresponding credentials file.

You can now configure your Tunnel. The example configuration file below uses the UUID value of the Tunnel, adds the path to the credentials file, and sets an optional logging location.

In the ingress section, input the hostname of the application created in Zero Trust. Placing the service in bastion mode will allow any connections that reach cloudflared to connect onward to resources available to cloudflared, similar to a jump host.

Bastion

tunnel: 79a60ee2-9a98-4f5f-96c7-76c88b2075be
credentials-file: /root/.cloudflared/79a60ee2-9a98-4f5f-96c7-76c88b2075be.json
logDirectory: /var/log/cloudflared
http2: true
ingress:
- hostname: ssh-bastion.widgetcorp.tech
service: bastion
- service: http_status:404

You can now run the Tunnel with the following command.

$ cloudflared tunnel run ssh-pool

​​ Configure a DNS record and route to the server

You can now configure a DNS record for the Tunnel you have created. Navigate to the Cloudflare dashboard and select the domain you configured in your Access policy and in the hostname value of your configuration file.

Open the DNS page and click Add record. Select CNAME for Type and in the Target field input the UUID value of your Tunnel followed by .cfargotunnel.com. In this example, that value is:

79a60ee2-9a98-4f5f-96c7-76c88b2075be.cfargotunnel.com

Add DNS

Users will now be able to authenticate through Cloudflare Access and connect over SSH to these resources once they follow the configuration steps below.

​​ Deploy short-lived certificates

You can extend the Zero Trust security model by replacing long-lived SSH keys with short-lived certificates provided by Cloudflare Access. To do so, navigate to Zero Trust and open the Service Authentication page. Select the SSH tab.

In the Application dropdown, select the application created previously and click Generate certificate. Cloudflare Access will display the public key and an audience tag for the generated certificate.

Gen Cert Output

You must now configure your SSH host to rely on the generated certificate. In your sshd configuration, set the following values:

PubkeyAuthentication yes
TrustedUserCAKeys /etc/ssh/ca.pub

Save the public key value as a ca.pub file in the path specified in the TrustedUserCAKeys setting. Restart the server.

​​ Configure the SSH client

Users can now modify their SSH configuration files to connect over SSH. This is a one-time step.

Instruct users to download cloudflared and run the following command, replacing the hostname in this example with the one that you created.

$ cloudflared access ssh-config --hostname ssh-bastion.widgetcorp.tech --short-lived-cert

cloudflared will generate the required lines to append to the SSH configuration file, similar to the example output below.

Match host ssh-bastion.widgetcorp.tech exec "/usr/local/bin/cloudflared access ssh-gen --hostname %h"
HostName ssh-bastion.widgetcorp.tech
ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h
IdentityFile ~/.cloudflared/vm.example.com-cf_key
CertificateFile ~/.cloudflared/vm.example.com-cf_key-cert.pub

When users authenticate through Cloudflare Access, Cloudflare will generate a certificate for the individual using the username from the identity provider (stripped of the email domain). That certificate will then be presented to the SSH server.