In this guide, youâll learn how to securely share an application running on your server onto the internet using Cloudflare Tunnel!
Why Use Cloudflare Tunnel?
- Share local applications youâve built with other people
- Host applications from home servers without port forwarding
Alternatives to Cloudflare Tunnel
- ngrok is another option, but it requires a paid plan for custom domains and persistent URLs. Itâs easy to use but not as flexible as Cloudflare Tunnel.
Prerequisites
Before we begin, ensure you have:
- An Ubuntu server
- SSH access to your server with sudo privileges
- Basic command line familiarity
- A Cloudflare account (free tier works perfectly)
- A domain name (optional)
Important note: The CLI tool is called cloudflared
(with a âdâ at the end). Donât let it trip you up!
Instant Tunnel: TryCloudflare
Before diving into full tunnel setup, let me show you the fastest way to start a tunnel. If you just want to test something quickly, you can use TryCloudflare, a free service that requires no configuration.
Instant Tunnel in One Command
On your Ubuntu server, run:
cloudflared tunnel --url http://localhost:8080
What this does: Cloudflare instantly generates a random URL like https://seasonal-deck-organisms-sf.trycloudflare.com
that tunnels directly to your local service. No accounts, no setup, no DNS configuration and no firewall changes required.
TryCloudflare Limitations
Important limitations to understand:
- Changing URLs: New random URL every time you restart the tunnel
- Request limits: Maximum 200 concurrent requests
- No uptime guarantee: Designed for testing only, not production workloads
- No Server-Sent Events: SSE streaming not supported
- No persistence: Tunnels disappear when you close the terminal or reboot
Testing your tunnel: Visit the generated URL in any browser and youâll see your Ubuntu serverâs application, complete with HTTPS and DDoS protection from Cloudflareâs global network.
Step 1: Custom Domains
To use Cloudflare Tunnel with your own domain, you have two options:
A. Full DNS Setup
For full DNS setup, you need to switch your domainâs DNS entirely to Cloudflare. Doing so provides:
- Automatic DNS management: Cloudflare automatically creates and manages DNS records for new tunnels
- Full feature access: Access to all Cloudflare security, performance, and analytics features
- Simplified administration: One dashboard to manage DNS, tunnels, and security policies
- Global load balancing: Distribute traffic across multiple servers automatically
B. Partial DNS Setup
You can still use Cloudflare Tunnel with other DNS providers by manually creating CNAME records:
- DNS record type: CNAME (or ALIAS for root domains)
- Record name: Your subdomain (e.g.,
api
forapi.yourdomain.com
) - Record value:
subdomain.domain.tld.cdn.cloudflare.net
Generally speaking, youâll want to use the full DNS setup for the best experience, but if you prefer to keep your existing DNS provider, you can manually create CNAME records pointing to Cloudflareâs infrastructure.
Step 2: Installing cloudflared on Ubuntu
On your Ubuntu server:
# Add Cloudflare's package signing key
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
# Add Cloudflare's repository to APT sources
echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflared.list
# Update package lists and install cloudflared
sudo apt-get update && sudo apt-get install cloudflared
What this installation process does:
- Package signing verification: The GPG key ensures youâre installing authentic Cloudflare software, not malicious packages
- Repository integration: Adding Cloudflareâs repository allows automatic updates through your normal
apt upgrade
process - System-wide installation: Places
cloudflared
in/usr/local/bin/
making it accessible to all users and system services
Verify successful installation:
cloudflared --version
You should see version information like cloudflared version 2024.x.x
confirming successful installation.
Step 3: Two Options to Creating Tunnels
Cloudflare offers two distinct methods for tunnel creation, each suited to different server administration needs:
Dashboard Method
This newer approach uses the intuitive Zero Trust dashboard and is perfect for learning:
Benefits:
- Visual interface: Point-and-click tunnel management with guided workflows
- Generated commands: Pre-configured installation commands with embedded credentials
- Remote management: Configure and monitor tunnels from anywhere without server access
- Built-in monitoring: Real-time connection status and traffic analytics
Process:
- Navigate to Zero Trust dashboard â Networks â Tunnels
- Click âCreate a tunnelâ â Choose âCloudflaredâ connector
- Name your tunnel descriptively (e.g., âproduction-web-serverâ, âdev-api-serverâ)
- Copy the provided installation command containing your unique tunnel token
- Run the command on your Ubuntu server
Command Line Method
This traditional command-line approach provides deeper understanding and is better for production automation:
Benefits:
- Infrastructure as code: Configuration files can be version-controlled with Git
- Automation friendly: Easily integrated into deployment scripts and configuration management
- Fine-grained control: Direct management of all tunnel parameters and routing rules
- Learning value: Better understanding of how tunnels work under the hood
Weâll focus on the CLI method below.
Step 4: Creating a Tunnel (CLI Method)
Letâs create a tunnel using the command-line:
Authenticate with Cloudflare
On your Ubuntu server:
cloudflared login
What happens during authentication: This command opens a browser-based authentication flow. If youâre on a headless server, copy the URL to a local browser:
- The command displays a URL like
https://dash.cloudflare.com/argotunnel?callback=...
- Open this URL in any browser where you can log into Cloudflare
- Authenticate and grant tunnel creation permissions
- The authentication creates a certificate file at
~/.cloudflared/cert.pem
Security consideration: This certificate authorizes tunnel creation for your Cloudflare account. Treat it like a password and keep it secure.
Create Your Named Tunnel
# Create a new tunnel with a descriptive name
cloudflared tunnel create your-tunnel-name
# List all tunnels to verify your new tunnel was created
cloudflared tunnel list
Understanding tunnel creation:
- Persistent identity: Creates a permanent relationship between your chosen name and a UUID
- Inactive by default: The tunnel exists but isnât runningâthink of it as reserving a phone number
- Credentials generation: Creates a JSON file containing tunnel-specific authentication tokens
Important details to record:
- Tunnel UUID: Long identifier like
ed5bfe16-cb5f-449c-b2e9-7c300b749c79
- Credentials file location: Path to the JSON file (usually
~/.cloudflared/[uuid].json
)
Verify Tunnel Creation
cloudflared tunnel list
Expected output shows your tunnel with âINACTIVEâ statusâthis is normal since we havenât configured routing or started the daemon yet.
Step 5: Server Configuration File
Configuration files are essential for production server management, providing repeatability and documentation:
Create Configuration Directory
On your Ubuntu server:
# Create user configuration directory
mkdir -p ~/.cloudflared
cd ~/.cloudflared
# Set secure permissions
chmod 700 ~/.cloudflared
Directory security: The 700
permission ensures only your user can read tunnel credentials, preventing other server users from accessing your tunnel configuration.
Configuration for a Single Service
For servers that run a single application:
vim ~/.cloudflared/config.yml
Basic web server configuration (replace values with your actual details):
tunnel: ed5bfe16-cb5f-449c-b2e9-7c300b749c79 # Change to your tunnel UUID
credentials-file: /home/yourusername/.cloudflared/ed5bfe16-cb5f-449c-b2e9-7c300b749c79.json # Change to your username and tunnel UUID
# Single service routing
url: http://localhost:8080
Configuration explanation:
- tunnel: The UUID from your tunnel creation stepâthis identifies your specific tunnel
- credentials-file: Absolute path to the JSON credentials file (replace
username
with your actual username) - url: Your local service endpointâadjust port to match your application
Configuration for Multiple Services
For servers running multiple applications:
tunnel: ed5bfe16-cb5f-449c-b2e9-7c300b749c79 # Change to your tunnel UUID
credentials-file: /home/yourusername/.cloudflared/ed5bfe16-cb5f-449c-b2e9-7c300b749c79.json # Change to your username and tunnel UUID
# The below are examples. Change the hostnames and services as needed
ingress:
- hostname: api.yourdomain.com
service: http://localhost:8080 # REST API service
- hostname: admin.yourdomain.com
service: http://localhost:9000 # Admin dashboard
- hostname: websocket.yourdomain.com
service: ws://localhost:8081 # WebSocket service
- hostname: static.yourdomain.com
service: http://localhost:8082 # Static file server
- service: http_status:404 # Required catch-all rule
Ingress rules explained:
- hostname matching: Each hostname routes to a different local service on your server
- Service protocols: Support for HTTP, HTTPS, WebSocket, and TCP protocols
- Catch-all rule: The final rule is mandatory and handles unmatched requests
- Load balancing: Can distribute traffic across multiple backend servers
Secure Configuration File Permissions
# Secure configuration file permissions
chmod 600 ~/.cloudflared/config.yml
# Verify permissions
ls -la ~/.cloudflared/
Security importance: Configuration files contain sensitive routing information and should only be readable by the tunnel owner.
Step 6: DNS Configuration & Tunnel Activation
Create DNS Routes for Your Services
Connect your tunnel to specific hostnames that will route to your Ubuntu server:
# Create DNS routing for your primary service
cloudflared tunnel route dns your-tunnel-name app.yourdomain.com
# Add additional hostnames for multi-service configurations
cloudflared tunnel route dns your-tunnel-name api.yourdomain.com
cloudflared tunnel route dns your-tunnel-name admin.yourdomain.com
What DNS routing creates:
- CNAME records: Points
app.yourdomain.com
to<tunnel-uuid>.cfargotunnel.com
- Automatic SSL: Cloudflare automatically provisions and manages SSL certificates
- Global anycast: Your Ubuntu server becomes accessible from Cloudflareâs 300+ data centers worldwide
Start Your Tunnel for Testing
Basic tunnel startup:
cloudflared tunnel --config ~/.cloudflared/config.yml run your-tunnel-name
With detailed logging for troubleshooting:
cloudflared tunnel --loglevel debug --config ~/.cloudflared/config.yml run your-tunnel-name
Success indicators to look for:
INF Connection to edge established
- Tunnel connected to Cloudflare networkINF Registered tunnel connection
- Your specific tunnel is activeINF Initial protocol http2
- Communication protocol established
Test your tunnel: Your Ubuntu server applications should now be accessible at https://app.yourdomain.com
from anywhere in the world.
Monitor Tunnel Status
In a separate terminal session:
# Check tunnel status
cloudflared tunnel info your-tunnel-name
# Monitor live connection logs
tail -f ~/.cloudflared/cloudflared.log
Step 7: Advanced Server Configurations
Non-HTTP Service Tunneling
Your Ubuntu server can expose more than just web applications through Cloudflare Tunnel:
tunnel: ed5bfe16-cb5f-449c-b2e9-7c300b749c79 # Change to your tunnel UUID
credentials-file: /home/yourusername/.cloudflared/ed5bfe16-cb5f-449c-b2e9-7c300b749c79.json # Change to your username and tunnel UUID
# The below are examples. Change the hostnames and services as needed
ingress:
- hostname: ssh.yourdomain.com
service: ssh://localhost:2222 # Change to your SSH port if needed
- hostname: database.yourdomain.com
service: tcp://localhost:5432 # PostgreSQL database
- hostname: redis.yourdomain.com
service: tcp://localhost:6379 # Redis cache
- hostname: monitoring.yourdomain.com
service: http://localhost:3000 # Grafana dashboard
- service: http_status:404
Server service examples:
- SSH tunneling: Secure remote administration without opening port 22
- Database access: Direct database connections through encrypted tunnels
- Monitoring tools: Access to Grafana, Prometheus, or custom monitoring dashboards
- Development tools: Code servers, documentation sites, or internal tools
Production Server Routing Strategies
Environment-based routing:
ingress:
- hostname: prod.yourdomain.com
service: http://localhost:8080
- hostname: staging.yourdomain.com
service: http://localhost:8081
- hostname: dev.yourdomain.com
service: http://localhost:8082
- service: http_status:404
Service-based routing:
ingress:
- hostname: www.yourdomain.com
service: http://localhost:80 # Main website
- hostname: api.yourdomain.com
service: http://localhost:8080 # API server
- hostname: admin.yourdomain.com
service: http://localhost:9000 # Admin interface
- hostname: docs.yourdomain.com
service: http://localhost:4000 # Documentation site
- service: http_status:404
Step 8: Run Cloudflare Tunnel on Boot
If you want your Cloudflare Tunnel to run automatically when the server starts, you can set it up as a system service. This allows the tunnel to run in the background and remain active and start automatically whenever you boot up your server.
Service Installation and Configuration
Install cloudflared as a system service:
sudo cloudflared service install
What service installation creates:
- Systemd service file:
/etc/systemd/system/cloudflared.service
- Automatic startup: Service configured to start on boot
- Process monitoring: Systemd automatically restarts the service if it crashes
- Logging integration: Logs accessible through
journalctl
System-Wide Configuration Setup
Configuration file location: System services require configuration in /etc/cloudflared/
, not user directories.
Copy your configuration to the system location:
# Create system configuration directory
sudo mkdir -p /etc/cloudflared
# Copy your working configuration
sudo cp ~/.cloudflared/config.yml /etc/cloudflared/
# Set appropriate permissions
sudo chmod 600 /etc/cloudflared/config.yml
sudo chown root:root /etc/cloudflared/config.yml
Update configuration for system service context:
sudo vim /etc/cloudflared/config.yml
Critical system service configuration:
tunnel: ed5bfe16-cb5f-449c-b2e9-7c300b749c79
credentials-file: /home/username/.cloudflared/ed5bfe16-cb5f-449c-b2e9-7c300b749c79.json
# Production service settings
logfile: /var/log/cloudflared/cloudflared.log
loglevel: info
# Your service configuration
url: http://localhost:8080
Why absolute paths are critical: System services run in a different context than user sessions. The service must be able to locate credential files regardless of which user starts the service.
Service Management and Monitoring
Essential systemd service commands:
# Start the cloudflared service
sudo systemctl start cloudflared
# Enable automatic startup on boot
sudo systemctl enable cloudflared
# Check current service status
sudo systemctl status cloudflared
# Stop the service
sudo systemctl stop cloudflared
# Restart service after configuration changes
sudo systemctl restart cloudflared
# Disable automatic startup
sudo systemctl disable cloudflared
Service monitoring and logging:
# View live service logs
sudo journalctl -u cloudflared -f
# View recent logs with timestamps
sudo journalctl -u cloudflared --since "1 hour ago"
# View logs from last boot
sudo journalctl -u cloudflared -b
# Check if service is enabled for boot
sudo systemctl is-enabled cloudflared
Log file management:
# Create log directory
sudo mkdir -p /var/log/cloudflared
# Set appropriate log permissions
sudo chown syslog:adm /var/log/cloudflared
sudo chmod 755 /var/log/cloudflared
Production Service Validation
Verify service is running correctly:
# Check process status
ps aux | grep cloudflared
# Verify network connections
sudo netstat -tlpn | grep cloudflared
# Test tunnel connectivity
curl -I https://yourdomain.com
# Monitor resource usage
sudo systemctl show cloudflared --property=MainPID,CPUUsageNSec,MemoryCurrent
Step 9: Troubleshooting
Connection and Network Issues
âFailed to create new quic connectionâ error:
This may be because of firewall restrictions or ISP limitations:
# Check if UFW is blocking outbound connections
sudo ufw status verbose
# Allow Cloudflare Tunnel's required outbound ports
sudo ufw allow out 80/tcp
sudo ufw allow out 443/tcp
sudo ufw allow out 7844/udp
# Force HTTP/2 protocol instead of QUIC (more firewall-friendly)
cloudflared tunnel --protocol http2 --config ~/.cloudflared/config.yml run your-tunnel-name
Protocol explanation: QUIC (UDP-based) provides better performance but some firewalls or ISPs block it. HTTP/2 over TCP is more universally supported.
Configuration and Service Issues
âCannot determine default configuration pathâ error:
Always specify configuration file location explicitly:
# Correct command with explicit config path
cloudflared tunnel --config ~/.cloudflared/config.yml run your-tunnel-name
# For system service, ensure config exists
sudo ls -la /etc/cloudflared/config.yml
Service fails to start but manual tunnel works:
Common system service issues and solutions:
-
Configuration file location mismatch:
# Verify system config exists sudo cat /etc/cloudflared/config.yml # Check service logs for path errors sudo journalctl -u cloudflared --lines=20
-
Incorrect credentials file permissions:
# Service needs access to credentials file sudo chmod 644 /home/username/.cloudflared/uuid.json # Or copy credentials to system location sudo cp /home/username/.cloudflared/uuid.json /etc/cloudflared/ sudo chmod 600 /etc/cloudflared/uuid.json sudo chown root:root /etc/cloudflared/uuid.json
-
Service user access issues:
# Check which user runs the service sudo systemctl show cloudflared --property=User # Ensure service user can access files sudo -u cloudflared test -r /etc/cloudflared/config.yml
Step 10: Useful Command Line Commands
Tunnel Operations Youâll Use Regularly
# List all tunnels on your account
cloudflared tunnel list
# Get detailed information about your server's tunnel
cloudflared tunnel info your-tunnel-name
# Validate configuration file syntax
cloudflared tunnel --config ~/.cloudflared/config.yml validate
# Add new hostname to existing tunnel
cloudflared tunnel route dns your-tunnel-name new-service.yourdomain.com
# Test tunnel connectivity
curl -I https://yourdomain.com
System Service Management
# Check service health
sudo systemctl status cloudflared
# Restart service after configuration changes
sudo systemctl restart cloudflared
# Monitor service logs in real-time
sudo journalctl -u cloudflared -f
# Check service startup time and performance
sudo systemctl show cloudflared --property=ExecMainStartTimestamp,CPUUsageNSec
# Verify service starts automatically
sudo systemctl is-enabled cloudflared
DNS and Routing Management
Adding new services: Use the cloudflared tunnel route dns
command for each new hostname.
Removing DNS records: Navigate to Cloudflare dashboard â DNS â Records, locate the CNAME record for your hostname, and delete it.
Bulk hostname management: For multiple hostnames, the Cloudflare dashboard provides more efficient management than individual CLI commands.
Server Security and Monitoring
# Monitor tunnel connection attempts
sudo journalctl -u cloudflared | grep -E "(connection|auth|error)"
# Check for unauthorized access attempts
sudo tail -f /var/log/auth.log | grep -E "(ssh|tunnel)"
# Verify only expected ports are listening
sudo netstat -tlpn | grep -E "(cloudflared|80|443)"
# Monitor server resource usage with tunnels
htop -p $(pgrep cloudflared)
Step 11: Security and Access Control
IP-Based Access Restrictions
Restrict tunnel access to specific IP ranges or geographic locations:
In your Cloudflare dashboard:
-
Navigate to âAccessâ â âApplicationsâ
-
Click âAdd an applicationâ â âSelf-hostedâ
-
Configure application security:
- Application name: âUbuntu Server Accessâ
- Application domain: âapp.yourdomain.comâ
- Session duration: Set appropriate timeout
-
Create access policies:
- Policy name: âOffice IP Allowlistâ
- Action: âAllowâ
- Rule type: âIP Rangesâ
- Value: Your office/home IP addresses (e.g.,
203.0.113.0/24
)
Authentication Integration
Email-based one-time passwords:
- In application policy setup:
- Rule type: âEmailâ
- Value: Authorized email addresses
- Users receive OTP codes via email for access
- No additional authentication infrastructure required on your Ubuntu server
Corporate authentication integration:
- SAML/OIDC: Connect to existing corporate identity providers
- Multi-factor authentication: Require additional verification steps
- Session management: Control session duration and concurrent connections
Step 12: Server Maintenance
Regular Maintenance Tasks
Weekly server maintenance checklist:
# Update cloudflared and system packages
sudo apt update && sudo apt upgrade
# Check tunnel service logs for errors
sudo journalctl -u cloudflared --since "1 week ago" | grep -i error
# Verify tunnel connectivity
curl -I https://yourdomain.com
# Review Cloudflare analytics for unusual traffic patterns
# (Check in the dashboard on Cloudflare's website under Analytics â Traffic)
Conclusion
You now have general knowledge of Cloudflare Tunnel deployment and management for your Ubuntu server:
- â Instant tunnels using TryCloudflare
- â Flexible tunnel creation using both dashboard and CLI methods
- â Advanced server configurations supporting multiple services and protocols
- â System service integration with systemd for reliability and automatic startup
- â Troubleshooting
- â Server maintenance with regular updates and monitoring