Cloudflare Tunnels
Learn how to set up Cloudflare Tunnel to securely expose applications without opening firewall ports
What is Cloudflare Tunnel?
Cloudflare Tunnel is a secure, encrypted connection that allows users to expose applications and services to the internet without opening inbound firewall ports. It enables businesses and developers to securely route traffic through Cloudflare's global network, protecting applications from DDoS attacks, unauthorised access, and other security threats.
With Cloudflare Tunnel, self-hosted services can be accessed from anywhere without requiring a public IP address, VPN, or complex networking configurations. It works by running a lightweight Cloudflare Connector (cloudflared) in your local environment, which establishes a persistent outbound connection to Cloudflare's network.
Key Benefits:
- Zero Trust Security – Protects applications with identity-based access controls.
- No Open Ports – Eliminates the need to expose services to the public internet.
- Automatic TLS Encryption – Ensures end-to-end encryption without managing certificates.
- Seamless Integration – Works with Cloudflare Access, Zero Trust, and Load Balancing.
Prerequisites
- Virtual Machine running Ubuntu 22.04 or newer
Update Package Repository and Packages
sudo apt update
sudo apt upgradeDownload and Install Cloudflared
wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared-linux-amd64.deb
cloudflared --versionAuthenticate with Cloudflare
cloudflared tunnel loginProvide your Cloudflare credentials and token
Create a new tunnel
cloudflared tunnel create my-tunnelConfigure the tunnel
cloudflared tunnel route dns my-tunnel jenkins.devopsfoundry.comCopy tunnel ID
Create "config.yml" file in cloudflared dir
vim ~/.cloudflared/config.ymltunnel: j-tunnel
credentials-file: /home/femi/.cloudflared/3e9dfb6f-63c9-4902-b48d-83aa2abb386a.json
ingress:
- hostname: jenkins.devopsfoundry.com
service: http://127.0.0.1:8080 # Another service using HTTPS
- service: http_status:404 # Default for unmatched requestsStart the tunnel
cloudflared tunnel run my-tunnelExposing Kubernetes Pods
Kubernetes Integration
Create Secret with tunnel ID:
kubectl create secret generic tunnel-credentials \
--namespace argocd \
--from-file=credentials.json=/home/femi/.cloudflared/1fae3131-bf44-4430-afb9-7fa364fd48b9.jsonvim cloudflared.yamlEdit this file to suit your application:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: cloudflared
namespace: argocd
spec:
selector:
matchLabels:
app: cloudflared
replicas: 1
template:
metadata:
labels:
app: cloudflared
spec:
containers:
- name: cloudflared
image: cloudflare/cloudflared:2022.3.0
args:
- tunnel
- --config
- /etc/cloudflared/config/config.yaml
- run
livenessProbe:
httpGet:
path: /ready
port: 2000
failureThreshold: 1
initialDelaySeconds: 10
periodSeconds: 10
volumeMounts:
- name: config
mountPath: /etc/cloudflared/config
readOnly: true
- name: creds
mountPath: /etc/cloudflared/creds
readOnly: true
volumes:
- name: creds
secret:
secretName: tunnel-credentials
- name: config
configMap:
name: cloudflared
items:
- key: config.yaml
path: config.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: cloudflared
namespace: argocd
data:
config.yaml: |
# Name of the tunnel you want to run
tunnel: argo-tunnel
credentials-file: /etc/cloudflared/creds/credentials.json
metrics: 0.0.0.0:2000
no-autoupdate: true
ingress:
- hostname: argocd.devopsfoundry.com
service: https://argocd-server:443
originRequest:
noTLSVerify: true
- service: http_status:404kubectl apply -f cloudflared.yamlHow is this guide?