İçindekiler
- 1 Ofiste Yaşanan Küçük Bir Panik ve Port Açmadan Yayın Hayali
- 2 Cloudflare Tunnel’ın Kafamızdaki Resmi: Port Açmadan Yayın, Ama Nasıl?
- 3 Temel Kurulum: cloudflared, Tunnel Oluşturma, DNS ve Ingress
- 4 Zero Trust Access ile Kapıya Akıl Koymak
- 5 mTLS: İki Tarafın Da Kimliğini Doğruladığı O Sıkı Tokalaşma
- 6 Birden Fazla Servis, Tek Tünel: HTTP, WebSocket, SSH ve Daha Fazlası
- 7 Sorun Giderme: Küçük Tuzaklar ve Tatlı Çözümler
- 8 Güvenliği Bir Kademe Daha Yükseltmek: Pratik Öneriler
- 9 Adım Adım Bir Örnek Senaryo: Küçük Bir İç Uygulamayı Yayına Alalım
- 10 Dokümantasyon ve Küçük Pusulalar
- 11 Kapanış: Port Açmadan Yayın, Ama Kontrol Hep Sizde
Ofiste Yaşanan Küçük Bir Panik ve Port Açmadan Yayın Hayali
Hiç başınıza geldi mi? Küçük bir side‑project’i evdeki sunucuda koşturursunuz, dışarıdan bakmak istersiniz, sonra modem arayüzünde NAT, port yönlendirme, çift NAT derken bir anda kendinizi ağ ayarlarının labirentinde bulursunuz. O gün ofiste tam da böyle bir an yaşadım. Bir demo göstereceğim, ama 443 portu kapalı, dinamik IP üstüne CGNAT. Uğraş uğraş, olmuyor. İşte o an aklıma şu geldi: Port açmadan, güvenlikten ödün vermeden, hatta tam tersi, daha sıkı güvenlik ile yayına nasıl çıkarım?
Bir süredir kulağımda dolanan bir isim vardı: Cloudflare Tunnel. Adı üstünde, trafiği dışarıdan içeriye çekmek yerine, içeriden dışarıya güvenli bir tünel kuruyordu. Yani modem, NAT, port açma gibi dertleri bir kenara bırakıyorsun. Üstelik üstüne bir de Zero Trust kuralları, Access politikaları ve istersen mTLS ile kimlik doğrulama ekleyebiliyorsun. O gün bu yolculuğa başladım, şimdi de size adım adım, hiç zorlamadan, gerçek hayattan örneklerle anlatmak istiyorum. Hadi beraber kuralım, ayarları tatlı tatlı konuşalım; arada küçük püf noktaları da bırakacağım.
Cloudflare Tunnel’ın Kafamızdaki Resmi: Port Açmadan Yayın, Ama Nasıl?
Mesela şöyle düşünün: Evdeki ya da ofisteki makineniz elini kaldırıp “Ben buradayım” diyerek dışarıya doğru güvenli bir hat açıyor. Bu hattın ucu Cloudflare’in kenar ağına bağlanıyor. Artık dünyadan gelen istekler önce Cloudflare’e uğruyor, oradan sizin açtığınız tünelden içeri akıyor. Yani yönü ters çeviriyorsunuz; port açmaya, NAT’la boğuşmaya gerek kalmıyor. Dışarıya açık tek kapı yok, bağlantı içeriden başlıyor.
Bu modelin güzel tarafı sadece pratik olması değil. Trafik, Cloudflare’in ağı üzerinden geldiği için araya Zero Trust Access kuralları, kimlik doğrulama, isterseniz cihaz sertifikası gibi ek katmanlar koyabiliyorsunuz. Klasik “açık kapı” yaklaşımı yerine, “kapı görünmüyor, sadece izin verilenler içeri giriyor” modeline geçiyorsunuz. Kısacası, proxy mantığını tünelle birleştiriyor, trafik kontrolünü kenarda değil sizde tutuyorsunuz. Üstelik yapılandırma basit; birazdan beraber kuracağız.
Temel Kurulum: cloudflared, Tunnel Oluşturma, DNS ve Ingress
cloudflared nasıl kurulur?
İlk adım, tüneli açacak küçük yardımcı: cloudflared. Linux’ta basitçe paket indirip kurabilirsiniz. Ben hızlı olsun diye yayınlanan derlenmiş paketi tercih ediyorum. En güncel sürümler için cloudflared sürüm sayfasını kontrol edin. Örnek bir kurulum adımı şöyle:
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb -o cloudflared.deb
sudo dpkg -i cloudflared.deb
cloudflared --version
Kurulum tamam, şimdi Cloudflare hesabınızla tünel ilişkilendireceğiz. Bunun için kimlik doğrulamasını bir kez yapmanız yeterli.
Cloudflare hesabına giriş ve ilk tünel
Terminalden şunu çalıştırın; tarayıcı açılacak, hesabı doğrulayacaksınız:
cloudflared tunnel login
Girişten sonra yeni bir tünel oluşturalım. Adına ister “blog-tunnel” deyin, ister “ev-ofis”.
cloudflared tunnel create blog-tunnel
Bu komut size bir Tunnel ID ve kimlik bilgisi dosyası üretir. Genelde ~/.cloudflared/<TUNNEL_ID>.json altında durur. Şimdi sıra, hangi domain üzerinden geleceğini ve içeride nereye akacağını tarif etmeye geldi. DNS yönlendirmesiyle başlayalım:
cloudflared tunnel route dns blog-tunnel app.example.com
config.yml ile Ingress kuralları
Tünel ayarlarını bir dosyada tutmak işleri çok kolaylaştırıyor. ~/.cloudflared/config.yml dosyasını şöyle oluşturabilirsiniz:
tunnel: <TUNNEL_ID>
credentials-file: /home/<kullanici>/.cloudflared/<TUNNEL_ID>.json
ingress:
- hostname: app.example.com
service: http://localhost:8080
- service: http_status:404
Burada “app.example.com” için gelen istekleri içeride 8080 portuna yönlendiriyoruz. Sondaki 404 kuralı önemli; eşleşmeyen her şeyi kibarca geri çevirir. Küçük bir ipucu: Ingress kurallarında sıralama kritik. Daha spesifik olanları üste yazın, genel olanlar alta insin. Yoksa beklenmedik bir eşleşme yapabilirsiniz.
Tüneli ayağa kaldırma ve servis olarak çalıştırma
Tüneli bir test için doğrudan çalıştırabilirsiniz:
cloudflared --config ~/.cloudflared/config.yml tunnel run
Her şey yolundaysa bunu kalıcı bir servise dönüştürmek işin en tatlı kısmı. Systemd kullanan bir sunucuda örnek bir servis birimi şöyle olabilir:
[Unit]
Description=cloudflared Tunnel
After=network-online.target
[Service]
Type=simple
User=<kullanici>
ExecStart=/usr/local/bin/cloudflared --config /home/<kullanici>/.cloudflared/config.yml tunnel run
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Dosyayı /etc/systemd/system/cloudflared.service olarak kaydedin, sonra etkinleştirin:
sudo systemctl daemon-reload
sudo systemctl enable --now cloudflared
sudo systemctl status cloudflared
Artık port açmadan “app.example.com” adresine gidip uygulamanızı görebilirsiniz. Ama durun, hikâye burada bitmez. Güvenlik katmanları, kim girebilir kim giremez, cihaz doğrulama gibi detaylar asıl farkı yaratıyor.
Zero Trust Access ile Kapıya Akıl Koymak
Access uygulaması: Kimin gireceğini kibarca seçmek
Cloudflare’in Zero Trust panelinde “Access” bölümüne girdiğinizde, “Self-hosted” bir uygulama ekleyerek tünelin üzerine kimlik doğrulama ve yetkilendirme katmanları koyabilirsiniz. Adımlar basit: Uygulamaya bir ad verin, domain olarak “app.example.com” yazın, sonra da “Policies” bölümünde kimlerin girebileceğini belirleyin. Mesela, “E‑postası @firma.com ile bitenler” diyebilirsiniz. İsterseniz tek tek e‑posta adresi de girersiniz, isterseniz OIDC/SAML ile kurumsal hesabınızı bağlarsınız.
Hoşuma giden bir özellik de oturum süresi ve yenileme davranışı. Kısa süreli oturum, gerçekten giren kişinin hâlâ yetkili olduğundan emin olmanızı sağlar. Uygulamanız incelikli roller istiyorsa birden fazla politika tanımlayarak adım adım sınırlar çizebilirsiniz. Bir politikayı “Allow” yapıp diğerini “Deny” ile daraltmak mümkün. Çok katmanlı düşünün, ama abartmayın; kontrol panelinde okunabilir kalması uzun vadede sizi yormaz.
Servis token’ları ve makineler arası trafik
İş sadece insanlarla bitmiyor. Bir cron job ya da başka bir servis de bu uygulamaya bağlanmak isteyebilir. “Service Auth” bölümünden Access Service Token üretip bu istemcilerin isteğine iki özel başlıkla eklemesini sağlayın: CF-Access-Client-Id ve CF-Access-Client-Secret. Böylece makineler de sıraya girer, kimlik gösterir, içeri öyle alınır. Basit ama etkili.
mTLS: İki Tarafın Da Kimliğini Doğruladığı O Sıkı Tokalaşma
Şimdi geldik o ekstra kilide: mTLS yani karşılıklı TLS. Normalde tarayıcı sunucunun sertifikasını doğrular. mTLS’de ise sunucu da istemcinin sertifikasını doğrular. “Ben kimim?” sorusu tek taraflı değil, karşılıklı. Biraz daha hareketli bir ortamdaysanız, kritik bir dahili panele erişim veriyorsanız, mTLS şart.
Access tarafında mTLS şartı koymak
Zero Trust panelinde “mTLS” bölümüne girip bir istemci sertifikası oluşturabilirsiniz. Sonra Access’te uygulamanızın politikasına “Require mTLS certificate” şartını ekleyin. Böylece tarayıcı (veya WARP kullanan cihaz) uygulamaya yaklaşırken sertifikasını göstermek zorunda kalır. Yönetmesi kolay olsun diye sertifikaları belli bir süreyle sınırlayın ve gerektiğinde hızla iptal edebilmek için isimlendirmeyi düzenli yapın. Detaylar ve akış için Access uygulama belgelerine göz atabilirsiniz.
Origin tarafını gerçekten tanı: Authenticated Origin Pulls
Bazen tünel yerine doğrudan kenar‑origin trafiğiyle çalışıyorsanız, kenardan gelen isteğin gerçekten Cloudflare’den geldiğini kanıtlamak istersiniz. Bu durumda Authenticated Origin Pulls harika. Kenar, origin’e özel bir istemci sertifikasıyla gelir, siz de “başka kimse değil” dersiniz. Konuyu Authenticated Origin Pulls ve mTLS ile gerçek kaynak doğrulaması yazımızda adım adım işlemiştim; ihtiyacınıza uyuyorsa mutlaka bakın.
Tünel senaryosunda ise cloudflared trafiği içerideki uygulamaya iletir. İçerideki servisiniz HTTPS konuşuyorsa, cloudflared’in ona nasıl bağlanacağını originRequest ayarlarıyla incelikle belirleyebilirsiniz. Bazı durumlarda “noTLSVerify: true” ile test etmek pratik olur, ama üretimde doğru bir origin sertifikası kullanmanızı öneririm. Sertifikayı doğru kurmak, mTLS politikalarınızla birlikte gayet sağlam bir kapı eder.
Birden Fazla Servis, Tek Tünel: HTTP, WebSocket, SSH ve Daha Fazlası
Tünelin en sevdiğim yanı şu: Aynı tünelden birden fazla servisi güvenle taşıyabiliyorsunuz. Örneğin web uygulaması 8080’de, API 9000’de, bir de websockets kullanan gerçek zamanlı bir servisiniz var diyelim. Hepsini tek tek ingress’e yazın, hepsi aynı tünelden geçsin. WebSocket için ayrıca bir şey yapmanıza gerek yok; cloudflared onu da taşır.
Örnek bir çoklu ingress
ingress:
- hostname: app.example.com
service: http://localhost:8080
- hostname: api.example.com
service: http://localhost:9000
- hostname: ws.example.com
service: http://localhost:7000
- service: http_status:404
İçerideki servisleriniz için tek bir servis keşfi gibi düşünebilirsiniz. Bunun bir adım ötesinde SSH/RDP gibi bağlantıları da tünelden geçirmek mümkün. “Self-hosted, ama herkese açık değil” dediğiniz hassas araçlar için çok pratik.
SSH’yi Access ile sarmalamak
SSH için bir alt alan adı ayırın ve ingress’e ekleyin:
- hostname: ssh.example.com
service: ssh://localhost:22
İstemci tarafta ~/.ssh/config içine şu yapı, bağlanmayı çocuk oyuncağına çevirir:
Host ssh.example.com
ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h
User myuser
Böylece ssh ssh.example.com dediğinizde, önce Access sizi doğrular, sonra tünelden SSH oturumu açılır. Dışarıda 22 portu yok, güvenlik duvarını kurcalamıyorsunuz, ama içerideki makinaya gayet rahat erişiyorsunuz.
Sorun Giderme: Küçük Tuzaklar ve Tatlı Çözümler
İlk kurulumda her şey masal gibi akıyor, ama bazen ufak pürüzler çıkabiliyor. En yaygınlarından biri, ingress sırası. Daha genel bir kuralı üste, spesifiği alta yazınca “Neden 404?” diye bakakalıyorsunuz. Çözüm basit: Spesifik host kuralları her zaman üste.
Bir diğeri, içerideki servisinizin host header beklentisi. Bazı uygulamalar “Host: localhost:8080” görünce şaşırır, kendi domain adını ister. Bu durumda originRequest: httpHostHeader ile host başlığını hedef domain’e çevirirsiniz. Ayrıca, 502 hataları genelde içerideki servis kapalıyken ya da localhost yanlış porttayken çıkar. Loglara bakın; cloudflared bunu saklamaz, net söyler.
DNS tarafında “app.example.com” otomatik eklendiyse harika. Bazen aynı domain için eski bir kayıt kalmış olabilir; panelden temizleyin. Sağlam bir test için curl -I https://app.example.com ve cloudflared tunnel logs ikilisi çok şey anlatır. Geliştirme sırasında Access’i geçici olarak gevşetmek yerine kendinizi “Allow” politikasına ekleyin; unutulmuş açık kapı bırakmayın.
Güvenliği Bir Kademe Daha Yükseltmek: Pratik Öneriler
Güvenlikte küçük adımlar birikir. Mesela, Access’te kısa oturum süresi belirleyin, uzun süreli “Remember me” alışkanlığından kaçının. mTLS sertifikalarına ayrı isimler verin, proje bazlı ayırın. İptal etmeniz gerektiğinde tek bir sertifikayı hedefleyebilmek büyük rahatlık. İsteklerin gövdesi büyükse ve bir yük dengeleyiciye gidiyorsa, cloudflared’in zlib sıkıştırmasını ve HTTP/2 desteğini makul tutmak için ilgili ayarları keşfedin; kimi uygulama bu sayede nefes alır.
Güncellemeleri ihmal etmeyin. cloudflared sık sık iyileştirmeler alıyor; otomatik güncellemeyi sevmiyorsanız bile bir takvim koyun, ayda bir güncelleyin. Sertifika yenilemelerini, Access politikası değişikliklerini ve en önemlisi, kimlerin giriş denemesi yaptığını raporlayın. Bir bakışta anlaşılsın diye etiketler ve açıklamalar ekleyin.
Ek olarak, hassas değişkenleri (token, client secret, mTLS anahtarları) konfigürasyondan ayrı tutmak iyi bir alışkanlık. Dağıtım sürecinde gizleri elle değil, otomasyona bırakmak hem hızlandırır hem hata payını düşürür. Rotasyon için hafif ve güvenli bir araç zinciri seçmek, uzun vadede başınızı ağrıtmaz.
Adım Adım Bir Örnek Senaryo: Küçük Bir İç Uygulamayı Yayına Alalım
Somutlaştıralım. Diyelim ki içeride 8080’de çalışan bir Go uygulamanız var. Dışarıdan sadece ekibiniz erişsin, ayrıca API için de ayrı bir alt alan adı istiyorsunuz. mTLS ile sadece şirket cihazları girsin, misafir yok. Yol haritası şöyle akabilir:
Önce cloudflared’i kurdunuz ve giriş yaptınız. “blog-tunnel” ile tüneli oluşturdunuz. config.yml içine “app.example.com” için 8080, “api.example.com” için 9000 girdiniz; en alta 404 koydunuz. DNS rotası bitti. Testte her şey yerli yerinde, sayfalar akıyor.
Şimdi Access’e dönüp iki uygulama oluşturuyorsunuz: Biri app.example.com için, diğeri api.example.com için. Her ikisine de “@firma.com” ile biten e‑postaları dahil ediyorsunuz. Oturum süresini kısa tutuyor, deneme yanılma yaparken kendinizi ve bir test hesabını Allow’a ekleyip logları izliyorsunuz.
mTLS için Zero Trust panelinde cihaz sertifikaları üretiyorsunuz. Bu sertifikaları şirket cihazlarına profil üzerinden dağıtıyor, Access politikalarına “Require mTLS” şartını koyuyorsunuz. Misafir cihazla denediğinizde, giriş ekranını bile göremeyince doğru yoldasınız demektir. Son olarak SSH için “ssh.example.com” ekliyorsunuz; sadece SRE ekibi Access’te görünen gruptaysa geçebilsin. İstemci tarafında SSH config’i dokundu mu, tünelden SSH da tamam.
Dokümantasyon ve Küçük Pusulalar
Bir şeyleri ilk kez kurarken gözünüzün bir köşesinde kalması güzel olan kaynaklar var. Tünel yapısının şemasını ve olası gelişmiş seçenekleri görmek için Cloudflare Tunnel belgeleri sade ve güncel. Access tarafında politika örneklerini, grup/kural kombinasyonlarının nasıl işlendiğini ve mTLS adımlarını Self-hosted uygulama dokümanında buluyorsunuz. cloudflared’in sürüm notlarına ve platformlara göre kurulum paketlerine de sürüm sayfasından bakabilirsiniz. Kafanız karışırsa panik yok; en iyi öğrenme, ufak bir test alanında denemekle gelir.
Kapanış: Port Açmadan Yayın, Ama Kontrol Hep Sizde
Toparlayalım. Cloudflare Tunnel ile kapıları dışarıdan açmak yerine içeriden güvenli bir yol çiziyorsunuz. Bu yolun üzerine Zero Trust Access kurallarıyla kimlik, yetki ve oturum yönetimi koymak inanın çok rahatlatıcı. mTLS ile iki taraflı doğrulama eklemek ise “yanlış kişi kapıya gelse bile içeri adım atamaz” hissini veriyor. Kurulum basit, bakımı hafif, getirisi büyük.
Pratik bir tavsiye: Küçük başlayın. Önce tek bir uygulamayı tünelden çıkarın, Access’i ekleyin, sonra mTLS’yi devreye alın. Her katmanda loglara bakın, ufak bir ekip içinde test edin. En çok işinize yarayacak kısım, zamanla kendini belli ediyor. Ve unutmayın, tünel sadece bir boru değil; doğru kurallarla birleşince aslında akıllı bir kapı. Umarım bu yazı, port açmadan, NAT’la yorulmadan, ama daha güvenli bir şekilde yayına çıkmanıza yardımcı olur. Bir dahaki yazıda görüşmek üzere; sorularınız olursa yorumlarda beklerim.
