Kas čia per žvėris tas Cloudflare Tunnel?
Jei turi namų serverį – nesvarbu, ar tai Raspberry Pi su Home Assistant, ar pilnavertis NAS su Nextcloud, ar tiesiog koks nors Docker konteinerių rinkinys – tai tikriausiai bent kartą galvojai: kaip tą viską pasiekti iš išorės? Atsakymas, kurį dažniausiai randa žmonės, yra port forwarding. Atidarai prievadą ruoteryje, nukreipi srautą į serverį, ir viskas veikia. Teoriškai.
Praktikoje tai reiškia, kad tavo namų IP adresas yra viešai matomas, interneto šiukšliadėžės robotai jį nuskaito per kelias minutes ir pradeda belstis į duris, o jei turi dinaminį IP (o dauguma namų vartotojų turi), tai dar ir DynDNS ar panašius sprendimus reikia konfigūruoti. Ir tai dar nekalbu apie tuos, kurių interneto tiekėjas naudoja CG-NAT – jiems port forwarding apskritai neveikia.
Cloudflare Tunnel (anksčiau žinomas kaip Argo Tunnel arba cloudflared) sprendžia visas šias problemas vienu ypu. Idėja paprasta: tavo serveris pats inicijuoja ryšį su Cloudflare tinklu, sukuria šifruotą tunelį, ir visas srautas eina per jį. Nereikia atidaryti jokių prievadų, nereikia viešo IP, nereikia DynDNS. Cloudflare tampa tarpininku, o tavo serveris sėdi saugiai už NAT.
Kaip tai veikia po gaubtu
Techniškai kalbant, Cloudflare Tunnel naudoja protokolą, kurį Cloudflare vadina QUIC arba HTTP/2 – priklausomai nuo konfigūracijos. Tavo serveryje įdiegiamas cloudflared daemonas, kuris užmezga kelis lygiagrečius ryšius su Cloudflare edge serveriais (paprastai 4 ryšiai į skirtingus duomenų centrus). Kai kas nors bando pasiekti tavo domeną, Cloudflare priima užklausą savo edge’e ir perduoda ją per tunelį tavo serveriui.
Tai reiškia, kad srautas visada eina per Cloudflare. Tai yra ir privalumas, ir trūkumas – apie tai kalbėsiu vėliau. Privalumas tas, kad gauni Cloudflare DDoS apsaugą, WAF (Web Application Firewall) galimybes, SSL sertifikatus automatiškai, ir visą kitą Cloudflare ekosistemą. Trūkumas – Cloudflare mato visą tavo srautą (bent jau metaduomenis), ir jei Cloudflare turėtų problemų, tavo servisai taip pat neveiktų.
Svarbu suprasti, kad Cloudflare Tunnel nemokamoje versijoje yra visiškai nemokamas. Taip, skamba per gerai, kad būtų tiesa, bet tai tiesa. Nemokamame plane gauni neribotą tunelių skaičių, neribotą srautą (su sąlyga, kad nenaudoji jo video streamingui – tai draudžia ToS), ir visas pagrindines funkcijas.
Diegimas žingsnis po žingsnio
Gerai, eime prie praktikos. Prieš pradedant, reikia turėti:
- Cloudflare paskyrą (nemokama)
- Domeną, kuris yra pridėtas prie Cloudflare (DNS turi būti valdomas Cloudflare)
- Serverį su Linux (aš naudosiu Ubuntu/Debian pavyzdžius, bet veikia ir su kitomis distribucijomis)
Pirmas žingsnis – įdiegti cloudflared. Debian/Ubuntu sistemose tai daroma taip:
curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared.deb
Jei naudoji ARM architektūrą (Raspberry Pi ir panašūs), pakeisk amd64 į arm64 arba arm – priklausomai nuo tavo įrenginio. Galima patikrinti su uname -m komanda.
Toliau reikia autentifikuotis:
cloudflared tunnel login
Ši komanda atspausdins nuorodą – ją atidarysi naršyklėje, prisijungsi prie Cloudflare ir pasirinksi domeną. Grįžęs į terminalą pamatysi, kad sertifikatas buvo išsaugotas ~/.cloudflared/cert.pem.
Dabar sukuriame tunelį:
cloudflared tunnel create mano-tunelis
Pavadinimą galima rinktis bet kokį. Po šios komandos bus sukurtas tunelio UUID ir credentials failas. Užsirašyk UUID – jo prireiks.
Konfigūracijos failas – čia dauguma žmonių susipaina. Sukurk failą ~/.cloudflared/config.yml:
tunnel: TAVO-TUNELIO-UUID
credentials-file: /root/.cloudflared/TAVO-TUNELIO-UUID.json
ingress:
- hostname: servisas.tavo-domenas.lt
service: http://localhost:8080
- hostname: kitas-servisas.tavo-domenas.lt
service: http://localhost:3000
- service: http_status:404
Paskutinė eilutė service: http_status:404 yra privaloma – tai default taisyklė, kuri grąžina 404 visiems užklausimams, kurie neatitinka nė vieno hostname. Be jos cloudflared atsisakys paleisti.
DNS įrašus galima sukurti automatiškai:
cloudflared tunnel route dns mano-tunelis servisas.tavo-domenas.lt
Ir galiausiai, kad tunelis veiktų kaip sistemos servisas ir automatiškai paleistų po perkrovimo:
sudo cloudflared service install
sudo systemctl enable cloudflared
sudo systemctl start cloudflared
Kelios spąstų vietos, į kurias tikrai įkritau
Teorija skamba gražiai, bet praktikoje yra keletas dalykų, kurie gali sukelti galvos skausmą. Pirmas dalykas – credentials failo kelias. Jei paleidi cloudflared tunnel create kaip paprastas vartotojas, credentials failas bus /home/vartotojas/.cloudflared/. Bet jei servisas veikia kaip root (o dažniausiai taip ir yra po service install), jis ieškos failo /root/.cloudflared/. Tai sukelia klaidą, kuri nėra labai aiški iš log’ų.
Sprendimas – arba nukopijuoti credentials failą į /root/.cloudflared/, arba konfigūracijos faile nurodyti pilną kelią:
credentials-file: /home/tavo-vartotojas/.cloudflared/UUID.json
Antras spąstas – WebSocket palaikymas. Jei naudoji servisus, kurie naudoja WebSocket (Home Assistant, Grafana, daugelis modernių web aplikacijų), Cloudflare pagal nutylėjimą gali blokuoti ilgalaikes WebSocket jungtis. Tai reikia įjungti Cloudflare dashboard’e: Network → WebSockets → Enable.
Trečias dalykas, kuris ne visiems akivaizdus – SSL/TLS režimas. Cloudflare turi kelis SSL režimus: Flexible, Full, Full (Strict). Jei naudoji Cloudflare Tunnel, rekomenduoju nustatyti Full arba Full (Strict). Flexible režimas reiškia, kad ryšys tarp Cloudflare ir tavo serverio nėra šifruotas – o su tuneliu tai neatitinka tikrovės ir gali sukelti redirect loop’us.
Ketvirtas dalykas – didelių failų įkėlimas. Cloudflare nemokamame plane turi 100MB failo dydžio limitą per vieną užklausą. Jei naudoji Nextcloud ar panašų servisą, tai gali būti problema. Sprendimas – arba pereiti prie mokamo Cloudflare plano, arba didelius failus įkelti per kitą kanalą (pvz., tiesiogiai per VPN).
Cloudflare Access – papildomas saugumo sluoksnis
Vienas iš didžiausių Cloudflare Tunnel privalumų yra galimybė integruoti jį su Cloudflare Access – zero-trust prieigos valdymo sistema. Tai leidžia apsaugoti savo servisus autentifikacija be to, kad reikėtų pačiame servise konfigūruoti autentifikaciją.
Praktinis pavyzdys: tarkime, turi Grafana dashboard’ą, kuris veikia be autentifikacijos (arba su silpna autentifikacija). Su Cloudflare Access gali nustatyti, kad prieš pasiekiant Grafana, vartotojas turi prisijungti per Google, GitHub, ar net tiesiog patvirtinti savo el. pašto adresą. Cloudflare Access tai padaro dar prieš srautui pasiekiant tavo serverį.
Konfigūracija darosi per Cloudflare Zero Trust dashboard’ą (zero-trust.cloudflare.com). Eini į Access → Applications → Add an application, pasirenkam Self-hosted, nurodai hostname ir sukonfigūruoji politiką. Nemokamame plane gauni iki 50 vartotojų – daugiau nei pakankamai namų naudojimui.
Vienas niuansas – kai kurie servisai (pvz., Home Assistant mobile app, arba API klientai) nemoka dirbti su Cloudflare Access autentifikacija. Tokiu atveju galima naudoti Service Tokens – tai API raktai, kuriuos galima pridėti prie užklausos header’ių.
Alternatyvos ir kada Cloudflare Tunnel nėra geriausias pasirinkimas
Cloudflare Tunnel nėra sidabrinė kulka. Yra situacijų, kur kiti sprendimai gali būti geresni.
Tailscale – jei nori prieigos tik sau ar keliems patikimiems žmonėms, Tailscale yra fantastiška alternatyva. Jis sukuria virtualų privatų tinklą tarp tavo įrenginių, nereikia jokio domeno, ir visas srautas yra end-to-end šifruotas (Cloudflare Tunnel atveju Cloudflare mato srautą). Tailscale nemokamame plane leidžia iki 3 vartotojų ir 100 įrenginių.
WireGuard VPN – jei turi bent vieną serverį su viešu IP (pvz., pigų VPS), gali pats pasikonfigūruoti WireGuard. Tai suteikia pilną kontrolę, bet reikia daugiau techninių žinių ir yra daugiau ką konfigūruoti.
Ngrok – geras sprendimas greitam testavimui, bet nemokamame plane turi daug apribojimų (atsitiktiniai URL, limituotas srautas). Ilgalaikiam naudojimui netinka.
Cloudflare Tunnel nėra geriausias pasirinkimas kai:
- Nori eksponuoti ne-HTTP servisus (pvz., game serverius, raw TCP). Cloudflare Tunnel palaiko tik HTTP/HTTPS ir SSH (per specialų režimą). Nors yra eksperimentinis TCP tunelio palaikymas, jis nėra patikimas.
- Rūpi privatumas ir nenori, kad Cloudflare matytų tavo srautą
- Reikia labai mažo latency – Cloudflare prideda papildomą hop’ą
- Naudoji servisus, kurie reikalauja statinio IP (kai kurie API integracijos)
Docker ir Cloudflare Tunnel – puikus duetas
Jei naudoji Docker (o jei turi namų serverį ir nenaudoji Docker, tai turbūt jau galvoji apie tai), Cloudflare Tunnel integruojasi labai elegantiškai. Galima paleisti cloudflared kaip Docker konteinerį ir viskas veikia per Docker tinklą.
Docker Compose konfigūracija atrodytų maždaug taip:
version: '3'
services:
cloudflared:
image: cloudflare/cloudflared:latest
restart: unless-stopped
command: tunnel --config /etc/cloudflared/config.yml run
volumes:
- ./cloudflared:/etc/cloudflared
networks:
- web
mano-app:
image: mano-aplikacija:latest
networks:
- web
networks:
web:
driver: bridge
Konfigūracijos faile servisą nurodai ne kaip http://localhost:8080, o kaip http://mano-app:8080 – naudoji Docker tinklo pavadinimą. Tai reiškia, kad mano-app konteineris net nereikia eksponuoti prievadų į host sistemą – visas srautas eina per Docker vidinį tinklą.
Tai yra gana svarbus saugumo privalumas: tavo aplikacijos konteineriai visiškai izoliuoti nuo išorinio pasaulio, ir tik cloudflared konteineris turi ryšį su Cloudflare tinklu.
Vienas patarimas – naudok konkretų cloudflared image versiją, o ne :latest. Cloudflare kartais išleidžia atnaujinimus, kurie keičia konfigūracijos formatą, ir :latest gali sulaužyti veikiančią konfigūraciją. Geriau naudoti kažką panašaus į cloudflare/cloudflared:2024.x.x ir atnaujinti sąmoningai.
Kai tunelis tampa gyvenimo būdu (ir ką tai reiškia ilgainiui)
Po kelių mėnesių naudojimo galiu pasakyti – Cloudflare Tunnel tikrai pakeitė tai, kaip žiūriu į namų serverių administravimą. Nebereikia galvoti apie port forwarding taisykles, nebereikia stebėti, ar nepasikeitė IP adresas, nebereikia konfigūruoti reverse proxy su SSL sertifikatais (nors Nginx ar Traefik vis tiek praverčia vidiniams servisams).
Bet svarbu suprasti, kad priklausomybė nuo Cloudflare yra reali. Jei Cloudflare turėtų didelę avariją (o tokių būta – 2020 metais jie turėjo rimtą incidentą, kuris paveikė didelę dalį interneto), tavo servisai bus nepasiekiami iš išorės. Todėl rekomenduoju visada turėti alternatyvų prieigos būdą – bent jau WireGuard ar Tailscale kaip backup.
Taip pat verta reguliariai tikrinti Cloudflare Tunnel log’us. Komanda sudo journalctl -u cloudflared -f rodo realaus laiko log’us ir padeda pastebėti problemas anksti. Cloudflare dashboard’e taip pat yra Analytics sekcija, kur matosi srautas per tunelį – tai naudinga ir saugumo stebėjimui.
Galiausiai – jei rimtai žiūri į namų serverių saugumą, Cloudflare Tunnel yra tik vienas iš sluoksnių. Jis puikiai apsaugo nuo išorinių grėsmių, bet vidinis tinklo saugumas, reguliarūs atnaujinimai, stiprūs slaptažodžiai ir dviejų faktorių autentifikacija lieka tavo atsakomybe. Cloudflare Tunnel nėra magiška apsauga nuo visko – tai tiesiog labai geras įrankis, kuris, teisingai sukonfigūruotas, leidžia mėgautis namų serverių patogumu nesukant galvos dėl tinklo konfigūracijos sudėtingumo.
