Geçen ay kendi VPS’ime kurduğum yeni bir monitoring servisini internete açmam gerekti. Klasik yöntemle 443 portunu açıp Nginx’i yönlendirebilirdim, ancak bu bana her zaman iç ağımı dışa açıyormuşum gibi bir tedirginlik veriyor. Özellikle bir bankanın iç platformu için çalışırken, en ufak bir açığın büyük riskler taşıdığını defalarca tecrübe ettim. İşte tam bu noktada, port açma riskini tamamen ortadan kaldıran Cloudflare Tunnel çözümü imdadıma yetişti.
Cloudflare Tunnel, sunucunuzdan Cloudflare ağına doğru giden şifreli bir tünel oluşturarak, hiçbir gelen portu (inbound port) açmadan servislerinizi güvenli bir şekilde internete sunmanızı sağlayan bir Zero Trust çözümüdür. Bu sayede, sunucularınızdaki güvenlik duvarı ayarlarını basitleştirir, DDoS saldırılarına karşı Cloudflare’ın geniş altyapısından faydalanır ve potansiyel zafiyet yüzeyini önemli ölçüde daraltırız. Bir uretim ERP’sinin operatör ekranlarını dışarıya açma ihtiyacımız olduğunda, bu yaklaşım bize ciddi bir güvenlik ve yönetim kolaylığı sağlamıştı.
Cloudflare Tunnel Nedir ve Neden Önemlidir?
Cloudflare Tunnel, adından da anlaşılacağı gibi, sunucunuz ile Cloudflare’ın küresel ağı arasında güvenli ve şifreli bir “tünel” oluşturan bir servistir. Bu tünel sayesinde, iç ağınızda çalışan herhangi bir servisi (web sunucusu, SSH, RDP, veritabanı vb.) doğrudan internete maruz bırakmadan, Cloudflare’ın proxy yetenekleri üzerinden yayınlayabilirsiniz.
Benim için en büyük avantajı, sunucumun güvenlik duvarında 80 veya 443 gibi genel HTTP/S portlarını açmak zorunda kalmamam oldu. Geleneksel yaklaşımlarda bir web servisini dışarıya açmak istediğimizde, ilgili portları açarız ve bu portlar potansiyel saldırganlar için birer giriş kapısı haline gelir. Cloudflare Tunnel ise bu paradigmayı tersine çevirerek, sunucudan Cloudflare’a doğru giden bir bağlantı kurar ve tüm trafik bu tünel üzerinden akar. Bu sayede, sunucumun dışarıya dönük hiçbir portu açık kalmaz, bu da brute-force, port scanning gibi saldırı vektörlerini büyük ölçüde ortadan kaldırır. Özellikle kendi yan ürünümün backend’ini dışarıya açarken bu yöntemi tercih ettim ve 7/24 gelen saldırı trafiğinin %99’undan fazlasını Cloudflare’ın üstlenmesi benim için büyük bir yükü kaldırdı.
Geleneksel Port Açma Yaklaşımının Riskleri Nelerdir?
Geleneksel olarak bir servisi internete açtığımızda, sunucumuzun güvenlik duvarında (firewall) ilgili portları (örneğin 80/443 HTTP/S için, 22 SSH için) açarız. Bu işlem, basit gibi görünse de beraberinde birçok güvenlik riskini getirir ve ben bu risklerle defalarca karşılaştım. Bir sunucuyu açtıktan 7 dakika sonra SSH portuna gelen brute-force saldırılarını gördüğümde, dışa açık her portun ne kadar hızlı hedef haline gelebildiğini anladım.
Bu risklerin başında artan saldırı yüzeyi gelir. Açık bir port, dışarıdan erişilebilir olduğu için, potansiyel saldırganlar tarafından taranabilir ve zafiyet arayışında kullanılabilir. Eğer serviste bilinen bir güvenlik açığı varsa, bu açık hızla istismar edilebilir. Ayrıca, açılan portlara yönelik DDoS saldırıları, sunucunuzun kaynaklarını tüketerek servis kesintilerine yol açabilir. Bir başka risk ise konfigürasyon hatalarıdır. Firewall kurallarını yanlış yapılandırmak, beklenenden daha geniş erişim yetkileri vermek veya gereksiz portları açık bırakmak kolayca yapılabilecek hatalardır ve bu hatalar genellikle fark edilene kadar büyük sorunlara yol açar. Örneğin, bir üretim ERP’sinde bir kereliğine açılan test portunun unutulması ve bu port üzerinden dışarıya sızan verileri tespit etmek bize 3 gün kaybettirmişti. Cloudflare Tunnel, bu tür riskleri ortadan kaldırarak daha güvenli bir altyapı sunar.
Cloudflare Tunnel Nasıl Çalışır: Zero Trust Ağının Temeli
Cloudflare Tunnel’ın çalışma mantığı, geleneksel ağ mimarisinin aksine, bağlantıyı sunucudan Cloudflare’a doğru başlatmasıdır. Bu, “inbound connection” yerine “outbound connection” prensibine dayanır ve Zero Trust mimarisinin temel taşlarından biridir. Sunucunuzda çalışan cloudflared adında küçük bir daemon (servis), sürekli olarak Cloudflare ağına doğru şifreli bir TCP bağlantısı kurar ve bu bağlantıyı canlı tutar.
Kullanıcılar sitenize veya servisinize erişmek istediğinde, istekleri doğrudan Cloudflare ağına gelir. Cloudflare, bu isteği tünel üzerinden sunucunuzdaki cloudflared daemon’ına iletir. cloudflared bu isteği alır, yerel ağdaki ilgili servise yönlendirir, yanıtı alır ve tekrar tünel üzerinden Cloudflare’a geri gönderir. Cloudflare da bu yanıtı son kullanıcıya iletir. Bu akış sayesinde, sunucunuzun internete dönük hiçbir dinleme portu olmaz; tüm iletişim Cloudflare’ın güvenli altyapısı üzerinden gerçekleşir. Bu model, özellikle uzaktan erişim (VPN/ZTNA) mimarilerinde sıkça gördüğüm, dışarıdan gelen trafiği doğrudan iç ağa sokmama prensibiyle birebir örtüşüyor. Bir müşteri projesinde, çalışanların dahili uygulamalara erişimini ZTNA ile sağlarken benzer bir mimariyi kullanmıştık.
graph TD; A["Son Kullanıcı"] --> B["Cloudflare Edge"]; B --> C["Cloudflare Tunnel"]; C --> D["Sunucu (cloudflared)"]; D --> E["Lokal Servis (Nginx/Postgres/SSH)"]; E --> D; D --> C; C --> B; B --> A;
Cloudflare Tunnel Kurulumu: Adım Adım Rehber
Cloudflare Tunnel kurulumu birkaç basit adımdan oluşuyor ve genellikle 15-20 dakikamı alıyor. İşte kendi VPS’imde ve bir üretim ERP’sinde uyguladığım adımlar:
1. Cloudflare Hesabı ve Alan Adı (Domain) Kurulumu
Öncelikle aktif bir Cloudflare hesabınız ve Cloudflare’a yönlendirilmiş bir alan adınız olmalı. Alan adınızın DNS kayıtları Cloudflare üzerinden yönetiliyor olmalı. Eğer henüz bir alan adınız yoksa, bir tane alıp Cloudflare’a eklemeniz gerekiyor. Ben genellikle DNSSEC’i de aktif ediyorum, ek bir güvenlik katmanı sağlıyor.
2. cloudflared Daemon’ının Yüklenmesi
Sunucunuza cloudflared aracını kurmanız gerekiyor. Bu araç, tüneli Cloudflare ağına bağlayacak olan istemci yazılımıdır. Linux için genelde aşağıdaki adımları izlerim:
# İlk olarak gerekli paketleri yükleyelim
sudo apt update && sudo apt install -y curl lsb-release
# Cloudflare repository'sini ekleyelim
curl -fsSL https://pkg.cloudflare.com/cloudflare-repo.gpg | sudo gpg --dearmor -o /usr/share/keyrings/cloudflare-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/cloudflare-archive-keyring.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflared.list > /dev/null
# cloudflared'ı yükleyelim
sudo apt update && sudo apt install cloudflared
Yükleme sonrası cloudflared --version komutu ile doğru kurulup kurulmadığını kontrol edebiliriz.
3. cloudflared Yetkilendirmesi
cloudflared’ı yükledikten sonra, onu Cloudflare hesabınızla ilişkilendirmeniz gerekiyor. Bu, bir tarayıcı aracılığıyla yapılan bir yetkilendirme işlemidir:
cloudflared tunnel login
Bu komutu çalıştırdığınızda, size bir URL verecek. Bu URL’yi tarayıcınızda açın, Cloudflare hesabınıza giriş yapın ve tünelinizi hangi alan adı için yetkilendireceğinizi seçin. Başarılı bir yetkilendirme sonrası, ~/.cloudflared/cert.pem yolunda bir sertifika dosyası oluşturulacaktır. Bu sertifika, cloudflared’ın Cloudflare ağına güvenli bir şekilde bağlanmasını sağlar.
4. Yeni Bir Tunnel Oluşturma
Şimdi bir tünel oluşturalım. Tünel ismini genellikle servisi tanımlayacak şekilde veririm, örneğin monitoring-app veya erp-frontend.
cloudflared tunnel create my-first-tunnel
Bu komut size bir Tunnel ID döndürecek ve ~/.cloudflared/<Tunnel-ID>.json yolunda bir kimlik doğrulama dosyası oluşturacaktır. Bu JSON dosyası, tünelin kimliğini doğrulamak için kullanılır ve kesinlikle güvende tutulmalıdır. Bu Tunnel ID’yi not alın, çünkü konfigürasyon dosyasında kullanacağız.
5. Tunnel Konfigürasyon Dosyası Oluşturma
Tünelin hangi gelen istekleri hangi yerel servislere yönlendireceğini belirtmek için bir YAML konfigürasyon dosyası oluşturmamız gerekiyor. Ben genellikle bu dosyayı /etc/cloudflared/config.yaml yoluna yerleştiririm.
# /etc/cloudflared/config.yaml
tunnel: <Tunnel-ID> # create komutundan aldığınız Tunnel ID
credentials-file: /root/.cloudflared/<Tunnel-ID>.json # kimlik doğrulama dosyasının yolu
ingress:
- hostname: myapp.example.com
service: http://localhost:8080
- hostname: ssh.example.com
service: ssh://localhost:22
- service: http_status:404 # Yukarıdaki hostname'lere uymayan tüm istekler için 404 döndür
Yukarıdaki örnekte myapp.example.com adresine gelen tüm istekler sunucudaki 8080 portuna, ssh.example.com adresine gelen istekler ise 22 portuna yönlendirilecek. http_status:404 ise, tanımlanan hostname’ler dışında gelen tüm istekleri reddetmek için bir catch-all kuralıdır. Bu, güvenliğin temelini oluşturur: sadece izin verilenleri yönlendir, gerisini blokla.
6. DNS Kayıtlarını Oluşturma
Cloudflare panelinizde, tünelinize yönlendireceğiniz her bir hostname için CNAME DNS kaydı oluşturmanız gerekiyor. Örneğin myapp.example.com için:
- Type: CNAME
- Name:
myapp - Target:
<Tunnel-ID>.cfargotunnel.com - Proxy Status: Proxied (bulut simgesi turuncu olmalı)
Bu kayıt, myapp.example.com adresine gelen isteklerin Cloudflare ağına yönlendirilmesini sağlar ve tünel üzerinden servisinize ulaşmasını mümkün kılar.
7. Tunnel’ı Servis Olarak Çalıştırma
cloudflared’ı bir systemd servisi olarak çalıştırmak, sunucu yeniden başladığında otomatik olarak başlamasını ve sürekli aktif kalmasını sağlar.
sudo systemctl enable cloudflared tunnel run my-first-tunnel
sudo systemctl start cloudflared tunnel run my-first-tunnel
sudo systemctl status cloudflared tunnel run my-first-tunnel
systemctl status komutu ile servisin çalıştığından emin olun. Eğer bir sorun varsa, journalctl -u cloudflared komutu ile logları inceleyebilir ve sorun giderme yapabilirsiniz. Geçen ay bir cloudflared servisini ayağa kaldırırken cgroup memory.high limitini yanlış ayarladığım için OOM-killed olmuştu, logları inceleyerek cloudflared’a daha fazla hafıza ayırmam gerektiğini anlamıştım.
Gelişmiş Konfigürasyonlar ve Kullanım Senaryoları
Cloudflare Tunnel, sadece basit HTTP/S servislerini yayınlamaktan çok daha fazlasını yapabiliyor. Ben kendi geliştirdiğim Android spam uygulamamın backend’i için, ya da bir müşteri projesinde dahili bir veritabanı erişimi için farklı senaryolarda kullandım.
Dahili Servislerin Güvenli Erişimi
Cloudflare Tunnel ile sadece web servislerini değil, SSH, RDP, veritabanı (PostgreSQL, MySQL vb.) gibi dahili servisleri de güvenli bir şekilde dışarıya açabilirsiniz. Örneğin, bir geliştirme ekibinin uzaktan bir PostgreSQL veritabanına erişmesi gerektiğinde, doğrudan port açmak yerine Cloudflare Tunnel kullanabiliriz.
# /etc/cloudflared/config.yaml (PostgreSQL için)
tunnel: <Tunnel-ID>
credentials-file: /root/.cloudflared/<Tunnel-ID>.json
ingress:
- hostname: pgadmin.example.com
service: http://localhost:5050 # PgAdmin paneli
- hostname: postgres.example.com
service: tcp://localhost:5432 # Doğrudan PostgreSQL bağlantısı
originRequest:
noTLSVerify: true # Yerel PostgreSQL genelde TLS kullanmaz, dikkatli olun
- service: http_status:404
Bu şekilde, pgadmin.example.com üzerinden PgAdmin paneline, postgres.example.com üzerinden ise PostgreSQL veritabanına doğrudan TCP bağlantısı kurabiliriz. Ancak noTLSVerify gibi ayarlar güvenlik riskleri taşıyabilir, bu yüzden dikkatli kullanılmalı ve mümkünse yerel servislerde de TLS aktif edilmelidir.
Cloudflare Access ile Kimlik Doğrulama Katmanı Ekleme
Cloudflare Access, tünel üzerinden yayınladığınız servislere erişimi kimlik tabanlı olarak kontrol etmenizi sağlar. Bu, Zero Trust mimarisinin temel bir parçasıdır. Örneğin, pgadmin.example.com adresine sadece belirli e-posta adreslerine sahip kişilerin erişmesini sağlayabilirim.
- Cloudflare Panelinde Uygulama Oluşturma: Cloudflare Dashboard’da “Access” sekmesine gidin ve “Applications” altında yeni bir uygulama oluşturun.
- Hostname Belirtme: Uygulamanın koruyacağı hostname’i (
pgadmin.example.comgibi) belirtin. - Politikalar Tanımlama: Kimlerin erişebileceğini belirleyen kurallar oluşturun (örneğin, “Email is @example.com”).
- Identity Provider Entegrasyonu: Google Workspace, Okta, Azure AD gibi bir Identity Provider ile entegrasyon yaparak kullanıcı kimliklerini doğrulayın.
Bu sayede, kullanıcılar pgadmin.example.com adresine erişmeye çalıştıklarında önce Cloudflare Access tarafından kimlik doğrulamasına tabi tutulur. Başarılı olurlarsa tünel üzerinden servise yönlendirilirler. Bu yöntem, özellikle dahili araçlarımızı dışarıya açarken ekstra bir güvenlik katmanı sağlıyor ve VPN ihtiyacını ortadan kaldırıyor.
Yük Dengeleme (Load Balancing) ve Yüksek Erişilebilirlik
Birden fazla sunucuda aynı servisi çalıştırıyorsanız, Cloudflare Tunnel ile yük dengeleme yapabilirsiniz. Her sunucuda ayrı bir cloudflared daemon çalıştırılır ve aynı tünel ID ile Cloudflare’a bağlanır. Cloudflare, gelen trafiği bu tüneller arasında otomatik olarak dengeleyebilir.
# Sunucu A'daki config.yaml
tunnel: <Tunnel-ID>
credentials-file: /root/.cloudflared/<Tunnel-ID>.json
ingress:
- hostname: myapp.example.com
service: http://localhost:8080
- service: http_status:404
# Sunucu B'deki config.yaml (aynı Tunnel ID ile)
tunnel: <Tunnel-ID>
credentials-file: /root/.cloudflared/<Tunnel-ID>.json
ingress:
- hostname: myapp.example.com
service: http://localhost:8080
- service: http_status:404
Cloudflare, bu iki tünel arasında round-robin veya daha gelişmiş algoritmalarla (health checks ile birlikte) yükü dengeleyebilir. Bu, bir sunucu çöktüğünde bile servisin çalışmaya devam etmesini sağlar ve yüksek erişilebilirlik (High Availability) için önemli bir adımdır. Bir uretim ERP’sindeki gerçek zamanlı dashboard tasarımlarında bu tür bir mimariyi kullanmıştık, böylece tek bir sunucunun düşmesi tüm operasyonu durdurmuyordu.
Cloudflare Tunnel ile Elde Ettiğim Faydalar ve Trade-off’lar
Cloudflare Tunnel’ı yıllardır çeşitli projelerimde aktif olarak kullanıyorum ve benim için getirdiği faydalar oldukça somut. Ancak her teknolojide olduğu gibi, burada da bazı trade-off’lar mevcut.
Faydaları:
- Gelişmiş Güvenlik: En büyük fayda. Sunucularımın dışa dönük portlarını tamamen kapatabildiğim için saldırı yüzeyim minimuma iniyor. DDoS koruması ve WAF (Web Application Firewall) gibi Cloudflare özelliklerini doğrudan kullanabiliyorum. Bir üretim ERP’sinde, dışarıdan gelen SQL injection denemelerinin Cloudflare WAF tarafından otomatik engellenmesi, bizim için önemli bir iş yükünü ortadan kaldırmıştı.
- Basit Konfigürasyon: Port yönlendirmeleri, NAT ayarları veya karmaşık güvenlik duvarı kuralları ile uğraşmak zorunda kalmıyorum. Tek bir
cloudflaredservisi ve basit bir YAML dosyasıyla işimi hallediyorum. - Zero Trust Entegrasyonu: Cloudflare Access ile entegrasyon, dahili servislerime erişimi kimlik tabanlı olarak yönetmeme olanak tanıyor. Bu, VPN’e olan ihtiyacı azaltıyor veya tamamen ortadan kaldırıyor.
- Performans ve Güvenilirlik: Cloudflare’ın küresel CDN ağı sayesinde, kullanıcılar en yakın Cloudflare Edge lokasyonundan servise bağlanır, bu da gecikmeyi azaltır. Ayrıca, Cloudflare’ın geniş altyapısı sayesinde yüksek erişilebilirlik ve otomatik failover sağlıyor.
Trade-off’ları:
- Vendor Lock-in: Cloudflare ekosistemine bağımlı hale geliyorsunuz. Eğer Cloudflare servislerinde bir kesinti yaşanırsa, tünel üzerinden yayınladığınız servisler de etkilenebilir. Ancak Cloudflare’ın uptime oranları genellikle çok yüksek olduğu için bu riski göze alabiliyorum.
- Ekstra Gecikme: Trafik, sunucunuzdan Cloudflare’a, oradan da kullanıcıya gittiği için teorik olarak çok küçük bir ekstra gecikme (latency) yaşanabilir. Ancak bu gecikme genellikle göz ardı edilebilir seviyededir ve Cloudflare’ın CDN avantajlarıyla dengelenir. Kendi yan ürünümde yaptığım testlerde, doğrudan erişime kıyasla ortalama 10-20ms’lik bir artış gözlemledim, bu da kullanıcı deneyimini etkilemedi.
- Eğitim Maliyeti: Yeni bir araç olduğu için, ekibinizdeki diğer kişilerin
cloudflared’ın nasıl çalıştığını ve nasıl yönetileceğini öğrenmesi gerekebilir.
Genel olarak, güvenlik ve yönetim kolaylığı açısından Cloudflare Tunnel’ın sunduğu faydalar, benim için bu trade-off’ları fazlasıyla karşılıyor. Özellikle güvenlik açıklarıyla uğraşmak yerine, işimin asıl kısmına odaklanmak istediğimde Cloudflare Tunnel vazgeçilmez bir araç haline geliyor.
Sonuç
Port açmadan servislerinizi internete sunmak, modern güvenlik yaklaşımlarının temelini oluşturan bir prensiptir ve Cloudflare Tunnel bu prensibi pratik bir şekilde hayata geçirmenizi sağlar. Geleneksel port açma yöntemlerinin getirdiği riskleri minimize ederek, sunucularınızın güvenlik duruşunu önemli ölçüde güçlendirirsiniz. Ben kendi projelerimde ve müşteri çalışmalarımda bu teknolojiyi aktif olarak kullanarak hem güvenlikten ödün vermiyorum hem de operasyonel karmaşıklığı azaltıyorum.
Umarım bu rehber, Cloudflare Tunnel’ın ne olduğunu, nasıl çalıştığını ve nasıl kurulacağını anlamanıza yardımcı olmuştur. Güvenli bir altyapı oluşturma yolculuğunda bu aracın size de büyük kolaylıklar sağlayacağına eminim. Bir sonraki yazımda, systemd unit’lerinde yaşadığım ilginç bir cgroup limit hatasını ve bunu nasıl çözdüğümü anlatacağım.