CF Workers i DNS: dobre rozwiązanie dla homelaba

Globalna sieć łącząca infrastrukturę chmurową

Cloudflare Workers i DNS to dobre rozwiązanie dla homelaba, gdy chcemy publikować strony bez wystawiania domowego serwera jako pierwszej linii obrony.

Najprostszy model wygląda tak:

Internet → Cloudflare Edge → Worker / static assets

Praktyczne korzyści:

  • publiczna strona może działać bez serwera origin;
  • rekordy DNS z włączonym proxy zwracają adresy anycast Cloudflare zamiast IP originu;
  • TLS, przekierowania, cache, ochrona DDoS i wybrane reguły WAF działają na Cloudflare Edge;
  • DNS i polityka bezpieczeństwa stają się audytowalnym Infrastructure as Code;
  • środowisko można szybko odtworzyć z repozytorium Git po awarii.

Nie zastępuje to segmentacji sieci. Edge i firewall homelaba rozwiązują inne problemy. Warstwę sieciową opisujemy w poradnikach hardening domowego homelaba i prosta architektura firewalla MikroTik.

Podział odpowiedzialności zamiast dwóch źródeł prawdy

Zarówno Wrangler, jak i Cloudflare provider używany przez OpenTofu potrafią konfigurować część właściwości Workera.

Stosujemy jednoznaczny podział:

Właściciel Zasoby
Wrangler kod Workera, statyczne assety, compatibility date, bindingi, observability i workers_dev
OpenTofu strefy, rekordy DNS, Custom Domains Workerów, przekierowania, cache, WAF Custom Rules i rate limiting

Wrangler najpierw wdraża aplikację, a OpenTofu łączy jej stabilną nazwę usługi z hostname i zarządza infrastrukturą.

Przykład IaC

# main.tf
terraform {
  required_version = ">= 1.12, < 2.0"

  required_providers {
    cloudflare = {
      source  = "cloudflare/cloudflare"
      version = "~> 5.0"
    }
  }
}

provider "cloudflare" {
  api_token = var.cloudflare_api_token
}

# variables.tf
variable "cloudflare_api_token" {
  type      = string
  sensitive = true
}

variable "website_zone_id" {
  type = string
}

variable "account_id" {
  type = string
}

# workers_dns.tf
locals {
  website = {
    zone_id = var.website_zone_id
    domain  = "example.net"
    worker  = "example-website"
  }
}

resource "cloudflare_workers_custom_domain" "apex" {
  account_id = var.account_id
  zone_id    = local.website.zone_id
  hostname   = local.website.domain
  service    = local.website.worker
}

resource "cloudflare_dns_record" "www" {
  zone_id = local.website.zone_id
  name    = "www"
  content = local.website.domain
  type    = "CNAME"
  ttl     = 1
  proxied = true
}

resource "cloudflare_page_rule" "redirect_www" {
  zone_id  = local.website.zone_id
  target   = "www.${local.website.domain}/*"
  priority = 1
  status   = "active"

  actions {
    forwarding_url {
      url         = "https://${local.website.domain}/$1"
      status_code = 301
    }
  }
}

Istniejący rekord A lub CNAME z tą samą nazwą może uniemożliwić utworzenie Custom Domain.

Rekordy pocztowe działają inaczej. MX, SPF, DKIM i DMARC pozostają zwykłymi zasobami DNS, a CNAME poczty i rekordy walidacyjne najczęściej muszą pozostać DNS-only.

Cloudflare proxy obsługuje tylko odpowiednie rekordy ruchu HTTP/HTTPS. Granicę tę opisuje nasz poradnik Cloudflare i poczty OVH.

Wrangler zarządza Workerem

Statyczna witryna może używać niewielkiego pliku wrangler.jsonc:

{
  "$schema": "./node_modules/wrangler/config-schema.json",
  "name": "example-website",
  "main": "./src/worker.ts",
  "compatibility_date": "2026-08-18",
  "assets": {
    "binding": "ASSETS",
    "directory": "./dist",
    "run_worker_first": false
  },
  "workers_dev": false,
  "observability": {
    "enabled": true
  }
}

workers_dev: false eliminuje dodatkowy publiczny endpoint workers.dev, jeśli produkcja ma być dostępna wyłącznie pod własną domeną. Podczas testów można tymczasowo pozostawić go włączonego.

run_worker_first: false jest dobrym domyślnym ustawieniem dla statycznej witryny. Cloudflare może wtedy obsłużyć statyczny asset bez uruchamiania kodu Workera.

Jeżeli konkretne requesty wymagają logiki Workera przed odczytem assetu, można włączyć run_worker_first świadomie. Nie warto jednak uruchamiać Workera dla każdego assetu bez potrzeby.

Ostrożny workflow:

npx wrangler deploy --dry-run
npx wrangler deploy

tofu fmt -check -diff
tofu validate
tofu plan
tofu apply

Wdrożenie Workera przed utworzeniem nowej Custom Domain zapobiega odwołaniu OpenTofu do nieistniejącej usługi.

W CI najpierw budujemy i testujemy, następnie wdrażamy Workera, a na końcu osobno aplikujemy zatwierdzony plan infrastruktury.

Więcej o tym stacku piszemy w artykule Wybór technologii do bloga i strony firmowej w 2026.

Tokeny API i minimalne uprawnienia

Token Uprawnienie Zastosowanie
deployment Wrangler Account Workers Scripts: Edit wysłanie i aktualizacja Workera
baza OpenTofu Zone DNS: Edit zarządzanie rekordami DNS
Custom Domain OpenTofu Account Workers Scripts: Edit powiązanie domeny z Workerem

Pozostałe uprawnienia dodawaj tylko wtedy, gdy odpowiadają zasobom istniejącym w konfiguracji:

Opcjonalny zasób OpenTofu Uprawnienie
tworzenie lub zarządzanie strefami Account Zone: Edit
ustawienia TLS i HTTPS strefy Zone Zone Settings: Edit
WAF Custom Rules Zone WAF: Edit
reguły cache Zone Cache Settings: Edit

Cloudflare definiuje uprawnienie Edit jako CRUDL: create, read, update, delete i list. Edit zawiera więc Read/List tam, gdzie mają zastosowanie; osobne Read dla tej samej grupy nie zwiększa dostępu.

Szczegóły zawierają dokumenty Create API token i API token permissions.

Nie umieszczaj sekretów w .tf, tfvars, konfiguracji Wranglera, historii powłoki ani Git. Przekazuj je z secret managera lub chronionych zmiennych CI, na przykład jako TF_VAR_cloudflare_api_token dla OpenTofu i CLOUDFLARE_API_TOKEN dla Wranglera.

State OpenTofu może zawierać dane wrażliwe nawet wtedy, gdy terminal oznacza je jako sensitive. Zdalny backend powinien być szyfrowany i objęty ścisłą kontrolą dostępu.

Co jest dostępne bezpłatnie?

Najważniejsze jest rozróżnienie dwóch ścieżek:

static asset → bez wywołania Workera
dynamic request → wywołanie Workera
run_worker_first: true → Worker uruchamia się również przed assetem

Dla planu Workers Free:

  • żądania obsłużone bezpośrednio jako statyczne assety są bezpłatne i nielimitowane;
  • Worker ma limit 100 000 requestów dziennie;
  • limit CPU wynosi 10 ms na wywołanie Workera;
  • DNS, Universal SSL i ochrona DDoS są dostępne również na planie Free;
  • WAF, cache, redirecty i logi mają własne limity zależne od aktualnego planu.

Dlatego dla typowej statycznej strony run_worker_first: false jest dobrym punktem startowym.

Limity i zawartość planów zmieniają się. Przed zaprojektowaniem rozwiązania wokół konkretnej liczby sprawdź aktualne ceny Workers, limity Workers i dostępność WAF Custom Rules.

OpenTofu i Wrangler są bezpłatnymi narzędziami, ale mogą utworzyć płatne zasoby Cloudflare.

Mała i precyzyjna warstwa WAF

Statyczna strona na Workerze nie powinna otrzymywać żądań do .env, .git, PHP ani ścieżek WordPressa.

WAF Custom Rules mogą odrzucić takie próby przed uruchomieniem Workera:

resource "cloudflare_ruleset" "probe_block" {
  zone_id     = var.website_zone_id
  name        = "Block probes"
  kind        = "zone"
  phase       = "http_request_firewall_custom"
  description = "Block paths absent from the static site"

  rules = [{
    action      = "block"
    enabled     = true
    description = "Block sensitive-file and legacy-CMS probes"
    expression  = "(http.request.uri.path contains ".env") or (http.request.uri.path contains "/.git") or (lower(http.request.uri.path) contains ".php") or (lower(http.request.uri.path) contains "/wp-")"
  }]
}

To nie zastępuje zabezpieczeń originu. WAF na edge ogranicza niepotrzebny ruch HTTP, a firewall homelaba nadal chroni warstwę sieciową.

Wskazówki operacyjne

  • Przypnij wersję providera Cloudflare i commituj .terraform.lock.hcl.
  • Przechowuj state OpenTofu zdalnie, z blokadą, szyfrowaniem, backupem i minimalnym dostępem.
  • Importuj istniejące rekordy DNS przed tofu apply; inaczej OpenTofu może próbować utworzyć duplikaty.
  • Wymagaj przeglądu tofu plan, szczególnie usunięć rekordów i wymiany Worker Custom Domain.
  • Rekordy pocztowe pozostaw DNS-only i po zmianach sprawdź SPF, DKIM oraz DMARC.
  • Wyłącz workers.dev dla produkcyjnego Workera z własną domeną, jeśli ten endpoint nie jest celowo używany.
  • W miarę możliwości używaj osobnych hostname i tokenów dla stagingu.

Wynik jest celowo prosty: Wrangler wdraża aplikację, OpenTofu łączy ją z domeną i zabezpiecza edge, a firewall homelaba zakłada, że Cloudflare może zostać ominięty.

Taki podział ułatwia zrozumienie, odtworzenie i zabezpieczenie małego środowiska.

Dokumentacja