Cloudflare Tunnel — usługi z homelabu bez otwierania portów

Cloudflare Tunnel w Dockerze: dostęp do usług w sieci domowej z zewnątrz bez otwierania portów i publicznego IP, plus Cloudflare Access dla paneli admina.

Klasyczny sposób na udostępnienie domowej usługi to przekierowanie portu 443 na routerze do reverse proxy. Działa, ale ma trzy wady: Twój domowy adres IP jest publiczny, każdy skaner w internecie widzi otwarty port, a za CGNAT-em u operatora komórkowego czy światłowodowego w ogóle nie masz czego przekierować.

Cloudflare Tunnel — co to jest i jak działa

Cloudflare Tunnel odwraca kierunek połączenia. Demon cloudflared w Twojej sieci sam łączy się z Cloudflare, a ruch od użytkowników wraca tym samym, wychodzącym połączeniem. Router nie ma otwartych portów, a Twoje IP pozostaje ukryte.

Przepływ ruchu przez tunel
przeglądarka ──HTTPS──► Cloudflare (vault.prywatnylab.pl)
▲
│ połączenie wychodzące, utrzymywane przez cloudflared
│
┌─────────┴──────────┐
│ VM docker01 │
│ cloudflared ──────┼──► vaultwarden:80 (sieć cf-tunnel)
└────────────────────┘

Czego potrzebujesz

  • Domeny w Cloudflare — rejestracja może być u dowolnego rejestratora, ale serwery DNS domeny muszą wskazywać Cloudflare. Po dodaniu domeny w panelu dostaniesz dwa adresy nameserverów do wpisania u rejestratora.
  • Darmowego konta Cloudflare Zero Trust — przy pierwszym wejściu do panelu Zero Trust wybierasz nazwę zespołu i plan Free (do 50 użytkowników). Cloudflare może poprosić o kartę płatniczą, ale plan darmowy nic nie kosztuje.
  • Maszyny z Dockerem z poprzedniej części i sieci cf-tunnel.

Tworzenie tunelu

W panelu Cloudflare Zero Trust przejdź do Networks → Tunnels → Create a tunnel:

  1. Typ konektora: Cloudflared.
  2. Nazwa: np. homelab-docker01.
  3. Na ekranie instalacji wybierz Docker i skopiuj z wyświetlonego polecenia sam token — długi ciąg po --token.

Token to jedyny sekret potrzebny do uruchomienia tunelu. Traktuj go jak hasło.

cloudflared w Dockerze

/opt/stacks/cloudflared/compose.yaml
services:
cloudflared:
image: cloudflare/cloudflared:latest
container_name: cloudflared
restart: unless-stopped
command: tunnel --no-autoupdate run
environment:
TUNNEL_TOKEN: ${TUNNEL_TOKEN}
TUNNEL_METRICS: 0.0.0.0:60123
healthcheck:
test: ['CMD', 'cloudflared', 'tunnel', '--metrics', 'localhost:60123', 'ready']
interval: 30s
timeout: 5s
retries: 3
networks:
- cf-tunnel
networks:
cf-tunnel:
external: true
Uruchomienie
cd /opt/stacks/cloudflared
# Polecenie zapyta o token i nie wyświetli go na ekranie ani nie zapisze w historii powłoki
read -rsp 'Token tunelu: ' TOKEN && echo "TUNNEL_TOKEN=$TOKEN" > .env && unset TOKEN
chmod 600 .env
docker compose up -d
docker compose logs -f

W logach szukaj czterech linii Registered tunnel connection — cloudflared utrzymuje połączenia z kilkoma centrami danych Cloudflare jednocześnie. W panelu tunel zmieni status na Healthy.

Publiczne hostname

W konfiguracji tunelu przejdź do zakładki Public Hostname → Add a public hostname:

Pole Wartość
Subdomain vault
Domain prywatnylab.pl
Service → Type HTTP
Service → URL vaultwarden:80

vaultwarden to nazwa kontenera. Obie usługi są w sieci cf-tunnel, więc Docker rozwiąże ją na właściwy adres. Cloudflare sam utworzy rekord DNS i certyfikat TLS. Po chwili https://vault.prywatnylab.pl działa z każdego miejsca na świecie.

Kolejne usługi dodajesz tak samo: kontener w sieci cf-tunnel i nowy wpis w Public Hostname. Bez restartu cloudflared i bez zmian na routerze.

Cloudflare Access: druga warstwa przed panelem admina

Tunel ukrywa Twoje IP, ale sama aplikacja jest publiczna — każdy może otworzyć stronę logowania. Dla paneli administracyjnych dodaj Cloudflare Access: zanim ruch w ogóle dotrze do Twojego serwera, Cloudflare wymaga potwierdzenia tożsamości.

Przykład: panel administracyjny Vaultwardena pod /admin ma być dostępny tylko dla Ciebie.

  1. Access → Applications → Add an application → Self-hosted.
  2. Application domain: vault.prywatnylab.pl, path: admin.
  3. Policy: Action Allow, Include → Emails → Twój adres e-mail.
  4. Metoda logowania: One-time PIN, czyli kod wysyłany na e-mail (domyślnie włączony).

Od teraz https://vault.prywatnylab.pl/admin najpierw pokaże ekran Cloudflare z prośbą o kod z e-maila. Reszta Vaultwardena — aplikacje mobilne i rozszerzenia przeglądarki — działa bez zmian.

Czego nie przepuszczać przez tunel

  • Streamingu wideo (Jellyfin, Plex). Warunki usługi Cloudflare ograniczają serwowanie dużych ilości wideo przez darmową sieć CDN, a konto łamiące regulamin może zostać zablokowane. Do mediów spoza domu używaj WireGuarda.
  • Dużych uploadów. Plan darmowy ogranicza rozmiar pojedynczego żądania HTTP do 100 MB. Nextcloud radzi sobie z tym dzięki wysyłaniu w kawałkach (chunked upload), inne aplikacje mogą nie.
  • Protokołów innych niż HTTP(S) dla anonimowych użytkowników. SSH czy RDP przez tunel wymagają cloudflared także po stronie klienta.

Weryfikacja

Okno terminala
# Z zewnątrz (np. telefon na LTE): odpowiedź przez Cloudflare
curl -sI https://vault.prywatnylab.pl | grep -iE 'HTTP/|server|cf-ray'
# W domu: Twój publiczny adres IPv4
curl -4s https://ifconfig.me
# Z maszyny spoza sieci domowej (np. VPS): skan adresu z poprzedniego polecenia
nmap -Pn -p 80,443,8006 203.0.113.25

Oczekiwany wynik: nagłówek server: cloudflare z cf-ray przy żądaniu do domeny i wszystkie porty filtered lub closed przy skanie domowego IP.

Aplikacje webowe są już dostępne dla świata. Do administracji — SSH, panelu Proxmoxa, udziałów sieciowych — skonfigurujesz w następnej części prywatny tunel WireGuard.