fairlane.systems

CLOUDFLARE · HOW-TO

Set up Cloudflare with your own domain: DNS, SSL, WAF, Workers KV and Tunnel (May 2026)

Guide from domain registration via nameserver change, SSL modes, DNS records, page rules, Workers KV, WAF rules and Cloudflare Tunnel for origin protection.

Researched & fact-checked by: · As of: 2026-05

What is this about?

This guide goes from an empty domain to a production-ready Cloudflare config. You register a domain (with a CH/EU registrar or with Cloudflare directly), switch nameservers to Cloudflare, pick the right SSL mode, set the most important DNS records, configure page rules, set up Workers KV, enable a baseline WAF setup and lock the origin behind a Cloudflare Tunnel from direct internet access.

The guide targets three audiences. First: SMEs setting up a domain new and wanting it clean from the start. Second: fiduciary and law firms migrating an existing domain to Cloudflare and tightening data protection. Third: developers needing Workers KV as a free key-value store for small applications.

Prerequisites: a domain (existing or to be registered), a Cloudflare account (the Free plan covers 90% of SME cases), an origin server behind the domain (Hetzner, AWS, Render – whichever). Setup time: 2-4 hours of configuration plus 12-48 hours of nameserver propagation. Cloudflare Free is free; Pro at EUR 20/month only pays off above page-rules limits or for image optimisation.

Why Cloudflare pays off

Cloudflare in May 2026 is the simplest solution for three problems every SME with an own domain faces: SSL certificates with zero effort, DDoS protection free on the Free plan, and a WAF catching the bulk of opportunistic attack attempts. Pointing a domain directly at a Hetzner server without Cloudflare leaves you responsible not only for DDoS but for forgotten SSL renewals and automated bot scans – the Cloudflare layer absorbs all that.

The second lever is Workers KV. Cloudflare offers a key-value store on the Free plan with 100,000 reads per day and 1,000 writes – enough for feature flags, session tokens, rate-limit counters or small application state. Workers themselves (the compute layer) have 100,000 requests per day free, sufficient for mini APIs and edge logic (geo-redirect, A/B tests, header modifications). Ignoring this means paying for a small server doing the same.

The third point is Cloudflare Tunnel (formerly Argo Tunnel). A daemon (cloudflared) on the origin server opens an outbound WebSocket connection to Cloudflare. Cloudflare can reach the origin without any open inbound port on the server. In plain words: the server has no public IP exposure left, all inbound ports can be closed. That eliminates a whole class of attack vectors and is the clean path for fiduciary/law-firm servers.

The fourth point is EU compliance. Cloudflare has the "EU Data Localization Suite" since 2024 – for an Enterprise surcharge all logs and cache data stay in EU data centres. Free does not get the full treatment, but Cloudflare is classified by the current EDÖB consultation as "acceptable with adequate safeguards" if a TIA is documented and data flow is limited (no PII in URLs, no full client-data access via CDN cache).

How the setup hangs together

The architecture has five layers: domain and nameservers, SSL mode, DNS records, security layer (WAF + rate limiting), compute layer (Workers, KV, Tunnel).

Domain and nameservers: domain stays with the registrar (e.g. switch.ch for .ch domains, Cloudflare Registrar for .com/.app). In the Cloudflare dashboard add the domain as a site – Cloudflare shows two nameservers like elsa.ns.cloudflare.com and tom.ns.cloudflare.com. Set those at the registrar. Propagation 12-48h.

SSL mode: three options. "Flexible" encrypts only user → Cloudflare, Cloudflare → origin runs in plaintext (HTTP) – for testing, never production. "Full" encrypts both legs but Cloudflare accepts self-signed certificates at the origin. "Full (Strict)" encrypts both and requires a valid certificate at the origin – the only correct mode for production. Origin certificate: Let's Encrypt via Caddy/Traefik/certbot, or a Cloudflare Origin CA certificate (15-year validity, free, only verifiable by Cloudflare).

DNS records: four standard types. A record (e.g. @ → 94.130.35.250) points at the origin. AAAA record for IPv6 (if origin has IPv6). CNAME (e.g. www → your-domain.ch) redirects www to root. MX record for email (e.g. @ → mail.brevo.com priority 10 if Brevo handles inbound; otherwise own mail server). Enable the Cloudflare proxy (orange cloud) on A/AAAA – hides the origin IP and enables WAF/cache. Always keep MX and TXT DNS-only (grey cloud).

Page rules / rulesets: page rules (Free: 3 rules) allow URL-pattern-based behaviour. Typical rules: `*your-domain.ch/api/*` → cache level bypass (API not cached). `*your-domain.ch/static/*` → cache level "Cache Everything", edge TTL 1 month (static assets aggressively cached). `*your-domain.ch/admin*` → Always Use HTTPS, Security Level High. Modern replacement: Cloudflare Rules (Configuration Rules, Cache Rules, Redirect Rules, Transform Rules) with more granularity.

Workers KV: in the dashboard under "Workers & Pages → KV" create a namespace (e.g. "session-tokens"). In Worker code: `await env.SESSIONS.put(key, value, {expirationTtl: 3600})`. Reads: `await env.SESSIONS.get(key)`. Global replication across 300+ POPs, eventually consistent (write latency worldwide 60-90 seconds).

WAF: Free plan has "Managed Rules → Free Plan" – a baseline list of known attack patterns (SQL injection, XSS, bot patterns). Enable in the dashboard under "Security → WAF". Custom rules: 5 rules on Free. Example: `(http.request.uri.path contains "/wp-admin" and not ip.src in {<your-IPs>})` → Block. Rate limiting: 1 rule on Free, e.g. `(http.request.uri.path eq "/api/login")` with 10 requests/minute per IP.

Cloudflare Tunnel: on the origin `wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb && apt install ./cloudflared-linux-amd64.deb`. `cloudflared tunnel login` (OAuth flow in the browser). `cloudflared tunnel create my-origin` – returns a UUID. In the Cloudflare dashboard "Zero Trust → Networks → Tunnels" you see the tunnel, add a hostname (e.g. app.your-domain.ch → http://localhost:3000). On the origin `cloudflared tunnel run my-origin` (or install as a systemd service with `cloudflared service install`). Inbound firewall on the server: nothing open, only outbound 443.

Cloudflare setup in 12 steps

  1. 01Step 1 – register domain or add Cloudflare site: existing domain: in the Cloudflare dashboard "Add a Site" → enter domain → pick Free plan. Cloudflare scans DNS at the previous provider and imports records automatically. New domain: Cloudflare Registrar (.com USD 10/year, .ch not possible – use switch.ch or Hostpoint there).
  2. 02Step 2 – switch nameservers: Cloudflare shows two nameservers (e.g. elsa.ns.cloudflare.com and tom.ns.cloudflare.com). Enter these at the registrar, delete old ones. Cloudflare polls every 30 minutes – status flips to "Active" in the dashboard, typically 12-48h.
  3. 03Step 3 – set SSL mode to Full (Strict): in the dashboard "SSL/TLS → Overview" → "Full (strict)". Origin needs a valid certificate: Let's Encrypt via Caddy/Traefik (automatic), or generate a Cloudflare Origin CA cert (valid 15 years, in "SSL/TLS → Origin Server → Create Certificate", reference on the server in nginx or Caddy).
  4. 04Step 4 – verify and extend DNS records: "DNS → Records". A record to origin IP (orange cloud = proxied). CNAME www → your-domain.ch (proxied). MX records DNS-only (grey cloud). SPF/DKIM/DMARC TXT records DNS-only. Optionally a CAA record `0 issue "letsencrypt.org"` to restrict CAs.
  5. 05Step 5 – set page rules / cache rules: "Rules → Cache Rules" (modern variant). Rule 1: `URI Path → starts with → /api/`, action: Cache Eligibility = bypass. Rule 2: `URI Path → starts with → /static/`, action: Cache TTL = 1 month, Browser TTL = 1 day. Rule 3: `URI Path → contains → /admin`, action: Security Level = high.
  6. 06Step 6 – set up Workers KV: "Workers & Pages → KV" → "Create namespace" (e.g. "sessions"). In Worker code: `wrangler kv namespace create sessions` in wrangler.toml. Example worker: `export default { async fetch(req, env) { const key = req.url.split("?")[1]; await env.SESSIONS.put(key, "value", {expirationTtl: 3600}); return new Response("OK"); } }`. Deploy with `wrangler deploy`.
  7. 07Step 7 – enable WAF baseline: "Security → WAF → Managed Rules". Set "Cloudflare Free Managed Ruleset" to "Enable". Sensitivity "Medium". "Security → WAF → Custom Rules" → "Create rule": expression `(http.request.uri.path contains "/wp-admin") or (http.request.uri.path contains "/xmlrpc.php")`, action: Block. Second rule: `(cf.bot_management.score lt 30 and not cf.bot_management.verified_bot)`, action: Managed Challenge.
  8. 08Step 8 – rate limiting on /api/login: "Security → WAF → Rate Limiting Rules" (Free: 1 rule). Expression: `http.request.uri.path eq "/api/login" and http.request.method eq "POST"`. Characteristic: "IP". Period: 1 minute. Requests: 10. Action: Block for 1 hour.
  9. 09Step 9 – install cloudflared on origin: SSH to the origin. `wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb`. `apt install ./cloudflared-linux-amd64.deb`. `cloudflared tunnel login` – opens a browser flow, authorise. `cloudflared tunnel create my-origin` – note the tunnel UUID.
  10. 10Step 10 – tunnel hostname and routing: in the dashboard "Zero Trust → Networks → Tunnels" → open the new tunnel → "Public Hostname" add: subdomain `app`, domain `your-domain.ch`, service `http://localhost:3000`. On the origin write config `/etc/cloudflared/config.yml`: `tunnel: <UUID>`, `credentials-file: /root/.cloudflared/<UUID>.json`, `ingress: - hostname: app.your-domain.ch service: http://localhost:3000 - service: http_status:404`.
  11. 11Step 11 – run cloudflared as service: `cloudflared service install`. `systemctl enable cloudflared && systemctl start cloudflared`. `systemctl status cloudflared` – must show running. In the dashboard the tunnel should be "Healthy". Test: https://app.your-domain.ch should reach the origin service.
  12. 12Step 12 – harden server firewall: on origin close all inbound TCP ports except 22 (SSH, ideally only from your own IP). `ufw default deny incoming`, `ufw allow from <your-ip> to any port 22`, `ufw enable`. The origin is now reachable from outside only via Cloudflare Tunnel – no direct exposure. Optional: whitelist cloudflared IPs if SSH should go via Cloudflare Access.

When Cloudflare is the right choice

Cloudflare fits 90% of SME domains. Specifically: (a) every public-facing website needs DDoS protection and SSL – free with Cloudflare. (b) every application with a login form needs WAF and rate limiting – free with Cloudflare. (c) every origin server with sensitive data needs Cloudflare Tunnel to hide the public IP.

Typical cases: a fiduciary website on Hetzner with client login → Cloudflare Free + Tunnel + WAF block for /wp-admin and /xmlrpc.php. An n8n instance that should be reachable only internally → Cloudflare Tunnel + Zero Trust Access with email allowlist. A law-firm presence with a contact form → Cloudflare Pro for image optimisation plus bot protection.

For purely internal applications without internet exposure, Cloudflare is overkill – VPN (Tailscale, WireGuard) is the simpler path. For extreme high-performance workloads with > 1M requests/day, dedicated CDNs (Bunny CDN, Fastly) can be cheaper.

When Cloudflare is not the right choice

Cloudflare does not fit when (a) the use case is extremely data-protection-critical and CDN cache data must also stay in EU – not guaranteed on Free, only "EU Data Localization Suite" (Enterprise) fully delivers. (b) the application is WebSocket-heavy with long-lived connections – Cloudflare Free has 100s WebSocket timeout, Pro 4h, Enterprise configurable. (c) data volume is extremely high (> 10TB/month) – Free is fair-use, massive traffic triggers throttling or upgrade prompts.

More pitfalls: enabling Cloudflare proxy (orange cloud) on an MX record – does not work, mail-server connections break. Cloudflare proxy on an SSH subdomain (ssh.your-domain.ch) – does not work, SSH is not HTTP. Leaving SSL mode "Flexible" in production – user data flows in plaintext between Cloudflare and origin. A page rule with "Cache Everything" on a login page – session tokens get globally cached, all users see the same session.

Trade-offs

STRENGTHS

  • SSL, DDoS protection, WAF baseline and CDN free on the Free plan
  • Cloudflare Tunnel removes direct exposure of the origin server
  • Workers KV as a free key-value store for 100k reads/day
  • Global network with 300+ POPs delivers low latency worldwide

WEAKNESSES

  • Free-plan EU data localisation is not fully guaranteed – Enterprise needed for 100% EU hold
  • On a Cloudflare outage (rare but it happens) the domain is globally down
  • WebSocket timeout 100s on Free – too short for long-lived connections
  • Cloudflare-specific Worker runtime – not standard Node.js, mild lock-in tendency

FAQ

What does Cloudflare cost for an SME?

Cloudflare Free: 0. DDoS, SSL, baseline WAF, 100k Worker requests/day, 100k KV reads/day, unlimited Tunnel – all included. Cloudflare Pro EUR 20/month per domain: more WAF rules, image optimisation, Polish, mobile optimisation. Business EUR 200/month: extended WAF, advanced rate limits. For 90% of SMEs Free is enough. Pro pays off only with image-optimisation needs (photo-heavy sites) or more than 5 WAF rules.

How do I protect the origin despite Cloudflare?

Combine three measures. (1) Cloudflare Tunnel – no open inbound port on the server, direct IP no longer reachable. (2) Origin firewall (ufw) additionally blocks direct access. (3) Cloudflare WAF + Authenticated Origin Pulls (mTLS): Cloudflare sends a certificate, origin accepts only requests with that certificate – prevents IP-leak bypass. For fiduciary/law-firm servers: deploy all three.

Can I use Workers KV as a real database?

No, unsuitable for transactional workloads. KV is eventually consistent – writes are globally visible after 60-90 seconds. For session tokens, feature flags, rate-limit counters, small caches it works great. For database workloads with consistent reads: Cloudflare D1 (SQLite-compatible, in beta since 2024, beta-stable in 2026) or Cloudflare Durable Objects (strongly consistent, slightly more expensive). Classic Postgres remains the right choice for complex workloads.

What does the EDÖB say about Cloudflare?

As of May 2026: Cloudflare is rated "acceptable with adequate safeguards" in the ongoing EDÖB consultation. Means: document a TIA, restrict data flow to what is necessary, do not route PII in URLs/headers Cloudflare can read (or mask via Worker). For maximum safety: "EU Data Localization Suite" (Enterprise) – all logs and cache data stay in EU POPs, cost in four digits per month. For fiduciary standard, Free + TIA + IP masking is the pragmatic path.

Related topics

CLOUDFLARE · TECH STACKCloudflare as DNS, reverse proxy, and WAF: SSL modes, cache rules, origin certificatesDDoS · SECURITY & OPSDDoS protection with Cloudflare: layer 3, 4, and 7 for SME web apps in 2026CLOUDFLARE vs BUNNY.NET vs FASTLY - DUELCloudflare vs Bunny.net vs Fastly - which edge platform for SMEs?FIREWALL · SECURITY & OPSFirewall and CrowdSec: layered protection for SME servers in 2026HETZNER · TECHHetzner as EU hosting for Swiss fiduciaries and SMEs: data centres, contracts, costBREVO · HOW-TOSet up Brevo SMTP: DNS, DKIM, DMARC, Nodemailer test and bounce webhooks (May 2026)BACKUP · HOW-TOBackup strategy 3-2-1 for SMEs: restic, rclone, Backblaze B2 and recovery drills (May 2026)

Sources

  1. Cloudflare Documentation – Getting started with Cloudflare · 2026-05
  2. Cloudflare Tunnel – secure origin connectivity · 2026-05
  3. Cloudflare Workers KV – global key-value store · 2026-04
  4. Cloudflare WAF – custom rules and managed rulesets · 2026-04
  5. EDÖB – current consultation on US cloud providers and TIA practice · 2026-03

FITS YOUR STACK?

What this looks like in your business – a 30-minute intro call.

Book a call