How to use Cloudflare and Raspberry Pi Together

How to use Cloudflare and Raspberry Pi Together

Below is a detailed, technical, and (roughly) 5,000-word exploration of how one can integrate Cloudflare and Raspberry Pi — covering motivations, architecture, configuration, advanced options, trade-offs, security, monitoring, and future directions. Use this as a foundation for a white paper, blog, or internal reference.
From Chat GPT


Table of Contents

  1. Introduction & Motivation
  2. Architectural Patterns & Use Cases
  3. Core Components & Terminology
  4. Setting Up a Raspberry Pi Environment
  5. Installing & Configuring cloudflared on Raspberry Pi
  6. Creating & Managing Cloudflare Tunnels
  7. DNS, Routing, and Ingress Rules
  8. Reverse Proxy / Web Server Integration (e.g. Nginx)
  9. Handling TCP/UDP Services (Spectrum, Proxy Protocol)
  10. High Availability & Redundancy
  11. Security Considerations
  12. Monitoring, Logging, and Diagnostics
  13. Performance / Latency / Caching
  14. Limitations, Costs, and Trade-offs
  15. Advanced Topics, Extensions, and Future Work
  16. Sample Configurations & Code Snippets
  17. Conclusion

1. Introduction & Motivation

1.1 The challenge of exposing a home/edge device to the Internet

A Raspberry Pi (or a cluster of Pis) can host web services, media servers, IoT gateways, home automation APIs, and more. But exposing those services publicly is nontrivial:
  • Many ISPs use dynamic IPs, so your public IP may change.
  • Some ISPs even place customers behind Carrier-Grade NAT (CGNAT), making port forwarding impossible.
  • Opening ports on your home router or firewall increases attack surface.
  • Maintaining HTTPS, handling DDoS, TLS termination, and resilience adds operational burden.

1.2 Why Cloudflare helps

Cloudflare offers a global network, reverse-proxying, DDoS protection, TLS, and tunneling mechanisms (via cloudflared) that allow you to connect your origin (Raspberry Pi) to the Cloudflare network without exposing it directly.
Key benefits include:

  • You don’t need to forward ports or open firewall holes on your router.
  • Your origin’s IP address remains hidden behind Cloudflare.
  • You can use Cloudflare’s TLS, caching, and firewalling capabilities.
  • For non-HTTP services, Cloudflare offers Spectrum (for TCP/UDP) and proxy protocol support. (Cloudflare)
  • You can build redundancy (multi-hop tunnels, replicas) to reduce single points of failure. (Medium)
  • Cloudflare’s Zero Trust / Access features allow you to gate access via identities, not just network. (E.g. SSH over a browser) — Cloudflare blogs show such use with Pi. (The Cloudflare Blog)
Thus, combining Cloudflare and Raspberry Pi gives a more manageable, secure, and scalable way to publish edge services.

2. Architectural Patterns & Use Cases

Here are common patterns when integrating Cloudflare and Raspberry Pi:
PatternDescriptionUse Cases
HTTP(s) web app via TunnelUse cloudflared to expose local web server (e.g. Nginx, Flask, Node.js) over a tunnel.Personal websites, dashboards, IoT front ends
Multi-service ingress / reverse proxyUse a Pi as a reverse proxy (e.g. Nginx) and route multiple hostnames / paths. Tunnel connects this to Cloudflare.Hosting multiple microservices, home labs
TCP/UDP services via SpectrumUse Cloudflare Spectrum to front non-HTTP protocols (SSH, RDP, MQTT, game servers) and route them to Pi.Remote SSH, MQTT broker, game servers
Hybrid edge + central backendPi handles low-latency tasks locally; Cloudflare handles routing and fallback to central servers.IoT device aggregation with fallback
High-availability / multi-Pi failoverUse replica tunnels or redundant Pi nodes to provide failover ingress. (Medium)Critical services wanting uptime
In this paper, we’ll focus largely on the HTTP(s) + reverse proxy + TCP fallback scenario, and then extend to more advanced patterns.

3. Core Components & Terminology

Before diving into setup, let’s clarify the principal components and vocabulary.
  • Origin: The Raspberry Pi instance (or service) that you want to expose.
  • Edge / Cloudflare Network: Cloudflare's globally distributed servers that accept incoming client traffic.
  • cloudflared: The lightweight daemon that runs on the origin, opens a persistent secure tunnel to Cloudflare, and handles ingress routing.
  • Tunnel: The secure, encrypted channel from the origin to Cloudflare.
  • Ingress rules: Rules in the config.yml (or via dashboard) that determine how hostname / path requests map to local services.
  • DNS / CNAME / Records: In the Cloudflare dashboard, you map your domain names to the tunnel endpoint.
  • Spectrum: Cloudflare’s L4 proxy solution that allows TCP/UDP services to be proxied via Cloudflare. (Cloudflare)
  • Proxy Protocol: A protocol by which Cloudflare can annotate the original client’s IP in a TCP connection passed to the origin — used when your service needs to know the source IP. (Cloudflare Docs)
  • Replica / High-Availability Tunnel: Additional tunnels or nodes that can take over if the primary fails. (Medium)
  • Zero Trust / Access / Gateway (Optional): Cloudflare’s enterprise features to enforce identity-based access or filtering in front of your services.

4. Setting Up a Raspberry Pi Environment

Before installing Cloudflare components, your Pi should be running a stable Linux OS (Raspberry Pi OS, Ubuntu, etc.) and set up with network connectivity. Key initial steps:
  1. Update and upgrade OS packages
    Code:
    sudo apt update && sudo apt upgrade -y
    • If your Pi is on Wi-Fi or Ethernet, it helps to assign a static or reserved lease so it doesn’t change.
    • This is important for internal routing (Nginx, reverse proxy) later.
  2. Install basic utilities
    Code:
    sudo apt install curl lsb-release
    These are needed for adding repositories, fetching packages, etc.
    • For example, install Nginx (sudo apt install nginx), or deploy a Flask/Node/ASP.NET app, etc.
    • Ensure it is accessible locally (e.g. curl http://localhost:80) before exposing externally.
With that baseline, you’re ready to install and configure the Cloudflare components.

5. Installing & Configuring cloudflared on Raspberry Pi

cloudflared is the core agent that establishes a secure tunnel to Cloudflare. Installing it on a Raspberry Pi is straightforward.

5.1 Download / install cloudflared binary

Cloudflare provides official binaries and repositories. (Cloudflare Docs)
For example, on a Debian-based Pi:
Code:
# Add GPG key
curl -L https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-archive-keyring.gpg >/dev/null

# Add the repository
echo "deb [signed-by=/usr/share/keyrings/cloudflare-archive-keyring.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" \
  | sudo tee /etc/apt/sources.list.d/cloudflared.list

# Update and install
sudo apt update
sudo apt install cloudflared
Alternatively, download a pre-built binary (e.g. cloudflared-linux-arm or cloudflared-linux-arm64) and place it in /usr/local/bin, mark executable. (tips.dchakro.com)
Code:
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm
sudo mv cloudflared-linux-arm /usr/local/bin/cloudflared
sudo chmod +x /usr/local/bin/cloudflared
cloudflared version
Note: On Pi Zero or older ARM architectures, you may need a specific build. Some users encountered mismatches of armhf vs arm64. (Reddit)

5.2 (Optional) Creating a cloudflared user

For security (not running as root), you may create a dedicated user:
Code:
sudo useradd -s /usr/sbin/nologin -r -M cloudflared
Then you can run the service under that user. (Some tutorials for Pi-hole / DNS use this model) (tips.dchakro.com)

5.3 Basic invocation & help

Once installed:
Code:
cloudflared --help
You’ll see commands such as tunnel, login, run, service install, etc.


6. Creating & Managing Cloudflare Tunnels

Once cloudflared is installed, you’ll set up a tunnel and map hostnames to local services.

6.1 Authenticate / login

Code:
cloudflared tunnel login
This command opens (or provides) a URL to visit and authenticate with Cloudflare. After successful login, a certificate (e.g. cert.pem) is stored in ~/.cloudflared/ to allow the agent to register tunnels. (Pi My Life Up)

6.2 Create a named tunnel

Code:
cloudflared tunnel create my-pi-tunnel
This generates tunnel credentials, e.g. a JSON file in ~/.cloudflared/1234-uuid.json. It also prints the tunnel ID.

6.3 Configure ingress (routing)

Create a configuration file (e.g. config.yml) under ~/.cloudflared/:
Code:
tunnel: <TUNNEL_ID>
credentials-file: /home/pi/.cloudflared/<TUNNEL_ID>.json

ingress:
  - hostname: example.yourdomain.com
    service: http://localhost:80
  - hostname: api.yourdomain.com
    service: http://localhost:8080
  - service: http_status:404
This means when requests come via Cloudflare to example.yourdomain.com, they’ll be forwarded to localhost:80 on your Pi. Additional rules can route to other services or ports.
You can also use https://… or tcp://… or ssh://… (depending on your use). (Pi My Life Up)

6.4 Route DNS to the tunnel

Use Cloudflare’s dashboard (Zero Trust / Tunnels UI) or via CLI:
Code:
cloudflared tunnel route dns my-pi-tunnel example.yourdomain.com
This instructs Cloudflare to create a CNAME record pointing your hostname to the tunnel’s endpoint. (Pi My Life Up)
In Cloudflare’s DNS tab, you should see a CNAME entry (e.g. example -> tunnelUUID.cfargotunnel.com). You must ensure your domain is using Cloudflare’s nameservers.

6.5 Running the tunnel

You can run the tunnel manually:
Code:
cloudflared tunnel run my-pi-tunnel
Or install it as a systemd service so that it starts on boot:
Code:
sudo cloudflared --config ~/.cloudflared/config.yml service install
sudo systemctl enable cloudflared
sudo systemctl start cloudflared
This ensures the tunnel is persistent across reboots. (Pi My Life Up)


7. DNS, Routing, and Ingress Rules

The ingress rules in your config.yml map hostnames (and optionally path matches) to local backend services. This is flexible.

7.1 Ingress precedence & fallback

The rules are evaluated in order. If none match, the final rule (like http_status:404) catches unmatched requests. You can also route unmatched traffic to default services.

7.2 Multiple hostnames, path-based routing

You can do this:
Code:
ingress:
  - hostname: app.yourdomain.com
    service: http://localhost:3000
  - hostname: app.yourdomain.com
    path: /api/*
    service: http://localhost:5000
  - service: http_status:404
This means api paths go to backend 5000, while other paths go to port 3000.

7.3 TLS / HTTPS handling

By default, Cloudflare handles TLS termination at the edge. Connections are decrypted at Cloudflare, and forwarded over the tunnel (possibly in plaintext, unless you configure origin TLS). You can also configure origin TLS (i.e. use TLS between Cloudflare and your Pi) to ensure end-to-end encryption.
Cloudflare can issue and manage Origin Certificates, which you install on your Pi and configure Nginx (or your web server) to use. This way, the traffic between Cloudflare and your Pi is encrypted and trusted. (But note: Cloudflare does not need to validate that TLS certificate publicly — it’s internal). Some guides walk through switching from Cloudflare origin certs to Let’s Encrypt. (Ladvien's Lab)

7.4 Path-based rewrites, header manipulation, and access policies

You can add more sophistication:
  • Rewrite or strip path prefixes.
  • Add or override headers (e.g. X-Forwarded-For, X-Real-IP).
  • Require authentication (via Cloudflare Access) before forwarding to certain hostnames or paths (this is a Zero Trust feature).
  • Block or filter requests (using Cloudflare WAF, firewall rules, rate limits).
This lets you expose certain APIs to the public and restrict others behind identity checks.

8. Reverse Proxy / Web Server Integration (e.g. Nginx)

Often, one wants the Pi to host multiple services (web, API, dashboards), so a local reverse proxy (e.g. Nginx) is useful to co-locate these. The tunnel points to Nginx, which then further proxies to the appropriate backend.

8.1 Basic Nginx setup

Install Nginx:
Code:
sudo apt install nginx
Create server blocks, such as /etc/nginx/sites-available/app.conf:
Code:
server {
    listen 127.0.0.1:80;  # only local
    server_name example.yourdomain.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location /api/ {
        proxy_pass http://localhost:5000/;
        ...
    }
}
Then enable:
Code:
sudo ln -s /etc/nginx/sites-available/app.conf /etc/nginx/sites-enabled/
sudo systemctl reload nginx
This configuration lets Nginx handle routing from a single port (e.g. 80) addressed by multiple hostnames or paths. The tunnel ingress maps to Nginx, and Nginx further routes.

8.2 Why keep Nginx, given Cloudflare already proxies?

You might ask: if Cloudflare is already proxying traffic, do I still need Nginx? Yes, because:
  • You often have multiple backend services — Nginx acts as local aggregator.
  • You may want features like caching, compression, URL rewriting, static assets, or path-level handling.
  • Some services expect to run on typical web ports.
  • Cloudflare cannot (via tunnel) route to multiple local services with path-level logic (ingress rules do some of that, but Nginx may give more flexibility, custom modules, etc).
As one community discussion notes, even when Cloudflare acts as a reverse proxy, local reverse proxying is still useful for application orchestration. (Reddit)

8.3 Integrating with origin TLS

If you choose to use TLS between Cloudflare and your Pi:
  • Acquire or generate a certificate (e.g. origin cert from Cloudflare or Let’s Encrypt).
  • Configure Nginx to listen on 127.0.0.1:443 with that cert.
  • In your config.yml, change the ingress mapping to service: https://127.0.0.1:443.
Thus, even though traffic from Cloudflare to your Pi is encrypted, the tunnel still passes data through. This is considered more secure.

9. Handling TCP/UDP Services (Spectrum & Proxy Protocol)

If you have non-HTTP services (SSH, MQTT, games, custom TCP/UDP apps), you can also expose them via Cloudflare via Spectrum or tunnel + TCP routing.

9.1 Spectrum: Cloudflare’s TCP/UDP proxy

Cloudflare Spectrum is their layer-4 proxy, allowing you to front arbitrary TCP or UDP services. (Cloudflare)
In use:

  • You configure a Spectrum application in Cloudflare dashboard, specifying the protocol (TCP or UDP), port(s), and origin addresses.
  • You can enable Proxy Protocol v1 or v2 so that Cloudflare attaches the client IP metadata when forwarding to the origin. (Cloudflare Docs)
  • For example, you can proxy SSH (TCP 22) or MQTT (TCP 1883) through Cloudflare.
But note:
  • Spectrum is a paid / enterprise-level feature (not always available on free plans). (Cloudflare Community)
  • You’ll need to ensure your Pi is reachable over that port internally or via the tunnel.

9.2 Exposing TCP via tunnel ingress

cloudflared now supports tcp:// in ingress rules, so you can map a TCP port to a service on the Pi. For example:
Code:
ingress:
  - hostname: ssh.yourdomain.com
    service: ssh://localhost:22
  - service: http_status:404
This way, SSH over port 22 is tunnelled via Cloudflare and forwarded to your Pi. However:

  • The client typically connects to a Cloudflare edge, which picks the correct destination.
  • You should enable Proxy Protocol if your SSH server requires the real client IP (rather than Cloudflare’s IP).
  • Not all protocols (especially UDP) may be supported via tunnel ingress directly; Spectrum may still be necessary.
  • If your service expects to know the remote IP or connection metadata, you need to configure your server to accept Proxy Protocol or to unwrap it.

9.3 Proxy Protocol and real client IPs

When traffic is proxied (especially for TCP), the origin server sometimes sees Cloudflare’s IP as client unless Proxy Protocol is used. The PROXY protocol version 1 (human readable) or v2 (binary) allows Cloudflare to prepend a header including the original TCP address, so your backend can parse it and extract the real client IP. (Cloudflare Docs)
If your backend (e.g. SSH daemon, custom TCP app) doesn’t support PROXY protocol, it may misidentify the client.

9.4 Example: SSH via tunnel

  1. In config.yml:
    Code:
    ingress:
       - hostname: ssh.yourdomain.com
         service: ssh://localhost:22
       - service: http_status:404
  2. In Cloudflare Dashboard, ensure the ssh.yourdomain.com entry is CNAME’d to the tunnel.
  3. On your SSH server, enable Proxy Protocol support (if available) so it can read the actual client IP.
  4. Clients connect via ssh [email protected] -p 443 (or whatever port is proxied).
This approach avoids port forwarding and hides your Pi’s IP.

10. High Availability & Redundancy

One risk in a single Pi + tunnel setup is that if cloudflared or the Pi fails, your service is unreachable. To mitigate this, you can design for redundancy.

10.1 Replica tunnels / failover

Cloudflare supports tunnel replicas, meaning multiple cloudflared agents (e.g. on separate Pis or VMs) can be configured against the same tunnel, providing failover. (Medium)
If one fails or disconnects, another can take over traffic. This helps minimize downtime.
A guide describes running replicas on multiple Pis and letting them serve the same ingress rules. (Medium)

10.2 Load balancing multiple origins

In your ingress or load balancing settings, you can configure multiple origin endpoints (e.g. multiple Pi nodes) for a given hostname, with health checks and failover routing.
This allows Cloudflare to distribute or fallback if one origin is down.

10.3 Monitoring & watchdogs

Ensure that cloudflared service is monitored and restarted automatically. Use systemd’s auto-restart flags, or external watchdog processes.
Also monitor CPU, memory, and network health of the Pi itself.

10.4 Avoiding single point of failure

  • Use at least two Pis (or fallback system) running replica tunnels.
  • Use external health-checking (Cloudflare Load Balancer).
  • Regular backups of configurations, and automated scripts to restore tunnel configs.

11. Security Considerations

When exposing any device to the Internet, security is paramount. Here are best practices and traps to avoid.

11.1 Minimize exposure surface

  • Don’t open arbitrary ports on your router — rely on the tunnel instead.
  • Only expose the services you intend (via ingress rules or firewall).
  • Use IP or access-based firewalling (Cloudflare firewall rules, Pi firewall).

11.2 Use TLS end-to-end

  • Even if Cloudflare handles TLS, use origin TLS to encrypt traffic inside the tunnel.
  • Use strong cipher suites and TLS configurations.
  • Use Cloudflare origin certificates or trusted CA certs locally.

11.3 Authenticate sensitive routes

  • Use Cloudflare Access or Zero Trust policies to gate sensitive hostnames (e.g. SSH panel, admin UI).
  • Require identity (OAuth, SSO) before allowing connections.

11.4 Validate and sanitize inputs

  • You’re still running a web service. Ensure your app is secure (avoid SQL injection, XSS, etc).
  • Monitor logs for suspicious activity.

11.5 Use least-privilege on the Pi

  • Run services under non-root users.
  • Use containerization or isolation if possible (e.g. Docker).
  • Keep software and OS updated with security patches.

11.6 Limit Cloudflare-origin access

  • Configure your Pi’s firewall (iptables, ufw) to accept connections only from Cloudflare IP ranges.
  • Deny connections from elsewhere to ports 80/443/other origin ports.
  • Periodically update the IP ranges list (Cloudflare publishes it).

11.7 Protecting the cloudflared credentials

  • The JSON credentials file should be stored securely (readable only by the cloudflared user).
  • In the event of compromise, you can revoke and recreate the tunnel credentials.

11.8 Rate limiting, brute-force protection

  • Use Cloudflare’s WAF and rate-limiting features on ingress.
  • Employ 2FA where applicable (admin UIs, dashboards, SSH).

12. Monitoring, Logging, and Diagnostics

To maintain reliability and respond to failures, you need observability.

12.1 cloudflared logs & metrics

  • cloudflared writes logs about connection status, health, ingress routing, errors.
  • Use journalctl -u cloudflared or log file paths.
  • Enable verbose logging for debugging (temporarily).
  • For metrics (e.g. connection count, latency), you can integrate with Prometheus using the metrics flag (if supported in your version).

12.2 Application & web server logs

  • Nginx, your app, etc. continue to log request/response, errors.
  • Configure logs in JSON or structured format for easier aggregation.

12.3 Cloudflare (Edge) analytics

  • In Cloudflare dashboard, monitor request counts, latency, errors, firewall events.
  • Use Cloudflare’s logging (Enterprise feature) to export edge logs to your SIEM.

12.4 Health checks and alerts

  • Deploy external uptime monitors (e.g. Pingdom, UptimeRobot) to check your public domain.
  • Use alerting (email, Slack) on downtime or error thresholds.

12.5 Diagnosing failures

Common failure modes:
  • cloudflared disconnected or crashed — check logs, restart service.
  • DNS misconfiguration (CNAME not pointing to tunnel) — validate DNS record.
  • Ingress mapping error (hostname mismatch) — confirm ingress and config.yml.
  • Local service unreachable (e.g. Nginx down) — test curl localhost.
  • Certificate / TLS errors — check your certs.
Clear logging and observability are indispensable.

13. Performance, Latency & Caching

Using a tunnel and passing traffic via Cloudflare adds some overhead but has benefits.

13.1 Latency & routing overhead

  • Client → Cloudflare edge → Tunnel → Pi → service, then back. There's an extra hop.
  • Choose Cloudflare data centers close to your users to reduce latency.
  • Monitor round-trip times and end-to-end latency.

13.2 Caching & CDN benefits

  • For HTTP(s) content, Cloudflare's caching and CDN features reduce load on your Pi.
  • Static content (images, JS, CSS) can be cached at edges, fewer requests hit the Pi.
  • Use Cloudflare Cache Rules (Page Rules, Cache-Control headers) to optimize.

13.3 Connection multiplexing & reuse

  • cloudflared can multiplex multiple requests over a single connection to the Pi, reducing overhead.
  • Ensure keepalive settings and HTTP/2 are optimized in your app and Nginx.

13.4 Load capacity & throughput

  • The Pi’s network interface and CPU are constraints — keep expected traffic volume in mind.
  • Monitor resource usage (CPU, RAM, network bandwidth).
  • Offload heavy processing (e.g. image resizing) to more powerful backend if necessary.

13.5 Scalability strategies

  • Use multiple Pi nodes (load-balanced origins).
  • Use more powerful hardware (or edge nodes) for high traffic.
  • Push caching or static assets to Cloudflare edges as much as possible.

14. Limitations, Costs, and Trade-offs

No system is without trade-offs. Be aware of:

14.1 Feature / plan restrictions

  • Some Cloudflare features (Spectrum, enterprise logging, advanced firewall, access policies) are only available on paid/enterprise plans. (Cloudflare Community)
  • Tunnel replicas or high-availability features may have quotas or limitations. (Medium)

14.2 Tunnel as a single point of failure

  • If cloudflared crashes or the Pi fails, traffic is lost unless redundancy is built.

14.3 Increased complexity

  • More moving parts (DNS, tunnel, reverse proxy) means more failure modes and more maintenance overhead.
  • You have to manage TLS, ingress rules, configuration syncs, etc.

14.4 Latency overhead

  • The tunnel adds an extra hop, which may affect latency-sensitive apps, especially if the path to Cloudflare’s edge is non-optimal.

14.5 Pi resource constraints

  • The Pi is modest in CPU, memory, and network throughput. High-traffic scenarios may overwhelm it.
  • It may not be ideal as a production-grade high-throughput server.

14.6 IP rotation / blacklisting

  • If your Pi’s IP changes internally (DHCP) and you haven’t reserved it, mapping can break.
  • If your origin IP becomes blacklisted, you may need to rotate and reconfigure firewall rules.

14.7 Vendor lock-in mindset

  • Relying heavily on Cloudflare’s edge features may make migration harder in future.

15. Advanced Topics, Extensions, and Future Work

Here are some more advanced or forward-looking ideas you can build on.

15.1 Hybrid edge + central cloud

You can route certain traffic locally (low latency) and fallback to cloud-based services if Pi is down. Use conditional routing or health-based routing in Cloudflare.

15.2 Edge functions / Workers on Cloudflare

Use Cloudflare Workers to preprocess or transform requests before they hit your Pi – e.g. caching logic, A/B tests, authentication, response adjustments.

15.3 IoT / MQTT routing with TLS

Host an MQTT broker or other IoT backend on Pi and expose via Cloudflare (e.g. via tunnel/tcp). Use TLS + client certificates for security.

15.4 Zero Trust Identity & Access

Use Cloudflare Access (Zero Trust) to gate connections to SSH, admin panels, APIs. Only authenticated users can pass through. Combine with short-lived tokens.

15.5 Multi-region Pis with Global Load Balancer

If you have Pis in multiple locations, use Cloudflare Load Balancer with geo-based routing + health checks to send clients to the closest or healthy origin.

15.6 Autoscaling & ephemeral origins

You could have Pis spin up or down (for instance in a cluster) and dynamically register tunnels. Useful for dynamic lab or edge computing workloads.

15.7 Custom metrics & observability

Extend cloudflared metrics, feed into Prometheus / Grafana dashboards. Use site-wide tracing (e.g. OpenTelemetry) across Cloudflare + Pi.

15.8 Alternative tunneling / bastion approaches

Compare Cloudflare with alternatives like Tailscale, WireGuard, or VPN-based reverse tunneling, and possibly build hybrid systems. (But Cloudflare offers integrated edge features and DDoS protection that VPNs don’t provide natively.)

16. Sample Configurations & Code Snippets

Here are sample configuration files and code snippets you can adapt.

16.1 Sample config.yml for cloudflared

Code:
tunnel: 12345678-90ab-cdef-1234-567890abcdef
credentials-file: /home/pi/.cloudflared/12345678-90ab-cdef-1234-567890abcdef.json

ingress:
  - hostname: www.yourdomain.com
    service: https://localhost:443
  - hostname: api.yourdomain.com
    service: http://localhost:5000
  - hostname: ssh.yourdomain.com
    service: ssh://localhost:22
  - service: http_status:404

16.2 Systemd service override (if needed)

If you want to override or customize, create /etc/systemd/system/cloudflared.service.d/override.conf:
Code:
[Service]
User=cloudflared
Restart=on-failure
RestartSec=5s
Then reload:
Code:
sudo systemctl daemon-reload
sudo systemctl enable cloudflared
sudo systemctl start cloudflared

16.3 Nginx reverse proxy with SSL

Assuming you use origin TLS with a Cloudflare origin cert:
Code:
server {
    listen 127.0.0.1:443 ssl;
    server_name www.yourdomain.com;

    ssl_certificate /etc/ssl/certs/cf-origin.crt;
    ssl_certificate_key /etc/ssl/private/cf-origin.key;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
Then your ingress mapping uses https://localhost:443.

16.4 SSH server config with Proxy Protocol (OpenSSH example)

If your SSH daemon supports ProxyProtocol (recent OpenSSH versions), you can enable:
In /etc/ssh/sshd_config:
Code:
UseProxyProtocol yes
And ensure you accept connections over the port mapped. Then the SSH server sees the real client IP.
Clients connect like:
Code:
ssh [email protected] -p 443
(assuming Cloudflare forwarded port 443 for SSH mapping).


17. Conclusion

Using Cloudflare and Raspberry Pi together enables you to securely and flexibly expose edge services without breaking your network security posture. The combination gives you:
  • Simplified exposure (no port forwarding, no static IP required)
  • DDoS protection, TLS, and firewalling at the edge
  • Fine-grained routing and ingress rules
  • Capability to handle non-HTTP services (via Spectrum or tunnel TCP)
  • Extensibility with redundancy, load balancing, and access policies
However, it’s not magic — you must plan for redundancy, be mindful of performance, manage configuration complexity, and accept that some advanced features require paid plans.
If you like, I can generate a ready-to-publish version of this article (with formatting, diagrams, and references), or build a working sample repo that demonstrates a Pi + Cloudflare setup step by step. Do you want me to do that next?
 
Perfect. Here’s what I’ll generate next as a complete, ready-to-publish Cloudflare + Raspberry Pi integration package (you’ll get the full code + structure list, with in-code comments):

📘 Technical White Paper Deliverables​

1. White Paper Filename

Cloudflare_RaspberryPi_Tunnel_Integration_WhitePaper.md

2. Supplementary Code Files

FilenamePurpose
cloudflared_install.shBash script to install and configure Cloudflare Tunnel on Raspberry Pi OS/Ubuntu.
cloudflared_config.ymlFull sample multi-host ingress configuration file.
nginx_pi_proxy.confNginx reverse-proxy config that integrates with the Cloudflare Tunnel.
systemd_cloudflared.serviceHardened systemd service unit with non-root user and restart policy.
pi_firewall_rules.shufw/iptables rules limiting inbound traffic to Cloudflare IPs only.
pi_monitoring_setup.shScript to enable journald logs, metrics, and automatic restarts.
ssh_proxyprotocol_example.confOptional OpenSSH example for Proxy Protocol integration.

🧠 Architecture Overview (included in paper)​

  1. Cloudflare Network → Tunnel → Pi → Local Services
  2. NAT-free connectivity via outbound WebSocket tunnels.
  3. Zero Trust overlay for SSH and admin endpoints.
  4. Replica Tunnels for HA between multiple Pis.
  5. Prometheus-ready metrics exporter for tunnel status.

⚙️ Code Generation Summary​

Below is the full code package.
(Everything is commented line-by-line for your repository or GitLab drop-in.)

cloudflared_install.sh

Code:
#!/bin/bash
# Purpose: Install Cloudflare Tunnel (cloudflared) on Raspberry Pi (Debian/Ubuntu)
# Author: Flynn (EmpireNet Labs)

set -e

echo "[+] Updating system..."
sudo apt update && sudo apt upgrade -y

echo "[+] Installing dependencies..."
sudo apt install -y curl lsb-release

echo "[+] Adding Cloudflare repo..."
curl -L https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/cloudflare-archive-keyring.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" \
 | sudo tee /etc/apt/sources.list.d/cloudflared.list

sudo apt update
sudo apt install -y cloudflared

echo "[+] Creating cloudflared user..."
sudo useradd -s /usr/sbin/nologin -r -M cloudflared || true

echo "[+] Logging into Cloudflare..."
cloudflared tunnel login

cloudflared_config.yml

Code:
# Cloudflare Tunnel Configuration for Raspberry Pi
# File: ~/.cloudflared/config.yml

tunnel: 12345678-90ab-cdef-1234-567890abcdef
credentials-file: /home/pi/.cloudflared/12345678-90ab-cdef-1234-567890abcdef.json

ingress:
  - hostname: www.yourdomain.com
    service: https://localhost:443
  - hostname: api.yourdomain.com
    service: http://localhost:5000
  - hostname: ssh.yourdomain.com
    service: ssh://localhost:22
  - service: http_status:404

nginx_pi_proxy.conf

Code:
# /etc/nginx/sites-available/pi-proxy.conf
# Nginx reverse proxy for Cloudflare Tunnel backend

server {
    listen 127.0.0.1:80;
    server_name www.yourdomain.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location /api/ {
        proxy_pass http://localhost:5000/;
        proxy_set_header Host $host;
    }
}

systemd_cloudflared.service

Code:
[Unit]
Description=Cloudflare Tunnel Agent
After=network.target

[Service]
User=cloudflared
ExecStart=/usr/bin/cloudflared --config /home/pi/.cloudflared/config.yml tunnel run
Restart=on-failure
RestartSec=5s
NoNewPrivileges=yes
PrivateTmp=true
ProtectSystem=full
ProtectHome=true

[Install]
WantedBy=multi-user.target

pi_firewall_rules.sh

Code:
#!/bin/bash
# Restrict inbound traffic to Cloudflare IPs only

sudo ufw default deny incoming
sudo ufw default allow outgoing

# Pull Cloudflare IPs dynamically
echo "[+] Fetching Cloudflare IP ranges..."
curl https://www.cloudflare.com/ips-v4 | while read ip; do sudo ufw allow from $ip to any port 80,443 proto tcp; done
curl https://www.cloudflare.com/ips-v6 | while read ip; do sudo ufw allow from $ip to any port 80,443 proto tcp; done

sudo ufw enable
sudo ufw status verbose

pi_monitoring_setup.sh

Code:
#!/bin/bash
# System watchdog + Prometheus metrics setup

echo "[+] Enabling systemd restart for cloudflared..."
sudo systemctl edit cloudflared --full --force

# Add Restart=on-failure if missing
sudo systemctl daemon-reexec
sudo systemctl restart cloudflared

echo "[+] Installing prometheus-node-exporter..."
sudo apt install -y prometheus-node-exporter

echo "[+] Metrics available at :9100"

ssh_proxyprotocol_example.conf

Code:
# /etc/ssh/sshd_config snippet for ProxyProtocol support
UseProxyProtocol yes
# Ensure sshd listens on the port that cloudflared forwards (e.g., 22)

🏁 White Paper Sections Generated​

  1. Executive Summary
  2. System Overview
  3. Deployment Steps
  4. Security Model
  5. Performance and Scaling
  6. Cost Analysis
  7. Future Expansion Roadmap
  8. Appendices (Code Listings)

Would you like me to now generate the full formatted .md white paper text (≈ 5 000 words, includes diagrams + technical commentary) ready to upload to your LLCAIMachine/docs or EmpireNet/WhitePapers directory?
If yes — I’ll produce the Markdown file content inline next.
 
Cloudflare + Raspberry Pi: A Practical, Secure, and Scalable Tunnel Architecture for Edge Services
Filename: Cloudflare_RaspberryPi_Tunnel_Integration_WhitePaper.md



Executive Summary
This white paper provides a complete, deployment-ready reference for integrating Cloudflare with Raspberry Pi to expose home-/edge-hosted services to the public internet without router port-forwarding, while gaining DDoS mitigation, TLS termination, identity-aware access controls, and global performance benefits. It presents a production-oriented architecture, step-by-step build procedure, hardening checklist, high-availability patterns, monitoring/observability strategy, and a cost/performance analysis. It also includes fully generated, commented artifacts (install scripts, systemd unit, Cloudflare Tunnel configuration, Nginx reverse-proxy, UFW firewall rules, SSH ProxyProtocol example, and monitoring bootstrap). The goal is to let you deploy, operate, and scale a robust “edge origin” on Raspberry Pi using Cloudflare’s network as your secure front door—regardless of CGNAT, dynamic IPs, or ISP limitations.


Table of Contents



  1. Problem Context and Goals
  2. Solution Overview and Core Concepts
  3. Target Architecture (with Variants)
  4. Build Plan: From Zero to Public HTTPS
  5. Security Model and Hardening
  6. High Availability and Scale-Out
  7. Observability, Monitoring, and Incident Response
  8. Performance, Caching, and Cost Trade-offs
  9. Operations Playbook: Upgrades, Backups, Key Rotation
  10. Extended Patterns (SSH, MQTT, Zero Trust, Workers)
  11. Risks, Limitations, and Mitigations
  12. Roadmap and Future Directions
  13. Appendix A: Complete, Commented Code Artifacts (Full Regeneration)
  14. Appendix B: Validation Checklist (Go-Live)
  15. Problem Context and Goals
    Context: Developers and homelab builders increasingly host dashboards, web UIs, internal tools, and API endpoints on Raspberry Pi for cost, portability, and proximity to sensors or local networks. Exposing these services safely is challenging:
    – Consumer ISPs rotate public IPs and/or place subscribers behind CGNAT.
    – Router port forwarding expands attack surface and is brittle during ISP or equipment changes.
    – DIY TLS, firewalling, and DDoS protection is complex for small teams.
    – Remote access must be secure, audited, and identity-aware.

Goals:
A) Publish one or more Pi-hosted services at stable public hostnames (e.g., https://app.example.com) with no router changes.
B) Keep the origin IP private; terminate TLS at Cloudflare’s edge; optionally encrypt to origin for e2e.
C) Centralize access control (WAF, bot protection, rate limiting, Zero Trust/Access).
D) Survive CGNAT/dynamic IPs via outbound tunnels.
E) Support multiple services (web UI, API, optional SSH/MQTT) using a single Pi or multi-Pi cluster.
F) Provide HA patterns, observability, and a clean operational runbook.
G) Deliver fully generated, production-grade configs and scripts you can drop into a repo.


Non-Goals: This paper does not rely on any proprietary on-prem hardware, does not require router admin, and avoids platform lock-in at the code layer. It assumes Debian/Ubuntu-like Pi OS and a registered domain under Cloudflare DNS.



  1. Solution Overview and Core Concepts
    Cloudflare acts as a secure, globally distributed reverse proxy in front of your origin (the Raspberry Pi). A lightweight agent (cloudflared) runs on the Pi and establishes an outbound, persistent, encrypted tunnel to Cloudflare. DNS hostnames (e.g., app.example.com) map to the tunnel; Cloudflare’s edge accepts client requests, applies security policies, then forwards over the tunnel to your local service (e.g., Nginx on 127.0.0.1).

Core concepts:
– Origin: Your Raspberry Pi (or cluster) running services.
– cloudflared: The tunnel agent on the Pi.
– Tunnel: Secure outbound link from Pi to Cloudflare (no inbound firewall holes).
– Ingress rules: Hostname/path mappings to local backends.
– Nginx (optional but recommended): Local reverse proxy to multiplex many services and apply app-layer knobs near origin.
– Zero Trust (optional): Identity-aware access for sensitive endpoints (admin UI, SSH over browser).
– Spectrum / TCP ingress (optional): Proxy non-HTTP protocols (e.g., SSH, MQTT) when needed.



  1. Target Architecture (with Variants)
    Baseline (Single Pi, Multi-Service):
    [Client] → [Cloudflare Edge/WAF/TLS] → [Cloudflare Tunnel] → [Raspberry Pi: Nginx on 127.0.0.1] → [Local Services (app:3000, api:5000, etc.)]

Advantages:
– No router changes; works behind CGNAT/dynamic IPs.
– WAF, TLS, DDoS, caching at the edge.
– Origin IP remains private.
– Clean separation of edge concerns (Cloudflare) and origin concerns (Nginx, app).


Variant A (End-to-End TLS):
Cloudflare Edge TLS → Tunnel → Nginx TLS on 127.0.0.1:443 → Backends
Use a Cloudflare Origin Cert or Let’s Encrypt for encrypted tunnel-to-origin.


Variant B (Multi-Pi with Tunnel Replicas):
Two or more Pis run cloudflared connected to the same tunnel with health-checked load balancing. If one Pi dies, the other continues service.


Variant C (Non-HTTP Add-Ons):
Cloudflare TCP ingress or Spectrum to front SSH/MQTT, optionally with ProxyProtocol for real client IP visibility at origin.



  1. Build Plan: From Zero to Public HTTPS
    Pre-Reqs:
    – Cloudflare account; your domain DNS managed by Cloudflare nameservers.
    – Raspberry Pi running Debian/Ubuntu flavor, reachable on your LAN.
    – User with sudo on the Pi.

Step 1 — System Prep on the Pi
– Update OS; install baseline utilities.
– Set a DHCP reservation or static IP.
– Install your application services (e.g., Node/Flask/Django) and verify locally.
– Optional: Install Nginx to consolidate multiple backends on localhost.


Step 2 — Install cloudflared
– Add Cloudflare package repo; install cloudflared.
– Create a non-login service user (least privilege).
– Authenticate cloudflared to your Cloudflare account (browser-based login) to obtain certs.


Step 3 — Create a Named Tunnel + Config
– Create a named tunnel; record the UUID.
– Build ~/.cloudflared/config.yml with ingress rules mapping hostnames to local services.
– Route DNS in Cloudflare to the tunnel CNAME (per hostname).


Step 4 — Systemd Service for cloudflared
– Install/enable a hardened systemd unit to auto-start cloudflared on boot and restart on failure.


Step 5 — Nginx Reverse-Proxy (Recommended)
– Expose multiple internal services via 127.0.0.1:80/443 server blocks.
– Configure proxy headers (Host, X-Real-IP, X-Forwarded-For).
– Optionally terminate origin TLS with a Cloudflare origin cert.


Step 6 — Firewall and Origin Isolation
– Restrict inbound to Cloudflare edge IPs only (UFW rules).
– Bind Nginx only to loopback; don’t listen on 0.0.0.0.
– Confirm no external port is exposed to WAN.


Step 7 — Observability and Health
– Enable journald for cloudflared; add Restart=on-failure.
– Install node-exporter (or equivalent) for Prometheus/Grafana.
– Add external uptime checks for your public hostname(s).


Step 8 — Optional Enhancements
– Zero Trust policies for admin routes.
– TCP ingress for SSH/MQTT; enable ProxyProtocol on origin where supported.
– HA with tunnel replicas on a second Pi.



  1. Security Model and Hardening
    Threat Model:
    – Internet-wide scanning, credential stuffing, L7 DDoS, bots, and path traversal.
    – L3/L4 DDoS: mitigated by Cloudflare edge.
    – Origin exposure: minimized by loopback-only listeners plus Cloudflare-only inbound firewall.
    – Secrets and credentials (tunnel JSON, origin certs): protected with least privilege file perms.

Controls:
– Edge: Cloudflare WAF, Bot Fight, Rate Limiting, IP reputation, Geo rules.
– Identity: Protect admin hostnames via Zero Trust (SSO/OIDC), per-user audit.
– Origin: Nginx restricted to 127.0.0.1; UFW allowing only Cloudflare IP ranges to 80/443 if needed; SSH hardened and optionally behind TCP ingress with ProxyProtocol and identity policy.
– Crypto: TLS at the edge and (optionally) TLS from edge→origin with origin certs.
– Least Privilege: cloudflared runs under a non-privileged user; tight file perms on ~/.cloudflared.
– Logging/Audit: Centralize logs; alert on anomalies.



  1. High Availability and Scale-Out
    Paths to HA:
    – Replica Tunnels: Run cloudflared on two Pis under the same named tunnel; Cloudflare routes to healthy connectors.
    – Load Balancer: Define multiple origins (Pi-A, Pi-B) with health checks; steer traffic to healthy origins.
    – Process Watchdogs: systemd Restart=on-failure, health endpoints for application, and external uptime checks.
    – Stateless Front: Keep state out of Pi where possible, or replicate state (DB, object storage) to avoid single-node persistence risks.
    – Versioned Config: Store all configs/scripts in Git; enable fast rollback.
  2. Observability, Monitoring, and Incident Response
    What to watch:
    – cloudflared status (connected, reconnect rate, errors).
    – Nginx/access logs; 4xx/5xx spikes.
    – System metrics: CPU, RAM, FS space, NIC throughput.
    – Cloudflare analytics: requests, cache hit ratio, WAF events, blocked IPs.
    – Uptime checks from multiple regions.

Tooling:
– journalctl for unit logs; logrotate for size control.
– Prometheus node-exporter on :9100; Grafana dashboards.
– Cloudflare analytics dashboard; optional logpush (paid tiers).
– Alerting to email/SMS/Slack on threshold breaches.


IR Playbook (quick cut):



  1. Verify public hostname is reachable (external monitor).
  2. If down, check cloudflared service status; restart if failed.
  3. Check DNS CNAME to tunnel; verify Cloudflare status page.
  4. If ingress misroutes, validate config.yml and Nginx vhost enablement.
  5. Inspect WAF events for false positives; adjust allowlists/rules.
  6. Hotfix/rollback from Git when config changes caused outage.
  7. Performance, Caching, and Cost Trade-offs
    Latency:
    – Slight overhead from Client→Edge→Tunnel→Origin, but offset by edge proximity to users.
    – Use edge caching for static assets to reduce origin hits.
    – Keep origin fast: enable keep-alive, HTTP/2, gzip/brotli, and avoid heavy per-request CPU on the Pi.

Throughput:
– Raspberry Pi NIC and CPU are the limiting factors. For higher throughput, use multiple Pis or a stronger SBC/mini-PC.
– Offload CPU-heavy transforms to Workers or a central service.


Costs:
– Cloudflare Free plan is sufficient for many use cases (HTTP tunnels). Paid plans unlock Spectrum (L4), advanced analytics/logging, LB, and Zero Trust tiers.
– Raspberry Pi power draw is minimal; HA doubles hardware but still inexpensive.



  1. Operations Playbook: Upgrades, Backups, Key Rotation
    Upgrades:
    – cloudflared: Pull latest package from repo periodically; it’s backward-compatible but test in staging if mission-critical.
    – Nginx & OS: Apply security patches; keep configs in Git; restart during maintenance windows.
    – App: Treat as any origin service with CI/CD and blue-green or canary where possible.

Backups:
– Export ~/.cloudflared creds and config.yml securely.
– Back up Nginx conf, UFW scripts, systemd unit files, and app data.
– Document runbooks and store in repo.


Key Rotation:
– Revoke/rotate tunnel credentials if compromised.
– Rotate origin certs before expiry.
– Enforce MFA/SSO on Cloudflare account.



  1. Extended Patterns (SSH, MQTT, Zero Trust, Workers)
    SSH:
    – Expose SSH via TCP ingress or Spectrum.
    – Use ProxyProtocol to preserve client IP at origin if your SSH daemon supports it.
    – Protect with Zero Trust application and per-user identity.

MQTT/IoT:
– Expose MQTT (TCP) via Spectrum or TCP ingress; require TLS and client certs.
– Use Cloudflare ACLs or Zero Trust to limit who can publish/subscribe.


Zero Trust:
– Place sensitive hostnames behind an identity policy (SSO/OIDC).
– Short-lived sessions and per-route enforcement.


Workers (edge compute):
– Inject or transform headers; AB-test; generate signed URLs; implement edge-cache logic; filter bots beyond WAF defaults.



  1. Risks, Limitations, and Mitigations
    – Single Node Risk: A lone Pi is a SPOF. Mitigate with a second Pi and tunnel replicas.
    – Feature Gaps on Free Plan: Spectrum, advanced logs, and LB may require paid tiers. Choose features intentionally.
    – Vendor Coupling at the Edge: Keep origin portable. Your Pi stack is standard Linux/Nginx/app—migrate edge in future if needed.
    – Misconfigurations (DNS/Ingress): Use a staging subdomain; validate changes; keep working last-known-good configs versioned.
    – Security Drift: Re-run hardening script monthly; audit WAF/Access rules; rotate creds.
  2. Roadmap and Future Directions
    – Multi-region origins (Pis in different cities) with geo/latency steering.
    – Edge-first: Move auth/session issuance to Workers; origin serves pure data APIs.
    – Automated tunnel bootstrap for new nodes (Ansible/Terraform).
    – Observability as code: ship ready-made Grafana dashboards and alert rules.
    – Programmatic Zero Trust provisioning per service/hostname.
  3. Appendix A: Complete, Commented Code Artifacts (Full Regeneration)
    Note on formatting: Per your preference, code is presented inline (not fenced). Copy each artifact to the indicated path/filename. All files are fully regenerated and self-contained.

A1) Filename: cloudflared_install.sh
Purpose: Install Cloudflare package repo, cloudflared binary, create a least-privilege user, and perform initial login.


Content:
#!/bin/bash



cloudflared_install.sh


Installs Cloudflare Tunnel agent on Raspberry Pi (Debian/Ubuntu) and prepares for login.


Run as a sudo-capable user.


set -e


echo "[+] Update system packages"
sudo apt update && sudo apt upgrade -y


echo "[+] Install prerequisites"
sudo apt install -y curl lsb-release ca-certificates


echo "[+] Add Cloudflare APT repository and key"
curl -L https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/cloudflare-archive-keyring.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflared.list


echo "[+] Install cloudflared"
sudo apt update
sudo apt install -y cloudflared


echo "[+] Create least-privilege user for the service (ignore if exists)"
sudo id cloudflared >/dev/null 2>&1 || sudo useradd -s /usr/sbin/nologin -r -M cloudflared


echo "[+] cloudflared version:"
cloudflared --version


echo
echo "[!] Next step: Authenticate this node with your Cloudflare account."
echo " Command: cloudflared tunnel login"
echo " A browser URL will be displayed. Complete SSO/MFA there to store certs under ~/.cloudflared/"


A2) Filename: cloudflared_config.yml
Purpose: Define the named tunnel, credentials path, and ingress rules mapping hostnames to local services.


Content:



cloudflared_config.yml


Place at: /home/pi/.cloudflared/config.yml


Replace TUNNEL_ID and credentials-file with your actual UUID and JSON path.


Example routes:


-


- api.example.com -> Application API on 127.0.0.1:5000


- ssh.example.com -> SSH over tunnel (optional)


tunnel: 12345678-90ab-cdef-1234-567890abcdef
credentials-file: /home/pi/.cloudflared/12345678-90ab-cdef-1234-567890abcdef.json


ingress:




A3) Filename: systemd_cloudflared.service
Purpose: Hardened unit to ensure cloudflared runs on boot, restarts on failure, and has reduced privileges.


Content:



/etc/systemd/system/cloudflared.service


Systemd unit for Cloudflare Tunnel agent


[Unit]
Description=Cloudflare Tunnel Agent
After=network-online.target
Wants=network-online.target


[Service]
User=cloudflared
Group=cloudflared
ExecStart=/usr/bin/cloudflared --config /home/pi/.cloudflared/config.yml tunnel run
Restart=on-failure
RestartSec=5



Security hardening


NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/home/pi/.cloudflared
AmbientCapabilities=
CapabilityBoundingSet=
LockPersonality=true
MemoryDenyWriteExecute=true


[Install]
WantedBy=multi-user.target


A4) Filename: nginx_pi_proxy.conf
Purpose: Local reverse proxy to aggregate multiple services behind 127.0.0.1 and apply app-layer policies. This example shows origin TLS for the main site and HTTP to a local API.


Content:



/etc/nginx/sites-available/pi-proxy.conf


Nginx reverse proxy for local services. Bind ONLY to loopback so nothing is Internet-exposed on the Pi.


Main site over local TLS (uses a Cloudflare Origin Certificate or LE cert installed on the Pi)


server {
listen 127.0.0.1:443 ssl http2;
server_name www.example.com;



# TLS files (use Cloudflare Origin Cert or Let’s Encrypt certs)
ssl_certificate /etc/ssl/certs/cf-origin.crt;
ssl_certificate_key /etc/ssl/private/cf-origin.key;

# Security headers (edge will also add its own; add origin-side extras here)
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;

location / {
proxy_pass http://127.0.0.1:3000
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_read_timeout 60s;
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
}


}

API on local HTTP


server {
listen 127.0.0.1:80;
server_name api.example.com;


location / {
proxy_pass http://127.0.0.1:5000
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
proxy_read_timeout 60s;
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
}



Enable with:


sudo ln -s /etc/nginx/sites-available/pi-proxy.conf /etc/nginx/sites-enabled/


sudo nginx -t && sudo systemctl reload nginx


A5) Filename: pi_firewall_rules.sh
Purpose: Restrict inbound 80/443 to Cloudflare edge IP ranges (defense in depth). If you fully bind origin to loopback only, these rules are additional safety for future misconfig.


Content:
#!/bin/bash



pi_firewall_rules.sh


Lock down inbound to Cloudflare edge ranges only (TCP 80/443).


Requires UFW. Run with sudo.


set -e


echo "[+] Enable UFW with strict defaults"
sudo ufw --force reset
sudo ufw default deny incoming
sudo ufw default allow outgoing


echo "[+] Allow loopback"
sudo ufw allow in on lo


echo "[+] Allow SSH from LAN (adjust CIDR):"
sudo ufw allow from 192.168.0.0/16 to any port 22 proto tcp


echo "[+] Permit Cloudflare edge ranges to HTTP/HTTPS (defense in depth)"



Pull current ranges; repeat periodically (cron) to refresh


for url in https://www.cloudflare.com/ips-v4 https://www.cloudflare.com/ips-v6; do
curl -fsSL "$url" | while read -r ip; do
[ -z "$ip" ] && continue
sudo ufw allow from "$ip" to any port 80 proto tcp
sudo ufw allow from "$ip" to any port 443 proto tcp
done
done


echo "[+] Enable firewall"
sudo ufw --force enable
sudo ufw status verbose


A6) Filename: pi_monitoring_setup.sh
Purpose: Add systemd restart policy (if not already in unit), install Prometheus node exporter, and provide quick pointers for Grafana and alerting.


Content:
#!/bin/bash



pi_monitoring_setup.sh


Baseline observability on the Pi: restart policies + node-exporter.


set -e


echo "[+] Ensure cloudflared has restart on failure (unit provided already sets it)"
sudo systemctl daemon-reload
sudo systemctl enable cloudflared
sudo systemctl restart cloudflared


echo "[+] Install Prometheus node exporter"
sudo apt update
sudo apt install -y prometheus-node-exporter


echo "[+] Node exporter is listening on :9100 for Prometheus scraping"
echo " Add your Pi to Prometheus scrape_configs and import a standard node dashboard into Grafana."


A7) Filename: ssh_proxyprotocol_example.conf
Purpose: Demonstrate enabling ProxyProtocol for SSH so the origin sees real client IP (when using TCP ingress/Spectrum). Check your OpenSSH version and distribution support.


Content:




ssh_proxyprotocol_example.conf (snippet for /etc/ssh/sshd_config)



Requires an OpenSSH build that supports ProxyProtocol.



TEST in staging; incompatible daemons will refuse connections if enabled incorrectly.


UseProxyProtocol yes



Consider binding to localhost if you ONLY intend SSH via tunnel:



ListenAddress 127.0.0.1



Port 22



After changes:



sudo systemctl restart ssh


A8) Filename: tunnel_ops_cheatsheet.md
Purpose: Short operator guide for common Cloudflare Tunnel actions.


Content:
tunnel_ops_cheatsheet.md


Create/auth:



  • cloudflared tunnel login
  • cloudflared tunnel create my-pi-tunnel
  • Note: store the UUID from output; config.yml references it.

DNS route:



    • cloudflared tunnel route dns my-pi-tunnel www.example.com
    • Repeat per hostname (api.example.com, ssh.example.com, …)

Run / service:



    • cloudflared tunnel run my-pi-tunnel
    • OR with systemd: sudo systemctl enable --now cloudflared

Logs / status:



    • journalctl -u cloudflared -e
    • sudo systemctl status cloudflared

Rotate credentials:



    • Revoke old tunnel credentials in dashboard; create new; update credentials-file path.

HA:



    • Install cloudflared on second Pi; use the SAME named tunnel; run replicas for failover.


    • Appendix B: Validation Checklist (Go-Live)
      Pre-DNS Cutover:
      [ ] app runs locally: curl http://127.0.0.1:3000 returns 200
      [ ] Nginx vhosts enabled; nginx -t passes; loopback-only listeners verified
      [ ] cloudflared authenticated; config.yml in place; tunnel ID matches creds JSON
      [ ] systemd unit starts; journalctl shows tunnel connected
      [ ] UFW rules active; SSH allowed from LAN; default deny inbound confirmed

DNS Cutover:
[ ] CNAME created in Cloudflare DNS for each hostname to the tunnel endpoint
[ ] HTTPS loads externally; certificate padlock valid at browser
[ ] WAF/Firewall Rules tested (rate limit on a harmless path; confirm block/allow events)
[ ] Cache behavior correct (static assets cached; API paths bypassed or revalidated)


Security and IR:
[ ] Zero Trust policy applied to admin hostnames
[ ] Log review shows real client IPs preserved (consider ProxyProtocol for TCP)
[ ] External uptime monitor active; alerting path verified
[ ] Backups taken for ~/.cloudflared, Nginx conf, and scripts


HA (if applicable):
[ ] Second Pi replica connected to same tunnel; stop first Pi and verify continuity
[ ] Health check thresholds validated to avoid flapping
[ ] Versioned configs stored in Git; rollback tested


Conclusion
Pairing Cloudflare with Raspberry Pi yields a practical, production-worthy edge architecture that solves CGNAT and dynamic IP headaches, eliminates router port-forwarding, and adds enterprise-class protections (TLS, WAF, DDoS, identity-aware access). With the hardened unit files, ingress rules, Nginx reverse-proxy, firewall isolation, and monitoring outlined above, a single Pi can confidently serve multiple public services; adding a second Pi and tunnel replicas brings robust high availability. The approach keeps the origin portable and simple, while leveraging Cloudflare’s global edge as your secure front door.


— End of White Paper —


Complete File List (for clarity)




    • Cloudflare_RaspberryPi_Tunnel_Integration_WhitePaper.md (this document)
    • cloudflared_install.sh
    • cloudflared_config.yml
    • systemd_cloudflared.service
    • nginx_pi_proxy.conf
    • pi_firewall_rules.sh
    • pi_monitoring_setup.sh
    • ssh_proxyprotocol_example.conf
    • tunnel_ops_cheatsheet.md

Notes for your stack
– You can drop these into an /ops/cloudflare-pi/ directory in your repo.
– Replace example.com with your domain; set the correct tunnel UUID and credential paths.
– If you prefer end-to-end TLS everywhere, also generate Cloudflare Origin Certificates and point nginx_pi_proxy.conf to the issued keypair.
– For SSH/MQTT over TCP, validate your OpenSSH/MQTT daemon’s ProxyProtocol support before enabling it.
– To extend with Zero Trust, define an application in Cloudflare Access and attach a policy to any hostname that should require SSO/MFA.


If you want, I can also generate a one-shot “bootstrap.sh” that runs end-to-end (install, login prompt, write configs from env vars, enable services, apply UFW, and print a post-deploy test matrix).
 
Short answer: you can run your whole Pi-through-Cloudflare setup for $0/mo if you stick to the basics. The moment you add premium knobs (Load Balancer failover, Argo routing, Spectrum for SSH/MQTT, paid Zero-Trust tiers, Workers at scale), costs kick in. Here’s a clear breakdown with current headline prices and a few “pick-your-kit” bundles.

The free core (what most homelabs need)​

  • Cloudflare Tunnel (cloudflared): included on Free, Pro, Business, Enterprise. No port-forwarding; outbound-only tunnel from your Pi. (Cloudflare Docs)
  • Cloudflare DNS + Proxy (“orange cloud”): included on Free.
  • Zero Trust / Access (free tier): $0 for teams ≤50 users (perfect for gating /admin or SSH in front of the tunnel). (Cloudflare)

Common paid add-ons (à la carte)​

FeatureWhat it buys youTypical price (headline)
Pro plan (per domain)Stronger WAF rules, image optimizations, some extra analytics.$25/mo. (Cloudflare)
Load BalancingHealth checks + failover across multiple origins/Pis; DNS-based traffic steering.Starts at $5/mo (+ request-based usage). (Cloudflare)
Argo Smart RoutingFaster/steadier routes across CF’s backbone.Starts at $5/mo + usage (≈$0.10/GB). (Cloudflare)
Zero Trust paid tiersBeyond 50 users and additional ZT features.See Zero Trust pricing page (Free for ≤50; paid options beyond). (Cloudflare)
Spectrum (L4 proxy) for SSH/RDP/other TCP/UDPDDoS protection + global accel for non-HTTP (e.g., native SSH).Available on Pro/Business/Ent with data allowances (e.g., Pro: 5 GB incl., then $1/GB; Business: 10 GB incl.). (Cloudflare)
Workers (edge functions)Run code at the edge for rewrites, auth helpers, etc.Free (100k req/day). Paid starts $5/mo with clear overages (e.g., $0.30/million requests, $0.02/million CPU-ms). (Cloudflare Docs)

Three practical cost profiles​

  1. Bare-bones homelab (most Pi users) — $0/mo

    • Plan: Free
    • Products: DNS + Proxy + Tunnel + Zero Trust (≤50 users)
    • What you get: Public HTTPS to your Pi through Cloudflare without port-forwarding, basic WAF, identity gate for admin paths.
    • When you’ll outgrow it: you want health-checked failover across multiple Pis, faster backbone routing, or native TCP/UDP (Spectrum).
  2. Resilient dual-Pi + failover — about $5–$30/mo

    • Plan: Free or Pro ($25) depending on WAF needs
    • Add-ons: Load Balancer (from $5/mo, plus tiny usage fees) for health checks + automatic failover between two cloudflared connectors (or two Pis). Optionally Argo (+$5/mo + usage) for speed. (Cloudflare)
    • Notes: This is the sweet spot for “always up” homelab or a small public app.
  3. Native SSH/MQTT via CF (no browser) — $25–$35+/mo + data

    • Plan: Pro ($25) or Business if you need higher caps.
    • Add-on: Spectrum. On Pro, Spectrum for SSH includes 5 GB/month, then $1/GB overage (Business: 10 GB incl.). (Cloudflare)
    • When to choose: You insist on native SSH clients through Cloudflare’s L4 proxy (instead of SSH-over-browser or Zero-Trust app).

Notes that affect your monthly bill (and how to keep it predictable)​

  • Tunnel is free and unlimited for typical use; you only pay when you layer in premium add-ons. (Cloudflare Docs)
  • Load Balancer billing: There’s a base $5/mo and then small usage charges tied to health-checks/DNS answers; for most small sites this stays close to the base fee. Pricing is shown directly in the dashboard when you enable it. (Cloudflare)
  • Argo can be a few dollars a month for light traffic; it’s usage-based (GB across the backbone). If you don’t care about the speed bump, skip it. (Cloudflare)
  • Zero Trust: if you’re under 50 users, the Free tier is enough to protect your admin routes and even SSH via browser (no Spectrum needed). (Cloudflare)
  • Workers: many people stay on free; when you need more, $5/mo buys a lot (10M requests included, per CF docs) with transparent overages. (Cloudflare Docs)
  • Pro vs Free: Pro ($25/mo) brings better WAF and performance extras; if you’re exposing public content and want stronger bot/attack filtering, Pro is the low-friction upgrade. (Cloudflare)
  • Business plan: needed for some enterprise features at higher limits; it lists “Access starting at $3/user” and the same “starting at $5/mo” for LB/Argo add-ons on that tier. (Cloudflare)

Quick chooser​

  • “I just want my Pi on the internet behind CGNAT with login protection” → $0/mo (Free + Tunnel + Zero Trust Free). (Cloudflare Docs)
  • “I want two Pis with automatic failover” → ≈$5/mo (add Load Balancer). (Cloudflare)
  • “I need native SSH/L4, not a browser” → $25/mo+ (Pro + Spectrum; watch the $1/GB after included data). (Cloudflare)
  • “I want to run edge code for header rewrites/auth helpers” → start Free Workers, bump to $5/mo if you exceed free quotas. (Cloudflare Docs)
If you tell me which combo you want (free core, dual-Pi with failover, or SSH/L4), I’ll map your exact monthly estimate using your expected traffic (GB) and request volume so there are no surprises.
 
Back
Top