SSD Nodes Learn
Rehberler Matt ConnorYazan Matt Connor · Güncellendi 2026-07-24

UFW ve IPv6 Güvenlik Duvarı Sorunu Çözümü

UFW kurallarının yalnızca IPv4 için geçerli kalması VPS sunucunuzda açık kapı bırakır. IPv6 üzerinden gelen sızmaları önlemek için izlenmesi gereken adımlar.

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

Güvenlik duvarınız IPv4 trafiğini korur. VPS sunucunuzun büyük olasılıkla bir kamuya açık IPv6 adresi vardır ve birçok servis varsayılan olarak bu adres üzerinden dinleme yapar. Eğer güvenlik duvarınız yalnızca IPv4'ü kapsıyorsa veya yalnızca IPv4 filtreleyen bir bulut güvenlik duvarına güveniyorsanız, IPv4 tarafı tamamen kapalı görünse bile bu servislerin her biri IPv6 üzerinden tüm internetten erişilebilir durumdadır. Bir portu curl ile test eder, bağlantının reddedildiğini görür ve güvende olduğunuzu hissedersiniz. Bir saldırgan ise aynı porta IPv6 üzerinden bağlanarak içeri sızar.

Bu kılavuz, standart bir Ubuntu 24.04 VPS üzerinde bu boşluğun neden kaynaklandığını, neleri dış dünyaya açtığınızı tam olarak nasıl göreceğinizi ve bu boşluğu nasıl kapatacağınızı göstermektedir. Buradaki sorun UFW değildir. Modern bir Ubuntu kurulumunda UFW, IPv6 trafiğini halihazırda yönetmektedir. Güvenlik açığı, UFW'nin etrafındaki katmanlardan ve dinleme yaptığını bilmediğiniz servislerden kaynaklanmaktadır.

VPS cihazınızın neden IPv6 kullandığına dair temel nedenler

Günümüzde hemen hemen her VPS, IPv4 adresinin yanı sıra genellikle tam bir /64 ile birlikte halka açık bir IPv6 adresiyle birlikte 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 yerden yönlendirilebilir durumdadır. Şimdi hangi servislerin dinlemede olduğunu inceleyin:

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 dikkatlice okuyun. 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 loopback adresine bağlıdır ve tamamen halka açık değildir, bu nedenle Postgres satırı güvenlidir. İki adet [::] satırı IPv6 üzerinden tüm internete yanıt verir; docker-proxy satırı ise genellikle başlatıldığı unutulan türdendir.

Çoğu daemon varsayılan olarak :: adresine bağlanır; çünkü Linux üzerinde bir :: soketi genellikle IPv4'ü de kabul eder. Bu nedenle, yeni bir sunucunun varsayılan durumu "her iki protokol yığınında da, her yerde yanıt ver" şeklindedir. Bunu engelleyen tek şey güvenlik duvarınızdır; bu yüzden sadece tek bir protokol yığınını gören bir güvenlik duvarı ciddi bir sorun teşkil eder.

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

Dört yaygın kaynak bulunmaktadır. Belirli bir sistemde bunlardan biri veya birkaçı aynı anda bulunabilir.

1. Sadece IPv4 filtreleyen bir bulut güvenlik duvarı. Birçok sağlayıcı güvenlik duvarı ve security-group ürünü IPv4 üzerine geliştirilmiştir; bu ürünler ya IPv6'yı görmezden gelir ya da manuel olarak eklenmesi gereken ayrı IPv6 kurallarına ihtiyaç duyar. Eğer tek güvenlik duvarınız sağlayıcı panelindeki araç ise ve IPv6'yı kapsamıyorsa, IPv4 port 22 hakkında ne yazdığına bakılmaksızın [::] servisleriniz dış dünyaya açıktır. Sağlayıcınızın güvenlik duvarı dokümantasyonunu okuyun ve özellikle IPv6 ifadesini arayın.

2. ip6tables içermeyen, manuel yazılmış iptables. iptables komutu sadece IPv4 tablolarını etkiler. IPv6, kendine ait kuralları olan tamamen ayrı bir ip6tables komutuna sahiptir. Eğer iptables -A INPUT ... satırlarıyla dolu bir güvenlik duvarı betiği yazdıysanız ve karşılık gelen ip6tables kurallarını hiç yazmadıysanız, IPv6 güvenlik duvarınız boştur. Varsayılan ACCEPT politikasına sahip boş bir INPUT zinciri her şeye izin verir:

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

Bu çıktı, tüm tuzağı tek bir ekranda göstermektedir. IPv4 filtrelenirken, IPv6 tüm dünyadan gelen bağlantıları kabul eder.

3. Docker'ın portları güvenlik duvarını doğrudan aşması. docker run -p 8080:80 çalıştırıldığında, Docker kendi kurallarını UFW kurallarının önüne ekler. Bu nedenle, bir port yayınlandığında, ufw status o portun engellendiğini söylese bile porta erişilebilir; modern Docker sürümlerinde aynı durum IPv6 için de geçerlidir. Neden Docker, UFW'yi atlar ve konteyner portları nasıl düzgün filtrelenir içeriği mekanizmayı ve çözümleri açıklar. Yayınlanan portların nasıl tanımlandığını öğrenmek için bir VPS üzerinde Docker Compose temelleri kısmına bakın.

4. IPv6'nın kapalı olduğu UFW. UFW, IPv6'yı yönetebilir ancak sadece bu talimat verildiğinde. Ayarı kontrol edin:

grep IPV6 /etc/default/ufw

Modern Ubuntu sürümleri IPV6=yes ile birlikte gelir, bu nedenle UFW her kuralı her iki protokol yığınına da uygular. Eski bir imajdan veya eski bir kılavuzdan kaynaklı IPV6=no ifadesini görüyorsanız, yazdığınız tüm UFW kuralları sadece IPv4 içindir ve IPv6 yönetimsiz bırakılmıştır.

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

Tahmin yürütmeyin. Dışarıdan ölçüm yapın. İlk olarak dinleyicileri 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 bir sayfa veya banner dönerse, port IPv6 üzerinde açıktır. Kapalı bir port Connection refused veya zaman aşımı (timeout) döndürür. Tam bir tablo elde etmek için, sunucu dışından nmap ile IPv6 adresini tarayın:

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

nmap tarafından IPv6 üzerinden açık olarak raporlanan her port, IPv4 taramanız ne gösterirse göstersin, tüm internetin erişebileceğ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 olup IPv4 üzerinde kapalı olan her şey, güvenlik duvarınızın (firewall) gözünden kaçan bir servistir.

Close the gap

Make UFW cover both stacks, and default to deny. Confirm the switch, then set a default-deny inbound policy and allow only what you need:

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

If UFW was already active when you flipped IPV6=yes, the change does not take effect until you run sudo ufw reload.

ufw status lists each rule twice, once plain and once with a (v6) suffix. When you see the (v6) lines, UFW is filtering IPv6:

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

If you manage iptables by hand, mirror every rule in ip6tables, or move to nftables, whose inet tables cover IPv4 and IPv6 in one place and remove this whole class of mistake. A single nftables inet filter table is the cleanest fix when you are writing rules yourself.

Bind services you do not want public to loopback. A database, an admin panel, or a metrics endpoint rarely needs a public address at all. Bind it to 127.0.0.1 and ::1 so it never listens on a routable address in the first place. For Postgres, set listen_addresses = 'localhost'. For an app server, bind it to 127.0.0.1 and put a reverse proxy in front. Closing the listener beats firewalling it, because then there is nothing to reach.

Do not trust UFW to guard Docker's published ports. Publish container ports to a specific address rather than every interface, for example -p 127.0.0.1:8080:80, so the port is reachable only from the host and whatever you deliberately proxy to it. When a container genuinely must be public, put it behind a Traefik reverse proxy and publish only the proxy, not each app.

Add IPv6 rules to your provider firewall, or accept that it is not your firewall for IPv6 and let UFW or nftables on the host do that job instead.

Bağlantının gerçekten kesildiğini doğrulayın

Değişikliklerden sonra aynı dış 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 port artık bağlantıyı reddetmeli veya zaman aşımına uğramalıdır; nmap ise portun filtered veya closed olduğunu raporlamalıdır. Eğer bir port hâlâ açıksa, yukarıdaki dört kaynağı kontrol edin: önünde kural bulunmayan ve :: portuna bağlı kalan bir servis, UFW'den önce çalışan bir Docker kuralı veya IPv6 trafiğini hiç görmeyen bir sağlayıcı firewall'u.

Hassas servisleri tamamen halka açık internetten uzak tutmak daha güvenlidir. SSH ve yönetim panellerini WireGuard VPN arkasına koyun ve portlarını sadece tünel üzerinden yanıt verecek şekilde firewall ile koruyun; böylece IPv6 maruziyeti sorunu bu servisler için geçerliliğini yitirir. Halka açık kalan servisleri hedef alan brute-force taramalarını yavaşlatmak için, varsayılan olarak her şeyi engelleyen (default-deny) bir firewall üzerine SSH önüne Fail2ban ekleyin katmanını uygulayın.

Port kavramı yeniyse, portlar nedir ve servisler nasıl dinleme yapar başlıklı rehberi önce okuyun.

FAQ

UFW varsayılan olarak IPv6'yı engeller mi?

Modern bir Ubuntu 24.04 kurulumunda evet. UFW, /etc/default/ufw dosyasından IPV6=yes verisini okur ve her kuralı hem IPv4 hem de IPv6 için uygular; ufw status, IPv6 kurallarını (v6) soneki ile gösterir. Sorunlar şu durumlarda ortaya çıkar: IPV6=no kullanımı (eski bir imaj veya eski bir eğitimden kaynaklı), yalnızca IPv4 filtreleyen bir sağlayıcı güvenlik duvarına güvenilmesi veya Docker'ın bir portu UFW'yi atlayarak yayınlaması. Durumu 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üzlerinden 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 olan ancak IPv4'te kapalı olan her port bir güvenlik açığıdır.

UFW engellediğini söylerken Docker konteyner portuma neden erişebiliyorum?

-p ile bir port yayınladığınızda, Docker kendi güvenlik duvarı kurallarını UFW'den önce ekler; bu nedenle yayınlanan porta, ufw status bu portu reddedilmiş olarak listese bile erişilebilir. Bu durum IPv4'te ve 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 yayınlayın veya konteyneri bir reverse proxy arkasına koyarak yalnızca proxy'yi yayınlayın.

IPv4 güvenlik duvarım sağlamsa hala bir 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. Kusursuz bir IPv4 kural seti, IPv6 trafiği için bir işlem yapmaz. Eğer VPS'inizin bir genel IPv6 adresi varsa (ki çoğu cihazda vardır), :: üzerinde dinleme yapan her servis, bir IPv6 güvenlik duvarı kuralı veya loopback bağlaması engelleyene kadar IPv6 üzerinden erişilebilir kalır.

Bir servisin yalnızca IPv4'ü veya yalnızca localhost'u dinlemesini nasıl sağlarım?

Servisin bind adresini kendi yapılandırma dosyasında ayarlayın. Yalnızca IPv4 loopback için 127.0.0.1 adresine, IPv6 dinleyicisi olmadan tüm IPv4 adreslerine bağlamak için ise 0.0.0.0 adresine bağlayın. Postgres listen_addresses kullanır, SSH ListenAddress kullanır ve çoğu uygulama sunucusu 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.