Linux servisleri hangi portu dinliyor nasıl öğrenilir?
Linux sunucunuzda hangi servislerin hangi portları kullandığını ss komutu ile inceleyin. Yerel ve genel port farklarını, 1024 altı port kısıtlamalarını ve TCP/UDP ayrımını öğrenin.
Port nedir?
Port, bir sunucunun trafiği birbirine karıştırmadan aynı anda birçok servisi çalıştırmasına olanak tanıyan bir numaradır. VPS'nizin tek bir IP adresi vardır ancak aynı anda bir web sunucusu, bir SSH sunucusu ve bir veritabanı çalıştırıyor olabilir. Bir paket ulaştığında işletim sisteminin bu paketin hangisi için olduğunu bilmesi gerekir. Port numarası bu sorunun cevabıdır. HTTPS trafiği normalde 443 numaralı porta, SSH ise 22 numaralı porta gider. IP adresi paketi sunucunuza ulaştırır; port ise paketi o sunucudaki doğru programa iletir.
Port 16 bitlik bir sayıdır: 16 bit 0 ile 65535 arasında değer sağlar ve 0 ayrılmış olduğundan portlar pratikte 1 ile 65535 arasında çalışır. 1024'ün altındaki portlar "iyi bilinen" (well-known) portlardır ve Linux varsayılan olarak bunları yalnızca root kullanıcısının (veya CAP_NET_BIND_SERVICE yetkisi verilmiş bir programın) açmasına izin verir; standart servislerin burada bulunmasının nedeni budur: SSH için 22, HTTP için 80, HTTPS için 443, DNS için 53. net.ipv4.ip_unprivileged_port_start sysctl ayarı bu sınırı değiştirebilir ancak varsayılan değer 1024'tür. 1024 ve üzerindeki her port sıradan programlar için kullanılabilir.
TCP ve UDP olmak üzere iki tür vardır ve birindeki port numarası diğerindeki aynı numaradan bağımsızdır. TCP, SSH, HTTP ve veritabanları gibi çoğu servisin kullandığı bağlantı tabanlı protokoldür. UDP bağlantısızdır ve DNS ile bazı VPN'ler gibi servisler için kullanılır. Bir güvenlik duvarı açarken genellikle protokolü belirtirsiniz, örneğin 22/tcp.
Dinleme, bir programın port üzerinde beklemesi anlamına gelir
Bağlantı kabul etmek isteyen bir program, çekirdekten bir port üzerinde "dinleme" yapmasını ister. O andan itibaren port makine üzerinde açılır ve güvenlik duvarı kurallarına bağlı olarak, programa gelen her türlü veriye yanıt verilir. Dinleme yapan hiçbir programın olmadığı bir port, bağlantıları doğrudan reddeder. Bu nedenle herhangi bir güvenlik denetimindeki ilk soru şudur: ne dinleniyor ve nerede.
Bunu yanıtlamak için kullanılan komut ss şeklindedir:
sudo ss -tlnpBayraklar; TCP (t), yalnızca dinleme yapan soketler (l), sayısal portlar (n, böylece ssh yerine 22 görürsünüz) ve sahip olan süreci (p) ifade eder. Tipik bir sonuç şöyledir:
State Recv-Q Local Address:Port Process
LISTEN 0 0.0.0.0:22 sshd
LISTEN 0 127.0.0.1:5432 postgres
LISTEN 0 [::]:80 nginxProcess sütunu, her bir portun hangi programa ait olduğunu belirtir; çalışır durumda bırakmak istemediğiniz bir süreci bu şekilde tespit edebilirsiniz.
Yerel Adres sütunu önemlidir
Her portun önündeki adresi dikkatlice okuyun, çünkü servise kimin erişebileceğine bu karar verir. Sürekli karşılaşacağınız üç durum vardır.
0.0.0.0:22, "bu makinedeki tüm IPv4 adreslerini dinle" anlamına gelir; buna genel (public) IP adresi de dahildir. Güvenlik duvarı izin veriyorsa servis internet üzerinden IPv4 ile erişilebilir durumdadır.
[::]:80, IPv6 için aynı anlama gelir: genel adresler dahil tüm IPv6 adreslerini dinler. Birçok program varsayılan olarak buraya bağlanır ve Linux üzerinde bir :: soketi genellikle IPv4 trafiğini de kabul eder.
127.0.0.1:5432, "yalnızca loopback üzerinden dinle" anlamına gelir. 127.0.0.1, bir makinenin kendisiyle konuşmak için kullandığı adrestir ve çekirdeğin varsayılan ayarlarında başka hiçbir yerden yönlendirilemez. Buraya bağlı bir servis, güvenlik duvarınız portu açsa bile internetten değil, yalnızca aynı sunucudan erişilebilir durumdadır. Yukarıdaki Postgres satırı varsayılan olarak güvenlidir. Bunun istisnası route_localnet adlı bir çekirdek ayarıdır: varsayılan olarak kapalıdır ancak bazı araçlar bunu açar (Kubernetes'in kube-proxy'si gibi) ve bu ayar ile doğru yönlendirme veya NAT kuralları sayesinde loopback trafiği dışarıdan gelebilir. sysctl -a | grep route_localnet, her satırda = 0 değerini göstermelidir.
Pratik kural buradan çıkar: yalnızca kendi uygulamalarınızın kullandığı bir veritabanı, önbellek veya yönetim paneli 0.0.0.0 yerine 127.0.0.1 adresine bağlanmalıdır. Eğer hiçbir zaman genel bir adreste dinleme yapmazsa, bir saldırganın erişebileceği bir nokta kalmaz.
Dinleme yapmak ile erişilebilir olmak aynı şey değildir
Bir ayrım daha kafa karışıklığını önler. Bir makinede portun açık olması, yani bir programın dinleme yapıyor olması, o portun dışarıdan erişilebilir olmasıyla, yani güvenlik duvarının buna izin vermesiyle aynı şey değildir. Uzak bir istemcinin bağlanabilmesi için her ikisinin de doğru olması gerekir. İki hata türü istemci tarafında farklı görünür: reddedilen bir bağlantı genellikle dinleme yapan bir servis olmadığını gösterir; takılıp zaman aşımına uğrayan bir bağlantı ise genellikle güvenlik duvarının paketi düşürdüğü anlamına gelir ki bu tam olarak o iki SSH hatasının size anlattığı şeydir.
Yani iki kontrol katmanı vardır. Her servisin bind adresini ayarlayarak neyin dinleme yapacağına siz karar verirsiniz. Dış dünyanın neye erişebileceğine ise bir güvenlik duvarı ile karar verirsiniz. İyi yönetilen bir sunucu her ikisini de kullanır: servisler yalnızca ihtiyaç duydukları yerlerde dinleme yapar ve güvenlik duvarı açıkça izin vermediğiniz her şeyi reddeder. ss ile neyin dinleme yaptığını okumak ilk adımdır; güvenlik duvarının neye izin vereceğine karar vermek ise UFW ile güvenlik duvarı temelleri bölümünde ele alınan ikinci adımdır.
Burada insanları yanıltan ince bir nokta vardır. IPv4 ve IPv6 birbirinden ayrıdır ve yalnızca IPv4'ü kapsayan bir güvenlik duvarı, [::] servislerini IPv6 üzerinde açık bırakır. Bu özel tuzağın kendi yazısı mevcuttur: IPv6 güvenlik duvarı tuzağı.
FAQ
Linux sunucumda hangi portların açık olduğunu nasıl görebilirim?
TCP için sudo ss -tlnp veya UDP için sudo ss -ulnp komutunu çalıştırın. Bu komut, dinleme yapan tüm soketleri, portu, bağlı olduğu yerel adresi ve ona sahip olan süreci listeler. Local Address sütununu okuyun: 0.0.0.0 veya [::], servisin ağa açık olduğu anlamına gelirken, 127.0.0.1 servisin yalnızca makinenin kendisinde dinleme yaptığı anlamına gelir.
0.0.0.0 ile 127.0.0.1 arasındaki fark nedir?
0.0.0.0, "tüm IPv4 adreslerini dinle" anlamına gelir; buna genel adres de dahildir, bu nedenle servise ağ üzerinden erişilebilir. 127.0.0.1 loopback'tir; makinenin kendisiyle konuşmak için kullandığı adrestir ve çekirdeğin varsayılan ayarlarında başka hiçbir yerden yönlendirilemez, bu nedenle buraya bağlı bir servise yalnızca yerel olarak erişilebilir. Dahili servisleri 127.0.0.1 adresine bağlayın ki ağ dışında kalsınlar.
Bir servisin çalışması için güvenlik duvarında port açmam gerekir mi?
Yalnızca diğer makinelerden erişilmesi gereken servisler için gereklidir. 127.0.0.1 adresine bağlı bir servis için izin kuralına gerek yoktur, çünkü varsayılan çekirdek ayarlarıyla dışarıdan hiçbir şey oraya erişemez. 0.0.0.0 veya [::] üzerindeki bir servis, güvenlik duvarınız varsayılan olarak gelen trafiği reddediyorsa (ki öyle olmalıdır) bir izin kuralına ihtiyaç duyar. Eğer hiçbir güvenlik duvarı aktif değilse veya politikası her şeyi kabul ediyorsa, o servis zaten hiçbir kurala gerek kalmadan erişilebilirdir.
TCP portu ile UDP portu arasındaki fark nedir?
TCP bağlantı tabanlıdır ve SSH, web sunucuları ve veritabanları gibi çoğu servis tarafından kullanılır. UDP bağlantısızdır ve DNS ile bazı VPN'ler tarafından kullanılır. TCP ve UDP'deki aynı numara farklı portlardır, bu nedenle 53/tcp ve 53/udp farklıdır. Güvenlik duvarı kuralları yazarken protokolü belirtirsiniz, örneğin 22/tcp.