Linux üzerinde bir portun açık olduğunu nasıl anlarım?
Linux sisteminizde ss komutu ile dinlenen portları listeleyin ve nc ya da nmap ile dışarıdan test edin. Kapalı portun reddetme ile açık portun yanıt verme farkını öğrenin.
Linux üzerinde bir portun açık olup olmadığını kontrol etme: önce doğru soruyu belirleyin
Linux üzerinde bir portun açık olup olmadığını kontrol etmek için öncelikle hangi soruyu sorduğunuza karar verin; çünkü "açık" ifadesi, bulunduğunuz konuma göre farklı anlamlar taşır. Sunucunun kendi üzerinde "açık" olması, bir sürecin o porta bağlı olduğu ve yanıt beklediği anlamına gelir. Başka bir makineden bakıldığında ise "açık" olması, bir paketin o sürece ulaştığı ve yanıt aldığı anlamına gelir. Hiçbir yanıt gelmediğinde asıl soru, paketi hangi cihazın düşürdüğüdür. sudo ss -ltnp ilk soruyu yanıtlar. nc -z veya nmap ikinci soruyu yanıtlar. Güvenlik duvarı sayaçları ve tcpdump ise üçüncü soruyu yanıtlar.
Yanlış kontrolü çalıştırmak, insanların bir öğleden sonrasını boşa harcamasına neden olur. Sunucu üzerinde yapılan bir test, sağlayıcınızın ağ güvenlik duvarına asla temas etmez; çünkü bu filtre kutunun dışında yer alır. Port numaraları sizin için henüz yeniyse, Linux üzerinde portlar ve soketler nasıl çalışır başlıklı bölüm, bu kılavuzun geri kalanında varsayılan modeli açıklamaktadır.
Bu sunucuda hangi servisler dinlemede? ss çıktısını okuma
ss, iproute2 ile birlikte gelir, bu nedenle güncel tüm dağıtımlarda mevcuttur. netstat, Ubuntu'nun yıllardır varsayılan olarak kurmadığı net-tools paketinden gelir, bu yüzden netstat -tulpn genellikle netstat: command not found yanıtını döndürür. ss komutunu öğrenin ve hayal kırıklığından kurtulun.
sudo ss -ltnp-l yalnızca dinleme durumundaki soketleri gösterir. -t listeyi TCP ile sınırlar. -n isim çözümlemek yerine sayısal değerleri yazdırır, böylece komut anında sonuç verir. -p sahip süreci isimlendirir ve bunun için root yetkisi gerekir: sudo olmadan, sahibi olmadığınız her süreç için Process sütunu boş kalır. UDP trafiğini görmek için -t yerine -u kullanın.
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=612,fd=14))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=921,fd=3))
LISTEN 0 511 127.0.0.1:8080 0.0.0.0:* users:(("node",pid=1442,fd=19))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=921,fd=4))Local Address sütunu her şeyi belirler ve insanların genellikle göz ardı ettiği sütundur.
0.0.0.0:22, makinedeki tüm IPv4 adresleri anlamına gelir; güvenlik duvarı izin veriyorsa dışarıdan erişilebilir.[::]:22, IPv6 için aynı anlama gelir.127.0.0.1:8080, yalnızca loopback anlamına gelir. Makine dışından hiçbir şey buraya erişemez.10.20.0.5:5432, yalnızca o arayüz adresi anlamına gelir; özel ağ kurulumlarında yaygındır.- Boş bir Process sütunu genellikle eksik bir süreçten değil, eksik
sudoyetkisinden kaynaklanır.
Belirli bir portu sorgulamak için listenin tamamını grep ile süzmek yerine ss içinde filtreleme yapın:
sudo ss -ltnp 'sport = :8080'
sudo lsof -nP -iTCP:8080 -sTCP:LISTEN
sudo fuser 8080/tcpÜç komuttan da boş çıktı alıyorsanız, o portu kullanan hiçbir şey yoktur. Servis durdurulmuştur, başlatılamamıştır veya başka bir yerde dinleme yapıyordur. Tek bir güvenlik duvarı kuralına dokunmadan önce systemctl status <unit> ve journalctl -u <unit> -n 50 çıktılarını okuyun.
Local Address kısmındaki 127.0.0.1 neden zaman kaybına yol açar
127.0.0.1 adresine bağlanan bir sokete başka bir ana bilgisayardan ulaşılamaz ve hiçbir güvenlik duvarı kuralı bunu değiştiremez. Çekirdek, 127.0.0.0/8 adresine gelen trafiği yalnızca loopback arayüzüne yönlendirir; gerçek bir ağ kartına gelen ve bu hedef adresi taşıyan paketler ise "martian" (geçersiz) olarak işaretlenip atılır. Dolayısıyla süreç çalışır, ss dinleme yaptığını gösterir, ufw allow 8080 işlemin başarılı olduğunu bildirir ancak dizüstü bilgisayarınızdan yaptığınız bağlantı yine de başarısız olur. Bağlantı anında Connection refused hatasıyla kesilir; çünkü paket genel IP adresinize ulaşır, orada bağlı bir soket bulamaz ve çekirdek TCP reset yanıtı döner.
Birçok program kasıtlı olarak loopback adresine bağlanır; veritabanları veya yönetim arayüzleri için bu doğru varsayılan değerdir. Bu noktada iki geçerli seçeneğiniz vardır. Programın kendi yapılandırmasındaki bağlama adresini değiştirin (postgresql.conf içinde listen_addresses, redis.conf içinde bind veya uygulamanızın aldığı host argümanı) ve ardından güvenlik duvarını açın. Ya da servisi loopback üzerinde bırakıp ona başka bir yöntemle, örneğin bir nginx reverse proxy veya dizüstü bilgisayarınızdan kuracağınız bir SSH tüneli ile erişin:
ssh -L 8080:127.0.0.1:8080 user@203.0.113.10Docker, publish bayrağında aynı ayrımı gözetir. -p 8080:8080 komutu 0.0.0.0 adresine bağlanarak container'ı internete açar. -p 127.0.0.1:8080:8080 komutu ise loopback adresine bağlanarak erişimi yerel tutar.
Linux üzerinde bir portun başka bir makineden açık olup olmadığını kontrol etme
Bu testi farklı bir ağ üzerinden gerçekleştirin. Sunucunun kendisinden yapılan bir test, yalnızca loopback yolunun çalıştığını kanıtlar. Sunucudan kendi genel IP adresinize bağlanmak bile sağlayıcınızın ağ güvenlik duvarını devre dışı bırakır, çünkü bu filtreleme VPS'in dışında çalışır.
nc -zv -w 3 203.0.113.10 443-z komutu, veri göndermeden bağlantı kurar ve kapatır. -w 3 üç saniye sonra vazgeçer; bu bayrak önemlidir: zaman aşımı olmazsa, düşen bir paket istemcinin çekirdek durana kadar iki dakikadan fazla SYN paketini yeniden denemesine neden olur. Başarılı bir sonuç şu şekilde görünür:
Connection to 203.0.113.10 443 port [tcp/https] succeeded!Eğer araç yüklü değilse (nc: command not found), Debian veya Ubuntu üzerinde netcat-openbsd paketini kurun ya da hiçbir paket gerektirmeyen bash'in yerleşik ağ yönlendirme özelliğini kullanın:
timeout 3 bash -c '</dev/tcp/203.0.113.10/443' && echo open || echo "no answer"Bu sözdizimi bir bash özelliğidir, bu yüzden bash ile çalıştırın. Debian ve Ubuntu üzerindeki /bin/sh, /dev/tcp özelliğine sahip olmayan dash kabuğudur ve yolun bulunamadığına dair hata verir. Port aralıkları için veya durumun sizin için adlandırılmasını istediğinizde, sorumlu olduğunuz ana bilgisayarlara karşı nmap kullanın:
sudo nmap -Pn -p 22,80,443 203.0.113.10
sudo nmap -Pn -p 1-1024 203.0.113.10-Pn ana bilgisayar keşfini atlar. Çoğu VPS sağlayıcısı ICMP echo paketlerini düşürür, bu yüzden -Pn olmadan nmap ana bilgisayarın kapalı olduğuna karar verir ve hiçbir tarama yapmaz. nmap, bir yanıt alınıp bağlantı kabul edildiğinde open, bir yanıt alınıp bağlantı sıfırlandığında closed, hiçbir yanıt alınamadığında ise filtered çıktısını verir. Bir web servisi için curl -sS -o /dev/null -w '%{http_code}\n' https://example.com, ağ hatasını uygulama hatasından ayırır; çünkü bir durum kodu tüm yolun çalıştığını kanıtlar.
Engellenen bir portun neden yanıt vermediği ve kapalı bir portun neden anında reddettiği
Anında reddetme. Paket makineye ulaştı ve bir şey buna yanıt verdi.
nc: connect to 203.0.113.10 port 443 (tcp) failed: Connection refusedİki farklı neden tam olarak bu sonucu doğurur. Ya o adres ve porta bağlı hiçbir süreç yoktur, bu durumda çekirdek bir TCP reset paketiyle yanıt verir ya da bir güvenlik duvarı kuralı paketi bir reset veya ICMP port unreachable mesajı ile reddetmiştir. Reddetme kesin bir yanıttır ve tek bir gidiş-dönüş süresinde geri döner.
Bir duraksama, ardından zaman aşımı. Bir şey paketi düşürdü ve hiçbir yanıt vermedi.
nc: connect to 203.0.113.10 port 443 (tcp) timed out: Operation now in progressDROP kuralının yaptığı budur; bir servis sağlayıcı güvenlik duvarı veya bulut güvenlik grubu da aynı şekilde davranır. Sessizlik, düşürme işleminin imzasıdır; çünkü gönderici, paketin düşürüldüğü ile ana bilgisayarın kapalı olduğu durumları birbirinden ayırt edemez.
Belirti, nereye bakmanız gerektiğini size söyler. "Refused" (reddedildi) ifadesi, paketlerin ağ üzerinden sorunsuz geçtiği anlamına gelir; bu durumda ss -ltnp bölümüne dönün ve bind adresini ve port numarasını kontrol edin. "Timed out" (zaman aşımı) ifadesi, paketlerin düşürüldüğü anlamına gelir; bu durumda güvenlik duvarlarını dışarıdan içeriye doğru inceleyin. SSH üzerinde refused ve timed out farkı bölümü, çoğu kullanıcının karşılaştığı 22 numaralı port için aynı ayrımı detaylandırır.
ufw, her iki davranışı da bilinçli olarak sunar: ufw deny 8080 paketleri düşürür, ufw reject 8080 ise reddetme yanıtı gönderir. nftables içerisinde bu iki hedef drop ve reject, iptables içerisinde ise -j DROP ve -j REJECT olarak adlandırılır. Varsayılan politikalar neredeyse her zaman düşürme (drop) yönündedir; bu nedenle eksik bir kural, hata mesajı yerine bağlantının askıda kalmasına neden olur.
Portu kim engelliyor? Dışarıdan içeriye doğru inceleyin
sudo ufw status verbose
sudo iptables -L INPUT -n -v --line-numbers
sudo nft list ruleset-v sayaçları bu noktada işe yarar. nc testinizi dışarıdan çalıştırın, iptables komutunu tekrar girin ve artış gösteren sayacı bulun: paket sayısı artan kural, trafiğinizi işleyen kuraldır. Bu yöntem, tahmin yürütmek yerine kanıta dayalı analiz yapmanızı sağlar.
Kesin sonuç veren test, sunucu üzerinde çalıştırılır ve siz dışarıdan bağlanırken ağ trafiğini izler:
sudo tcpdump -ni any tcp port 8080Bir SYN paketi ulaşıyor ancak SYN-ACK yanıtı dönmüyorsa, paket VPS'inize ulaşmış ancak ana makine tarafından düşürülmüştür; bu durumda sağlayıcı güvenlik duvarı düzgün çalışıyor, yerel kurallarınız ise hatalıdır. Hiç çıktı alınmıyorsa paket hiç ulaşmamış demektir; bu durumda sorun sağlayıcı güvenlik duvarı, bir güvenlik grubu veya yanlış IP adresi kaynaklıdır. Bu ayrım, iş yükünüzün büyük kısmını ortadan kaldırır.
İki katman, imkansız görünen sonuçlar doğurabilir. Birincisi IPv6: eğer ana makine adının bir AAAA kaydı varsa, istemciniz IPv6 üzerinden bağlanmaya çalışıyor olabilir ancak kuralınız yalnızca IPv4'ü kapsıyor olabilir; bu yüzden her iki sonuca da güvenmeden önce nc -4 ve nc -6 ile her iki aileyi de test edin. VPS üzerinde ufw kuralları ve IPv6 portları bu uyumsuzluğu ele alır. İkincisi Docker: yayınlanan bir container portu, ufw status o portu reddedilmiş olarak listelese bile internetten yanıt verir; çünkü bu paketler ufw zincirine ulaşmadan önce işlenir. Docker neden ufw'yi atlayarak port yayınlar bu mekanizmayı ve çözümünü açıklar; yeni bir VPS üzerinde ayarlanması gereken temel ufw kuralları ise başlangıç için sahip olunması gereken temel yapılandırmayı içerir.
UDP yanıtlarının tasarımları gereği belirsiz olması
UDP bir el sıkışma (handshake) sürecine sahip değildir, bu nedenle bir sorgunun başarılı olması için herhangi bir kriter bulunmaz. nc -zu 203.0.113.10 53, paket gönderildiği anda 0 koduyla çıkar; bu durum yalnızca kendi makinenizin paketi gönderdiğini kanıtlar, karşı taraf hakkında ise hiçbir bilgi vermez. Bir UDP portu kapalı olduğunda, ana makine normalde bir ICMP port unreachable mesajı ile yanıt verir; ancak çekirdek bu hatayı bağlı bir sokete yalnızca bir sonraki yazma işleminde bildirir, dolayısıyla tek paketlik bir sorgu bunu kaçırır. Güvenlik duvarları genellikle ICMP paketlerini düşürür, bu da söz konusu ipucunu da ortadan kaldırır. nmap'in çoğu UDP portu için open|filtered çıktısı vermesinin nedeni budur: yanıt alınamaması, hem sessiz çalışan bir servisin hem de filtrelenmiş bir portun ortak sonucudur.
UDP bağlantısını, ilgilendiğiniz protokolü kullanarak test edin. Bir DNS sunucusu, dig +short @203.0.113.10 example.com sorgusuna bir adresle veya hiçbir şeyle yanıt verir. Bir WireGuard eşi, sudo wg show dosyasında yakın tarihli bir latest handshake satırı gösterir. Ardından sunucu tarafında paketlerin ulaştığını kanıtlayın:
sudo tcpdump -ni any udp port 51820İstemci gönderim yaparken paketlerin görünmesi, paketlerin ulaştığını; dolayısıyla sorunun serviste veya giriş zincirinde (input chain) olduğunu gösterir. Hiç paket görünmemesi ise paketlerin oraya hiç ulaşmadığı anlamına gelir.
Hataları en hızlı şekilde tespit etmek için kontrol listesi
- Sunucu üzerinde
sudo ss -ltnp 'sport = :8080'komutunu çalıştırın. Çıktı alınamaması, hiçbir servisin dinleme yapmadığı anlamına gelir; bu durumda önce servisi düzeltin. - Çıktı alabiliyorsanız Local Address sütununu inceleyin.
127.0.0.1ifadesi, yeniden bağlama yapana veya önüne bir proxy koyana kadar dışarıdan erişimin imkansız olduğunu gösterir. - Başka bir ağ üzerinden
nc -zv -w 3 <public ip> 8080komutunu çalıştırın. - Bağlantı reddedilirse 1. adıma geri dönün. Adres, port veya makine düşündüğünüzden farklıdır.
- Zaman aşımı (timeout) hatası, paketlerin düştüğü anlamına gelir. Sunucuda
sudo tcpdump -ni any tcp port 8080komutunu başlatın ve testi tekrarlayın. - SYN paketi ulaşıyor ancak yanıt dönmüyorsa sorun ana bilgisayar güvenlik duvarıdır.
sudo iptables -L INPUT -n -viçerisinde sayacı artan kuralı bulun. - SYN paketi hiç ulaşmıyorsa sorun sağlayıcı güvenlik duvarı, güvenlik grubu veya yanlış IP adresidir.
FAQ
Linux sunucumda hangi portların açık olduğunu nasıl kontrol ederim?
TCP için sudo ss -ltnp, UDP için sudo ss -lunp komutunu çalıştırın. Her satır bir dinleme soketini temsil eder; Local Address sütunu, portun kimler tarafından erişilebilir olduğunu belirtir: 0.0.0.0 ve [::], güvenlik duvarının izin verdiği her yerden gelen bağlantıları kabul ederken, 127.0.0.1 yalnızca makinenin kendisinden gelen bağlantıları kabul eder. Process sütununu görmek için root yetkisi gerekir; bu nedenle komutu sudo ile çalıştırın, aksi takdirde bu sütun boş dönecektir. ss, iproute2 paketinin bir parçasıdır ve her zaman yüklüdür; netstat ise net-tools paketine aittir ve genellikle yüklü değildir.
ss komutu servisin dinlediğini gösterdiği halde neden bağlanamıyorum?
Bunun iki yaygın nedeni vardır ve tek bir komutla aralarındaki fark anlaşılabilir. Eğer Local Address 127.0.0.1 olarak görünüyorsa, servis loopback arayüzüne bağlanmıştır ve çekirdek bu aralığı yalnızca loopback arayüzüne yönlendirdiği için başka hiçbir ana bilgisayardan erişilemez. Eğer adres 0.0.0.0 olduğu halde bağlantı başarısız oluyorsa, sunucuda sudo tcpdump -ni any tcp port <port> komutunu çalıştırın ve dışarıdan bağlanmayı deneyin. Yanıt gelmeden bir SYN paketi ulaşıyorsa, yerel bir güvenlik duvarı kuralı paketi düşürüyor demektir. Hiçbir paket ulaşmıyorsa, paket VPS'inize ulaşmadan önce, genellikle bir sağlayıcı güvenlik duvarı veya güvenlik grubu tarafından durduruluyordur.
Bağlantının reddedilmesi (refused) ile zaman aşımına uğraması (timeout) arasındaki fark nedir?
Reddedilme bir yanıttır. Paket ana bilgisayara ulaşmış ve bir TCP reset veya ICMP port unreachable yanıtı dönmüştür; bu, o adres ve portta hiçbir servisin dinlemediği veya bir kuralın bağlantıyı reddettiği anlamına gelir. Zaman aşımı ise sessizliktir: bir kural paketi düşürmüş ve hiçbir yanıt göndermemiştir; bu yüzden istemciniz vazgeçene kadar yeniden deneme yapar. Reddedilme durumu sizi servise ve onun bind adresine yönlendirir. Zaman aşımı ise sizi güvenlik duvarına yönlendirir; bu durumda dış dünyaya en yakın güvenlik duvarı ilk kontrol edilmesi gereken yerdir.
Bir UDP portunun açık olup olmadığını nasıl kontrol ederim?
UDP'nin bir el sıkışma süreci olmadığı ve sessiz bir servis ile düşürülen bir paketin aynı sonucu verdiği için genel bir tarama ile güvenilir bir "evet" yanıtı alamazsınız. nc -zu, paket gönderildiği anda başarı döner; nmap de aynı nedenle open|filtered raporlar. Bunun yerine protokolü kullanarak test edin: DNS için dig +short @<host> example.com veya yakın zamanda el sıkışması gerçekleşmiş bir WireGuard eşi için sudo wg show kullanın. Paketlerin ulaştığını doğrulamak için, istemci gönderim yaparken sunucuda sudo tcpdump -ni any udp port <port> komutunu çalıştırın.
Bir portu test etmek için hala telnet host port kullanabilir miyim?
TCP için çalışır ve Escape character is '^]' bağlantının kabul edildiği anlamına gelir. Çıkmak için Ctrl+] ve ardından quit tuşlarını kullanın. nc -z aracını daha iyi yapan iki neden vardır: telnet çoğu güncel sunucu imajında yüklü değildir ve nc, -w ile bir zaman aşımı süresi belirleyebilir ve betiklerde test edebileceğiniz bir çıkış durumu döndürür. İkisi de mevcut olmadığında, timeout 3 bash -c '</dev/tcp/<host>/<port>' herhangi bir paket gerektirmediği için kullanılabilir.