SSH with Access for Infrastructure (recommended)
NewAccess 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.
-
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.
-
In the Private Networks tab for the tunnel, enter the private IP address of your server (or a range that includes the server IP).
To connect your devices to Cloudflare:
- Deploy the WARP client on your devices in Gateway with WARP mode.
- Enable the Gateway proxy for TCP.
- Create device enrollment rules to determine which devices can enroll to your Zero Trust organization.
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 private network, you must configure Split Tunnels so that the IP/CIDR of your private network routes through WARP.
-
First, check whether your Split Tunnels mode is set to Exclude or Include mode.
-
If you are using Include mode, add your network’s IP/CIDR range to the list. Your list should also include the domains necessary for Cloudflare Zero Trust functionality.
-
If you are using Exclude mode:
- Delete your network’s IP/CIDR range from the list. For example, if your network uses the default AWS range of
172.31.0.0/16
, delete172.16.0.0/12
. - Re-add IP/CDIR ranges 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
, and172.30.0.0/16
. This ensures that only traffic to172.31.0.0/16
routes through WARP.
- Delete your network’s IP/CIDR range from the list. For example, if your network uses the default AWS range of
By tightening the private IP range included in WARP, you reduce the risk of breaking a user’s access to local resources.
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:
- In Zero Trust ↗, go to Networks > Targets.
- Select Add a target.
- 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
- In IP addresses, enter the private IPv4 and/or IPv6 address of the target resource. If the IP address overlaps across multiple private networks, select the 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.
- Select Add target.
-
Create an API token with the following permissions:
Type Item Permission Account Zero Trust Edit -
Make a
POST
request to the Infrastructure Access Targets endpoint:
-
Add the following permission to your
cloudflare_api_token
↗:Teams Write
-
Configure the
cloudflare_zero_trust_infrastructure_access_target
↗ resource:
Next, create an infrastructure application to secure the target.
- In Zero Trust ↗, go to Access > Applications.
- Select Add an application.
- Select Infrastructure.
- Enter any name for the application.
- 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.
- Enter the Protocol and Port that will be used to connect to the server.
- (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.
- Select Next.
- To secure your targets, configure a policy that defines who can connect and how they can connect:
- Enter any name for your policy.
- 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.
- In Connection context, enter the UNIX usernames that users can log in as (for example,
root
orec2-user
).
- Select Add application.
-
Create an API token with the following permissions:
Type Item Permission Account Access: Apps & Policies Edit -
Make a
POST
request to the Access applications endpoint:
-
Add the following permission to your
cloudflare_api_token
↗:Access: Apps and Policies Write
-
Use the
cloudflare_zero_trust_access_application
↗ resource to create an infrastructure application: -
Use the
cloudflare_zero_trust_access_policy
↗ resource to add an infrastructure policy to the application:
The targets in this application are now secured by your infrastructure policies.
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.
To generate a Cloudflare SSH CA and get its public key:
-
Create an API token with the following permissions:
Type Item Permission Account Access: SSH Auditing Edit -
If you have not yet generated a Cloudflare SSH CA, make a
POST
request to the Cloudflare API: -
If you have already created a Cloudflare SSH CA or receive the error message
access.api.error.gateway_ca_already_exists
, make aGET
request instead: -
Copy the
public_key
value returned in the response.
-
Use the following command to change directories to the SSH configuration directory on the remote target machine:
-
Once there, you can use the following command to both generate the file and open a text editor to input/paste the public key.
-
In the
ca.pub
file, paste the public key without any modifications.The
ca.pub
file can hold multiple keys, listed one per line. Empty lines and comments starting with#
are also allowed. -
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:
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.
-
While staying within the
/etc/ssh
directory on the remote machine, open thesshd_config
file. -
Go to the row named
PubkeyAuthentication
. In most default configurations, the row will appear commented out as follows: -
Remove the
#
symbol to uncomment the line; keep the settingyes
enabled. -
Next, add a new line below
PubkeyAuthentication
as follows:Save the file and quit the editor. You might need to use the following command again to save and exit.
Once you have modified your SSHD configuration, restart the SSH service on the remote machine.
For older Debian/Ubuntu versions:
For newer Debian/Ubuntu versions:
For CentOS/RHEL 6 and older:
For CentOS/RHEL 7 and newer:
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:
SSH with Access for Infrastructure also supports scp
and rsync
commands. At this time, sftp
is not supported.
For more information, refer to the Access for Infrastructure documentation.
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.
To log SSH commands, you will need to generate an HPKE key pair and upload the public key to Cloudflare.
-
Download ↗ the Cloudflare
ssh-log-cli
utility. -
Using the
ssh-log-cli
utility, generate a public and private key pair.This command outputs two files, an
sshkey.pub
public key and a matchingsshkey
private key. -
In Zero Trust ↗, go to Settings > Network.
-
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.
To turn off SSH command logging, delete your uploaded public key:
-
In Zero Trust ↗, go to Settings > Network > SSH encryption public key.
-
Select Remove.
-
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.
To delete the SSH encryption public key using the API:
SSH command logs are not visible from the dashboard itself and must be exported and decrypted.
To manually retrieve logs:
- In Zero Trust ↗, go to Logs > Access.
- Select a user who was allowed to access the target.
- Select Download to download the session’s command log.
-
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.This command outputs a
sshlog-decrypted.zip
file with the decrypted logs.