SSD Nodes Learn Hosting plans →
Rehberler Matt ConnorYazan Matt Connor · Güncellendi 2026-08-27

UFW ve IPv6: VPS sunucularında açık port riski

UFW kurallarınız IPv4 ile sınırlı kaldığında servisleriniz IPv6 üzerinden dış dünyaya açık kalır. Ubuntu 24.04 üzerinde bu güvenlik açığını nasıl tespit edip kapatacağınızı öğrenin.

Tek cümlede IPv6 güvenlik duvarı tuzağı

Güvenlik duvarınız IPv4 trafiğini korur ancak VPS sunucunuz büyük olasılıkla herkese açık bir IPv6 adresine de sahiptir ve birçok servis varsayılan olarak bu adres üzerinden dinleme yapar. Güvenlik duvarınız yalnızca IPv4 trafiğini kapsıyorsa veya yalnızca IPv4 filtreleyen bir bulut güvenlik duvarına güveniyorsanız, IPv4 tarafınız kapalı görünse bile tüm bu servisler internetin tamamından IPv6 üzerinden erişilebilir durumdadır. Bir portu curl ile test edip bağlantının reddedildiğini gördüğünüzde güvende olduğunuzu sanırsınız; ancak bir saldırgan aynı porta IPv6 üzerinden bağlanarak içeri sızabilir.

Bu kılavuz, standart bir Ubuntu 24.04 VPS üzerinde bu açığın nereden kaynaklandığını, neyi dışarıya açtığınızı nasıl göreceğinizi ve bu açığı nasıl kapatacağınızı gösterir. UFW burada suçlu değildir; modern bir Ubuntu kurulumunda UFW zaten IPv6 trafiğini yönetir. Güvenlik açığı, UFW'yi çevreleyen katmanlardan ve dinleme yaptığından haberdar olmadığınız servislerden kaynaklanır.

VPS sunucunuzun neden IPv6 kullandığı

Günümüzde neredeyse her VPS, IPv4 adresinin yanı sıra genellikle bir bütün halinde /64 ile birlikte genel bir IPv6 adresiyle gelir. Kendi adresinizi kontrol edin:

ip -6 addr show scope global
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
    inet6 2001:db8:2a::1/64 scope global

Bu 2001:db8:2a::1, tıpkı IPv4 adresiniz gibi internet üzerindeki herhangi bir noktadan erişilebilirdir. Şimdi nelerin dinleme modunda olduğuna bakın:

sudo ss -tlnp
State   Recv-Q  Local Address:Port   Process
LISTEN  0       0.0.0.0:22           sshd
LISTEN  0       [::]:22              sshd
LISTEN  0       127.0.0.1:5432       postgres
LISTEN  0       [::]:8080            docker-proxy

Local Address sütununu dikkatle inceleyin. 0.0.0.0:22, "tüm IPv4 adreslerini dinle" anlamına gelir. [::]:22, "tüm IPv6 adreslerini dinle" anlamına gelir. 127.0.0.1:5432 yalnızca loopback arayüzüne bağlıdır ve genel erişime açık değildir, bu nedenle Postgres satırı güvenlidir. İki adet [::] satırı, internetin tamamına IPv6 üzerinden yanıt verir; docker-proxy olan ise başlatıldığını unuttuğunuz türden bir servistir.

Çoğu daemon varsayılan olarak :: adresine bağlanır; çünkü Linux üzerinde bir :: soketi genellikle IPv4 trafiğini de kabul eder. Dolayısıyla yeni bir sunucunun varsayılan durumu "her iki yığında da, her yerden yanıt ver" şeklindedir. Bunun önündeki tek engel güvenlik duvarınızdır; bu yüzden yalnızca tek bir yığını gören bir güvenlik duvarı ciddi bir sorundur.

IPv6 boşluğunun gerçek kaynağı

Dört yaygın kaynak mevcuttur. Belirli bir sunucuda bunlardan biri veya birkaçı aynı anda bulunabilir.

1. Yalnızca IPv4 filtreleyen bir bulut güvenlik duvarı. Birçok sağlayıcı güvenlik duvarı ve güvenlik grubu ürünü IPv4 çevresinde gelişmiştir; bu ürünler ya IPv6'yı görmezden gelir ya da elle eklemeniz gereken ayrı IPv6 kurallarına ihtiyaç duyar. Tek güvenlik duvarınız sağlayıcı panelindeki ise ve bu panel IPv6'yı kapsamıyorsa, IPv4 üzerindeki 22 numaralı port hakkında ne söylerse söylesin [::] servisleriniz dış dünyaya açıktır. Sağlayıcınızın güvenlik duvarı belgelerini okuyun ve özellikle IPv6 kelimesini arayın.

2. ip6tables içermeyen manuel iptables yapılandırması. iptables komutu yalnızca IPv4 tablolarına etki eder. IPv6'nın kendine ait ayrı kuralları olan tamamen farklı bir komutu, yani ip6tables vardır. Eğer iptables -A INPUT ... satırlarıyla dolu bir güvenlik duvarı betiği yazdıysanız ve karşılığında ip6tables kurallarını oluşturmadıysanız, IPv6 güvenlik duvarınız boştur. Varsayılan ACCEPT politikasına sahip boş bir INPUT zinciri ise her şeye izin verir:

sudo ip6tables -L INPUT -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Bu çıktı, tuzağın tamamını tek bir ekranda gösterir. IPv4 filtrelenmiştir, IPv6 ise dünyaya açıktır.

3. Güvenlik duvarını devre dışı bırakarak portları doğrudan yayınlayan Docker. docker run -p 8080:80 komutunu çalıştırdığınızda Docker, kendi kurallarını UFW kurallarının önüne ekler. Bu nedenle, ufw status komutu o portun engellendiğini söylese bile yayınlanan bir porta erişilebilir; modern Docker sürümlerinde aynı durum IPv6 için de geçerlidir. Docker'ın neden UFW'yi devre dışı bıraktığı ve container portlarının nasıl düzgün filtreleneceği konusu mekanizmayı ve çözümleri açıklar. Bu yayınlanan portların nasıl tanımlandığını görmek için VPS üzerinde Docker Compose temelleri bölümüne bakın.

4. IPv6 desteği kapalı olan UFW. UFW, IPv6'yı destekler ancak bunun için komut verilmesi gerekir. Ayarı kontrol edin:

grep IPV6 /etc/default/ufw

Modern Ubuntu sürümleri IPV6=yes ile gelir, bu sayede UFW her kuralı her iki yığın (stack) için de uygular. Eğer eski bir imaj veya eski bir kılavuzdan kalma IPV6=no ifadesini görüyorsanız, yazdığınız her UFW kuralı yalnızca IPv4 için geçerlidir ve IPv6 yönetilmeden bırakılmıştır.

Neyi dışarıya açtığınızı tam olarak görün

Tahmin yürütmeyin. Dışarıdan ölçüm yapın. Öncelikle dinleyen servislerinizi listeleyin ve :: adresine bağlı olan her birini not edin:

sudo ss -tlnp | grep '::'

Ardından, farklı bir makineden sunucunun genel IPv6 adresine bağlanın ve kapalı olduğunu düşündüğünüz bir portu deneyin:

curl -6 -v http://[2001:db8:2a::1]:8080/

Eğer bu işlem bir sayfa veya banner döndürürse, port IPv6 üzerinde açıktır. Kapalı bir port size Connection refused hatası veya zaman aşımı verir. Bu iki hata aynı sinyal değildir ve reddedilme ile zaman aşımı arasındaki fark, ana makinenin yanıt verip sizi geri mi çevirdiğini yoksa bir güvenlik duvarının paketinizi sessizce mi düşürdüğünü size söyler. Tam bir resim elde etmek için, sunucunun dışından nmap ile IPv6 adresini tarayın:

nmap -6 2001:db8:2a::1

nmap'in IPv6 üzerinden açık olarak raporladığı her port, IPv4 taramanız ne gösterirse göstersin, tüm internetin erişebildiği bir porttur. IPv4 ve IPv6 taramalarını yan yana karşılaştırmak, aradaki farkı bulmanın en hızlı yoludur: -6 üzerinde açık olan ancak IPv4 üzerinde kapalı görünen her şey, güvenlik duvarınızda eksik olan bir servistir.

Açığı kapatın

UFW'nin her iki yığını da kapsamasını sağlayın ve varsayılan olarak reddetme kuralını uygulayın. Değişikliği onaylayın, ardından gelen trafik için varsayılan reddetme politikasını ayarlayın ve yalnızca ihtiyaç duyduğunuz trafiğe izin verin:

sudo sed -i 's/^IPV6=no/IPV6=yes/' /etc/default/ufw
sudo ufw default deny incoming
sudo ufw allow 22/tcp
sudo ufw enable
sudo ufw status verbose

IPV6=yes ayarını değiştirdiğinizde UFW zaten aktifse, değişiklik siz sudo ufw reload komutunu çalıştırana kadar devreye girmez.

ufw status her kuralı iki kez listeler; biri normal, diğeri (v6) soneki ile. (v6) satırlarını gördüğünüzde, UFW IPv6 trafiğini filtreliyor demektir:

22/tcp                     ALLOW IN    Anywhere
22/tcp (v6)                ALLOW IN    Anywhere (v6)

iptables yönetimini manuel yapıyorsanız, her kuralı ip6tables içinde de aynen uygulayın veya inet tabloları ile IPv4 ve IPv6'yı tek bir noktada birleştiren ve bu tür hataları tamamen ortadan kaldıran nftables'a geçiş yapın. Kuralları kendiniz yazıyorsanız, tek bir nftables inet filtre tablosu en temiz çözümdür. VPS'niz Ubuntu yerine Rocky veya AlmaLinux çalıştırıyorsa, yapılandırılacak bir UFW yoktur ve bunun yerine yönetmeniz gereken arayüz firewalld'dur; bu araç, bölge kurallarını her iki yığına da aynı anda uygular.

Dışarıya açık olmasını istemediğiniz servisleri loopback adresine bağlayın. Bir veritabanı, yönetim paneli veya metrik uç noktası genellikle genel bir adrese ihtiyaç duymaz. Bunları 127.0.0.1 ve ::1 adreslerine bağlayın; böylece hiçbir zaman yönlendirilebilir bir adres üzerinde dinleme yapmazlar. Postgres için listen_addresses = 'localhost' ayarını yapın. Bir uygulama sunucusu için ise 127.0.0.1 adresine bağlayın ve önüne bir reverse proxy yerleştirin. Dinleyiciyi kapatmak, onu güvenlik duvarı ile engellemekten daha etkilidir; çünkü bu durumda erişilebilecek bir port kalmaz.

Docker'ın yayınladığı portları koruması için UFW'ye güvenmeyin. Container portlarını her arayüz yerine belirli bir adrese yayınlayın; örneğin -p 127.0.0.1:8080:80. Böylece port yalnızca ana makineden ve sizin bilinçli olarak yönlendirdiğiniz trafikten erişilebilir olur. Bir container'ın mutlaka genel erişime açık olması gerekiyorsa, onu bir Traefik reverse proxy arkasına alın ve her uygulamayı değil, yalnızca proxy'yi yayınlayın.

Servis sağlayıcınızın güvenlik duvarına IPv6 kurallarını ekleyin veya bunun IPv6 için sizin güvenlik duvarınız olmadığını kabul edip bu işi ana makine üzerindeki UFW veya nftables'a bırakın.

Portun kapalı olduğunu doğrulayın

Yaptığınız değişikliklerden sonra dışarıdan yapılan testi tekrar çalıştırın:

curl -6 -v http://[2001:db8:2a::1]:8080/
nmap -6 2001:db8:2a::1

Daha önce yanıt veren portun artık bağlantıyı reddetmesi veya zaman aşımına uğraması gerekir; nmap çıktısında portun filtered veya closed olarak görünmesi beklenir. Eğer bir port hala açıksa, yukarıdaki dört kaynağı tekrar gözden geçirin: servis hala :: üzerinde dinleme yapıyor ve önünde bir kural bulunmuyor olabilir, UFW'nin önünde bir Docker kuralı kalmış olabilir veya sağlayıcı tarafındaki güvenlik duvarı IPv6 trafiğini hiç görmüyor olabilir.

Hassas servisleri genel internete tamamen kapatmak daha güvenli bir yöntemdir. SSH ve yönetim panellerini WireGuard VPN arkasına alın ve portlarını yalnızca tünel üzerinden yanıt verecek şekilde kısıtlayın; böylece IPv6 üzerinden erişilebilirlik sorunu bu servisler için ortadan kalkar. Genel erişime açık kalan servisleri hedef alan kaba kuvvet (brute-force) taramalarını yavaşlatmak için, varsayılan olarak reddeden bir güvenlik duvarının üzerine SSH için Fail2ban yapılandırın.

Port kavramı sizin için yeniyse, portların ne olduğu ve servislerin nasıl dinleme yaptığı konusundaki temel bilgileri içeren rehberi okuyun.

FAQ

UFW varsayılan olarak IPv6 trafiğini engeller mi?

Modern bir Ubuntu 24.04 kurulumunda evet. UFW, IPV6=yes dosyasını /etc/default/ufw üzerinden okur ve her kuralı hem IPv4 hem de IPv6 için uygular; ufw status komutu, IPv6 kurallarını (v6) sonekiyle listeler. Sorun, IPV6=no ayarı (eski bir imajdan veya eski bir rehberden kalma), yalnızca IPv4 filtreleyen bir sağlayıcı güvenlik duvarına güvenilmesi veya Docker'ın bir portu UFW'yi atlayarak dışarı açması durumunda ortaya çıkar. Ayarı grep IPV6 /etc/default/ufw ile kontrol edin.

VPS'imin IPv6 üzerinden neleri dışarı açtığını nasıl kontrol ederim?

sudo ss -tlnp komutunu çalıştırın ve yerel adresi [::] ile başlayan tüm dinleyicileri not edin; bu, servisin tüm IPv6 arayüzlerinde yanıt verdiği anlamına gelir. Ardından, farklı bir makineden sunucunun genel IPv6 adresini doğrudan curl -6 -v http://[YOUR:IPV6::ADDR]:PORT/ ile test edin veya nmap -6 YOUR:IPV6::ADDR ile tarayın. IPv6 taramasında açık görünen ancak IPv4'te kapalı olan her port bir güvenlik açığıdır.

UFW engellendiğini söylemesine rağmen Docker container portuna neden erişebiliyorum?

Docker, -p ile bir portu dışarı açtığınızda kendi güvenlik duvarı kurallarını UFW kurallarının önüne ekler; bu nedenle, ufw status listesinde reddedildiği görünse bile port erişilebilir kalır. Bu durum IPv4'te yaşanır; Docker'ın IPv6 desteği açıksa IPv6'da da gerçekleşir. Portu -p 127.0.0.1:8080:80 gibi belirli bir adrese bağlayın veya container'ı bir reverse proxy arkasına alıp yalnızca proxy'yi dışarı açın.

IPv4 güvenlik duvarım sağlamsa yine de IPv6 güvenlik duvarına ihtiyacım var mı?

Evet. IPv4 ve IPv6, ayrı güvenlik duvarı kurallarına sahip ayrı ağ yığınlarıdır. Mükemmel yapılandırılmış IPv4 kuralları, IPv6 trafiği üzerinde hiçbir etkiye sahip değildir. VPS'inizin genel bir IPv6 adresi varsa (neredeyse hepsinde bulunur), :: üzerinde dinleme yapan herhangi bir servis, bir IPv6 güvenlik duvarı kuralı veya loopback bağlaması ile engellenmediği sürece IPv6 üzerinden erişilebilir kalır.

Bir servisi yalnızca IPv4'te veya yalnızca localhost'ta dinleyecek şekilde nasıl ayarlarım?

Servisin kendi yapılandırma dosyasından bind adresini ayarlayın. Yalnızca IPv4 loopback için 127.0.0.1 adresine, IPv6 dinleyicisi olmadan tüm IPv4 adresleri için 0.0.0.0 adresine bağlayın. Postgres listen_addresses, SSH ListenAddress kullanır; çoğu uygulama sunucusu ise bir host veya bind bayrağı sunar. Sonucu sudo ss -tlnp ile doğrulayın ve Local Address çıktısında artık [::] görünmediğinden emin olun.