Skip to content

SSH with Access for Infrastructure (recommended)

New

Access for Infrastructure uses the same deployment model as WARP-to-Tunnel but unlocks more granular policy options and command logging functionality.

Furthermore, Access for Infrastructure replaces traditional SSH keys with short-lived certificates issued to your users based on the token generated by their Access login. In traditional models, users generate an SSH keypair and administrators grant access to individual SSH servers by deploying their users' public keys to those servers. These SSH keys can remain unchanged on these servers for months or years. Cloudflare Access removes the burden of managing SSH keys, while also improving security by replacing long-lived SSH keys with ephemeral SSH certificates.

1. Connect the server to Cloudflare

  1. Create a Cloudflare Tunnel for your server by following our dashboard setup guide. You can skip the connect an application step and go straight to connecting a network.

  2. In the Private Networks tab for the tunnel, enter the IP address of your server (or a range that includes the server IP). Typically this would be a private IP, but public IPs are also allowed.

2. Set up the client

To connect your devices to Cloudflare:

  1. Deploy the WARP client on your devices in Gateway with WARP mode.
  2. Enable the Gateway proxy for TCP.
  3. Create device enrollment rules to determine which devices can enroll to your Zero Trust organization.

3. Route server IPs through WARP

By default, WARP excludes traffic bound for RFC 1918 space, which are IP addresses typically used in private networks and not reachable from the Internet. In order for WARP to send traffic to your SSH server, you must configure Split Tunnels so that the IP/CIDR of your SSH server routes through WARP.

  1. First, check whether your Split Tunnels mode is set to Exclude or Include mode.
  2. If you are using Include mode, add your SSH server's IP/CIDR range to the list. Your list should also include the domains necessary for Cloudflare Zero Trust functionality.
  3. If you are using Exclude mode:
    1. Delete your SSH server's IP/CIDR range from the list. For example, if your network uses the default AWS range of 172.31.0.0/16, delete 172.16.0.0/12.
    2. Re-add IP/CIDR ranges that are not explicitly used by your SSH server. 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.

By tightening the private IP range included in WARP, you reduce the risk of breaking a user's access to local resources.

4. Add a target

A target represents a single resource in your infrastructure (such as a server, Kubernetes cluster, database, or container) that users will connect to through Cloudflare. Targets are protocol-agnostic, meaning that you do not need to define a new target for each protocol that runs on the server.

To create a new target:

  1. In Zero Trust, go to Networks > Targets.
  2. Select Add a target.
  3. In Target hostname, enter a user-friendly name for the target resource. We recommend using the server hostname, for example production-server. The hostname does not need to be unique and can be reused for multiple targets. Hostnames are used to define the subset of targets included in an infrastructure application and are not used in DNS address resolution.

    Format restrictions

    • Case insensitive
    • Contain no more than 253 characters
    • Contain only alphanumeric characters, -, or . (no spaces allowed)
    • Start and end with an alphanumeric character
  4. In IP addresses, enter the IPv4 and/or IPv6 address of the target resource. The dropdown menu will not populate until you type in the full IP address.
  1. In the dropdown menu, select the IP address and virtual network where the resource is located. This IP address and virtual network pairing is now assigned to this target and cannot be reused in another target by design.
  2. Select Add target.

Next, create an infrastructure application to secure the target.

5. Add an infrastructure application

  1. In Zero Trust, go to Access > Applications.
  2. Select Add an application.
  3. Select Infrastructure.
  4. Enter any name for the application.
  5. In Target criteria, select the target hostname(s) that will represent the application. The application definition will apply to all targets that share the selected hostname, including any targets added in the future.
  6. Enter the Protocol and Port that will be used to connect to the server.
  7. (Optional) If a protocol runs on more than one port, select Add new target criteria and reconfigure the same target hostname and protocol with a different port number.
  8. Select Next.
  9. To secure your targets, configure a policy that defines who can connect and how they can connect:
    1. Enter any name for your policy.

    2. Create a rule that matches the users who are allowed to reach the targets. For more information, refer to Access policies and review the list of infrastructure policy selectors.

    3. In Connection context, configure the following settings:

      • SSH user: Enter the UNIX usernames that users can log in as (for example, root or ec2-user).
      • Allow users to log in as their email alias: (Optional) When selected, users who match your policy definition will be able to access the target using their email address prefix. For example, jdoe@company.com could log in as jdoe.
  10. Select Add application.

The targets in this application are now secured by your infrastructure policies.

6. Configure SSH server

Next, configure your SSH server to trust the Cloudflare SSH CA. This allows Access to authenticate using short-lived certificates instead of traditional SSH keys.

Generate a Cloudflare SSH CA

To generate a Cloudflare SSH CA and get its public key:

  1. Create an API token with the following permissions:

    TypeItemPermission
    AccountAccess: SSH AuditingEdit
  2. If you have not yet generated a Cloudflare SSH CA, make a POST request to the Cloudflare API:

    Terminal window
    curl --request POST \
    "https://api.cloudflare.com/client/v4/accounts/{account_id}/access/gateway_ca" \
    --header "Authorization: Bearer <API_TOKEN>"
  3. If you have already created a Cloudflare SSH CA or receive the error message access.api.error.gateway_ca_already_exists, make a GET request instead:

    Terminal window
    curl https://api.cloudflare.com/client/v4/accounts/{account_id}/access/gateway_ca \
    --header "Authorization: Bearer <API_TOKEN>"
  4. Copy the public_key value returned in the response.

Save the public key

  1. Use the following command to change directories to the SSH configuration directory on the remote target machine:

    Terminal window
    cd /etc/ssh
  2. Once there, you can use the following command to both generate the file and open a text editor to input/paste the public key.

    Terminal window
    vim ca.pub
  3. In the ca.pub file, paste the public key without any modifications.

    ca.pub
    ecdsa-sha2-nistp256 <redacted> open-ssh-ca@cloudflareaccess.org

    The ca.pub file can hold multiple keys, listed one per line. Empty lines and comments starting with # are also allowed.

  4. Save the ca.pub file. In some systems, you may need to use the following command to force the file to save depending on your permissions:

    Terminal window
    :w !sudo tee %
    :q!

Modify your SSHD config

The following procedure makes two changes to the sshd_config file on the remote target machine. The first change requires that you uncomment a field already set in most default configurations; the second change adds a new field.

  1. While staying within the /etc/ssh directory on the remote machine, open the sshd_config file.

    Terminal window
    vim /etc/ssh/sshd_config
  2. Go to the row named PubkeyAuthentication. In most default configurations, the row will appear commented out as follows:

    # PubkeyAuthentication yes
  3. Remove the # symbol to uncomment the line:

    PubkeyAuthentication yes
  4. Add a new line below PubkeyAuthentication:

    TrustedUserCAKeys /etc/ssh/ca.pub
  5. Save the file and quit the editor. You might need to use the following command again to save and exit.

    :w !sudo tee %
    :q!

Restart your SSH server

Once you have modified your SSHD configuration, restart the SSH service on the remote machine.

For older Debian/Ubuntu versions:

Terminal window
sudo service ssh restart

For newer Debian/Ubuntu versions:

Terminal window
sudo systemctl restart ssh

7. Connect as a user

Users can use any SSH client to connect to the target, as long as they are logged into the WARP client on their device. If the target is located within a particular virtual network, ensure that the WARP client is connected to that virtual network before initiating the connection. Users do not need to modify any SSH configs on their device. For example, to SSH from a terminal:

Terminal window
ssh <username>@<target IP>

SSH with Access for Infrastructure also supports scp and rsync commands. At this time, sftp is not supported.

To learn more about user connections, refer to the Access for Infrastructure documentation.

SSH command logs

SSH command logs contain the actual SSH commands that a user ran on the target. These logs are encrypted using a public key provided by the customer and are not visible to Cloudflare.

Enable SSH command logging

To log SSH commands, you will need to generate an HPKE key pair and upload the public key to Cloudflare.

  1. Download the Cloudflare ssh-log-cli utility.

  2. Using the ssh-log-cli utility, generate a public and private key pair.

    Terminal window
    ./ssh-log-cli generate-key-pair -o sshkey
    ls
    README.md ssh-log-cli sshkey sshkey.pub

    This command outputs two files, an sshkey.pub public key and a matching sshkey private key.

  3. In Zero Trust, go to Settings > Network.

  4. In SSH encryption public key, paste the contents of sshkey.pub and select Save.

All proxied SSH commands are immediately encrypted using this public key. The matching private key is required to view logs.

Disable SSH command logging

To turn off SSH command logging, delete your uploaded public key:

  1. In Zero Trust, go to Settings > Network > SSH encryption public key.

  2. Select Remove.

  3. Select Remove key to confirm.

Cloudflare will stop logging SSH commands to your targets, as well as any commands subject to Gateway Audit SSH policies.

View SSH logs

SSH command logs are not visible from the dashboard itself and must be exported and decrypted.

To manually retrieve logs:

  1. In Zero Trust, go to Logs > Access.
  2. Select a user who was allowed to access the target.
  3. Select Download to download the session's command log.
  4. To decrypt the log, follow the instructions in the SSH Logging CLI repository. In the following example, sshkey is the private key that matches the public key uploaded to Cloudflare.

    Terminal window
    ./ssh-log-cli decrypt -i sshlog -k sshkey

    This command outputs a sshlog-decrypted.zip file with the decrypted logs.