Setting Up Cloudflare Tunnels

Table of Contents
A Guide on Setting Up Cloudflare Tunnels
Introduction
Cloudflare Tunnels provide a secure way to host websites by establishing a direct connection between your local network and Cloudflare. This guide will walk you through the process of setting up Cloudflare Tunnels to enhance the security and performance of your website.
Why Cloudflare Tunnels?
Cloudflare Tunnels offer several benefits, including reducing attack vectors and simplifying network configurations. By using Cloudflare as a proxy, you can close off external ports and ensure all traffic goes through Cloudflare’s secure network. This provides an additional layer of protection for your website.
Prerequisites
Before setting up Cloudflare Tunnels, make sure you have the following:
- An active Cloudflare account.
- A server running Ubuntu.
Current Linux Installation
Cloudflare’s current Linux instructions use the Cloudflare package repository. The GitHub download command in Step 1 stays below as an alternate installation path. Check the installed version before creating a tunnel.
sudo mkdir -p --mode=0755 /usr/share/keyrings
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared any main" | sudo tee /etc/apt/sources.list.d/cloudflared.list
sudo apt-get update
sudo apt-get install cloudflared
cloudflared --version
See Cloudflare’s current download instructions for packages and architectures other than Ubuntu amd64.
Step 1: Installation
To begin, you need to install the Cloudflare Tunnels package on your Ubuntu server. Follow these steps:
- Open the terminal on your Ubuntu server.
- Download the latest version of the Cloudflare Tunnels package by running the following command:
wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
Step 2: Authentication
Next, you need to authenticate your Cloudflare account with the Cloudflare Tunnels service. Follow these steps:
- Run the following command in the terminal:
cloudflared tunnel login
- Click on the site you’d like to use with your tunnel to complete the authentication process.
The login command opens a browser and writes cert.pem in the current user’s ~/.cloudflared directory. This certificate authorizes local tunnel management. Store the certificate on the administrator’s system with restrictive file permissions. The JSON file created in Step 3 belongs to one tunnel, so protect the file separately.
Step 3: Creating a Tunnel
Now it’s time to create your Cloudflare Tunnel. Follow these steps:
- Run the following command in the terminal to create a tunnel:
cloudflared tunnel create name_of_tunnel
Choose a name for your tunnel that is memorable and descriptive. Note that the tunnel name can’t be changed later.
After creation, note the UUID in the command output. Use the UUID for later configuration.
To view a list of all active tunnels, use the command:
cloudflared tunnel list
This will display the names and UUIDs of your tunnels.
Named Tunnel Workflow
The name maps to a stable tunnel UUID. Record both values and the credentials file path in your deployment notes.
cloudflared tunnel create app-prod
cloudflared tunnel list
cloudflared tunnel info app-prod
Cloudflare’s current local-management guide covers named tunnel creation and inspection.
Step 4: Configuring the Tunnel
To configure your tunnel and start routing traffic, follow these steps:
Navigate to the Cloudflare Tunnels directory on your server. The default location is
/etc/cloudflared.Within this directory, create a new file named
config.ymlusing a text editor of your choice.Populate the config.yml file with the following contents:
tunnel: <your_tunnels_uuid>
credentials-file: /path/to/credentials/<UUID>.json
Make sure to replace <your_tunnels_uuid> with the UUID of your tunnel, and update the path to the credentials file if necessary.
For a Linux service, place config.yml and the JSON credentials file in the service user’s .cloudflared directory, or pass the configuration path explicitly. Running the installer with sudo changes $HOME to /root, so a file under a normal user’s home directory needs an explicit path. See
Cloudflare’s Linux service instructions
.
Step 5: Routing Traffic
To specify the internal services you want to serve through your tunnel, follow these steps:
Open the
config.ymlfile again.Add the ingress parameters to the file to define the services you want to route through Cloudflare. For example:
tunnel: <your_tunnels_uuid>
credentials-file: /path/to/credentials/<UUID>.json
ingress:
- hostname: example.com
service: http://10.10.10.123:1234
- hostname: subdomain.example.com
service: http://10.10.10.123:8888
- service: http_status:404
Replace <your_tunnels_uuid> with your tunnel’s UUID, and update the hostname and service details according to your configuration.
- Save the config.yml file.
Ingress Rule Order
Cloudflared evaluates ingress rules from top to bottom. Put specific host and path rules before broad rules. Keep the final http_status:404 rule. The final rule rejects unmatched hostnames instead of sending them to an unintended origin.
Validate the file before starting the tunnel, then test which rule matches a hostname:
cloudflared tunnel ingress validate
cloudflared tunnel ingress rule https://example.com
The current configuration reference documents rule matching, path behavior, and validation.
Step 6: Creating DNS Records
To create DNS records for your tunnel’s hostname and services, follow these steps:
Open the terminal.
Use the following command to create a DNS record:
cloudflared tunnel route dns <UUID or NAME of tunnel> <hostname>
Replace <UUID or NAME of tunnel> with the UUID or name of your tunnel, and <hostname> with the desired hostname for your service.
- For example, to create a DNS record for example.com, run the command:
cloudflared tunnel route dns <UUID or NAME of tunnel> example.com
Please note that the changes will be reflected in the DNS section of your Cloudflare dashboard.
DNS and Origin Requirements
The zone must exist in Cloudflare and use active Cloudflare nameservers. The DNS route creates a CNAME to <UUID>.cfargotunnel.com. The route does not start the tunnel and does not repair an origin service.
Check the origin from the host running cloudflared:
curl -I http://10.10.10.123:1234
ss -ltnp
The service address and port in config.yml must match a listener reachable from the cloudflared process. Use 127.0.0.1 for a service on the same host when no other local network client needs access. For a service on another host, restrict the origin firewall to the tunnel host or an approved internal path.
For an HTTPS origin, the certificate name must match the hostname expected by cloudflared. Set an explicit origin server name when the certificate uses a name different from the local service address. Do not disable TLS verification as a first troubleshooting step. See
Cloudflare’s origin parameters
.
The tunnel connection uses outbound port 7844 over UDP or TCP. Permit outbound traffic and return traffic on the selected protocol. No inbound port forwarding is required for the tunnel connection. Cloudflare lists the checks in its
connectivity pre-check guide
.
Step 7: Starting the Tunnel
To test and start your Cloudflare Tunnel, follow these steps:
Open the terminal.
Run the following command to start the tunnel:
cloudflared tunnel run <UUID or NAME of tunnel>
Replace <UUID or NAME of tunnel> with the UUID or name of your tunnel.
Cloudflared will now set up your tunnel and display information about its status. Once the tunnel is successfully up and running, you can proceed to the next step.
To prevent the tunnel from closing when you exit the terminal, you need to run Cloudflared as a systemd service. Use the following command:
cloudflared --config /path/to/config.yml service install
Replace /path/to/config.yml with the path to your config.yml file.
Service Operation
Use an explicit config path when the file lives under a normal user’s home directory:
sudo cloudflared --config /home/<USER>/.cloudflared/config.yml service install
sudo systemctl enable --now cloudflared
sudo systemctl status cloudflared
sudo journalctl -u cloudflared -f
After changing config.yml, restart the service and check its status. The service keeps the connector running after logout and across reboots. Cloudflare’s
service guidance
covers the supported service modes.
Access Policy Boundaries
Cloudflare Tunnel provides the connection between Cloudflare and the origin. It does not authenticate application users by itself. A published hostname without an Access application follows the exposure rules in DNS, tunnel ingress, and the origin firewall.
| Control | Purpose |
|---|---|
| Tunnel | Connects cloudflared to the Cloudflare network through outbound connections |
| Ingress rule | Selects the origin service for a hostname or path |
| Cloudflare Access | Checks identity, group, device, session, and other policy conditions |
| Origin firewall | Limits direct access to the service and protects the origin if another route appears |
For a private web application, create a self-hosted Access application for the exact hostname. Add an Allow policy for the intended identity group, then test an allowed account and an unlisted account. Access policies define who receives access. They do not replace the tunnel route or the origin service. See Cloudflare’s Access policy guide .
Use application paths when one hostname contains areas with different access rules. A more specific path takes precedence, so protect administrative paths with their own policy. See Cloudflare’s application path guidance .
Logging and Monitoring
Systemd sends service output to the journal. Follow journal output during startup and after configuration changes:
sudo journalctl -u cloudflared --since "15 minutes ago"
sudo journalctl -u cloudflared -f
For a short interactive test, run the tunnel with debug logging. For persistent local logs, use a log directory and apply the host’s normal retention controls:
cloudflared tunnel --loglevel debug run <UUID or NAME>
cloudflared tunnel --loglevel info --log-directory /var/log/cloudflared run <UUID or NAME>
For account-level live logs, authenticate cloudflared and use:
cloudflared tail <UUID or NAME>
cloudflared tunnel diag
Tunnel logs cover the connector-to-Cloudflare connection and requests between cloudflared and the origin. Remote log streaming drops entries under high throughput, so use local service logs when a complete record matters. Cloudflare documents
log streams
and
diagnostic logs
.
Troubleshooting
| Symptom | First checks |
|---|---|
| Healthy tunnel, failed application | Run curl against the origin from the cloudflared host. Check the service scheme, port, bind address, and origin TLS name. |
| Inactive or Down tunnel | Run sudo systemctl status cloudflared, inspect journalctl, and review cloudflared tunnel list. |
| Degraded tunnel | Check outbound and return traffic on port 7844, then inspect connector errors. |
| Hostname does not resolve | Confirm the zone’s nameservers, rerun cloudflared tunnel route dns, and inspect the CNAME. |
| Access denies an expected user | Check the hostname and path in the Access application, policy order, identity group, identity provider, and session state. |
| Unexpected origin exposure | Review every ingress rule, public DNS record, origin listener, and inbound firewall rule. |
Tunnel status reports the connector’s relationship with Cloudflare. A Healthy status does not prove reachability of the internal origin. Cloudflare lists this boundary and the status meanings in
Common errors
.
When Cloudflare connectivity fails, run the network checks from the same host. When the host reaches Cloudflare but the application fails, test the origin locally before changing tunnel settings. This separates connector failures from origin failures.
Safe Exposure Checks
Run these checks before declaring a published service ready:
- Confirm the public hostname resolves to a Cloudflare CNAME and does not publish the origin’s public IP.
- Confirm the origin service responds from the tunnel host.
- Confirm the public hostname returns the expected application response.
- Request an unmatched hostname and confirm the final ingress rule returns
404. - Confirm the origin firewall blocks unwanted inbound access and permits only the intended internal source.
- Test an allowed Access identity and an unlisted identity in separate browser sessions.
- Record the tunnel UUID, hostname, origin address, policy name, service unit, and last validation date.
The
Cloudflare firewall guidance
describes a positive model with blocked ingress and only the required cloudflared egress.
Current Deployment Checks
Cloudflare’s current documentation separates published applications from private-network routes. A published application becomes reachable at its hostname. A private CIDR route requires enrolled client devices and an access policy. Read the current tunnel creation guide before choosing the route type.
For a locally managed tunnel, the core command sequence remains:
cloudflared tunnel create my-app
cloudflared tunnel route dns my-app app.example.com
cloudflared tunnel --config /etc/cloudflared/config.yml run my-app
The configuration should end with a catch-all rule so unmatched requests fail instead of reaching an unintended service:
ingress:
- hostname: app.example.com
service: http://127.0.0.1:8080
- service: http_status:404
Before publishing, test the origin locally, confirm the service binds to the intended interface, and place authentication in front of administrative applications. A tunnel removes the need for an inbound port in the common outbound-connector model. A tunnel does not replace application authentication, authorization, patching, logging, or data classification.
When a connector fails, run cloudflared tunnel list, inspect the service logs, confirm outbound connectivity to Cloudflare, and verify the credentials-file path. Cloudflare’s
useful commands
and
tunnel troubleshooting guide
cover the current command names and common errors. Treat a tunnel token as a secret. Rotate a token after exposure in shell history, logs, screenshots, or a shared repository.
Conclusion
In this guide, we have covered the steps to set up Cloudflare Tunnels on Ubuntu. By following these instructions, you can enhance the security and performance of your website by using Cloudflare’s network. Remember to regularly monitor your tunnels and adjust the configuration as needed.
If you encounter any issues or need further assistance, refer to the official Cloudflare Tunnels documentation .
References
- Cloudflare Tunnels Documentation
- Cloudflare Tunnels GitHub Repository
- tcude - How to Set Up Cloudflare Tunnels on Ubuntu






