Açık kalmış ve unutulmuş bir port, sunucuya girmenin klasik yoludur: genel bir adreste veritabanı, bir hata ayıklama paneli, kimsenin istemediği bir portu yayınlamış bir container. İki komutu ve bir tuzağı bildiğinizde kontrol bir dakika sürer. Aşağıdaki her şeyi imajımızdan kurulmuş yeni bir Ubuntu 24.04 sunucuda yaptık ve ikinci bir makineden taradık; yani çıktılar kendi sunucunuzda göreceklerinizle aynı.
1. Ne dinliyor
Komut ss. Harfler TCP, UDP, dinleyen soketler, sayısal portlar ve süreç adı anlamına gelir:
sudo ss -tulpn
Yeni bir sunucuda altı satır yazdırır:
Netid State Local Address:Port Process
udp UNCONN 127.0.0.54:53 systemd-resolve
udp UNCONN 127.0.0.53%lo:53 systemd-resolve
tcp LISTEN 127.0.0.54:53 systemd-resolve
tcp LISTEN 127.0.0.53%lo:53 systemd-resolve
tcp LISTEN 0.0.0.0:22 sshd
tcp LISTEN [::]:22 sshd
Önemli olan sütun Local Address. Kimin bağlanabileceğini söyler:
| Adres | Kim ulaşabilir |
|---|---|
127.0.0.1:… veya 127.0.0.53 | Yalnızca bu sunucudaki programlar |
0.0.0.0:… | Güvenlik duvarı engellemezse IPv4 üzerinden herkes |
[::]:… | IPv6 üzerinden herkes (genellikle IPv4 de) |
10.0.0.5:… (belirli bir adres) | O adrese ulaşabilen herkes |
Yani yeni sunucu dışarıya tam olarak bir şey açıyor: IPv4 ve IPv6 üzerinden 22 numaralı portta SSH. 127.0.0.53 üzerindeki DNS çözümleyici özeldir.
Yalnızca internetin görebileceklerini listelemek için loopback adreslerini ayıklayın:
sudo ss -tlnp | awk 'NR>1 && $4 !~ /^(127\.|\[::1\])/ {print $4, $6}'
Bunu her kurulumdan sonra çalıştırın. nginx, Docker ve küçük bir Python uygulaması kurduk; liste 2 satırdan 10 satıra çıktı, aralarında 0.0.0.0:8081 üzerinde bir docker-proxy ve rastgele bir localhost portunda bir containerd soketi vardı.
2. Portu hangi süreç tutuyor
Bir port meşgulse ve kimin tuttuğunu öğrenmek istiyorsanız:
sudo lsof -i :80 -P -n
sudo fuser 80/tcp
sudo ss -tlnp 'sport = :80'
En okunaklısı lsof. nginx için root olarak bir ana süreç ve www-data olarak bir worker gösterdi, ikisi de IPv4 ve IPv6 için *:80 üzerinde. fuser yalnızca PID'leri yazdırır, betiklerde kullanışlıdır. Portu boşaltmanız gerekiyorsa PID'yi öldürmek yerine servisi durdurun, yoksa systemd onu yeniden başlatır: sudo systemctl stop nginx.
3. İnternet ne görüyor
ss sunucunun bakış açısını gösterir. İnternetin bakış açısı farklı olabilir; çünkü arada bir güvenlik duvarı vardır ya da bir servis 127.0.0.1'e bağlıdır. Gerçek tabloyu görmek için sunucuyu başka bir makineden, dizüstü bilgisayarınızdan ya da ikinci bir sunucudan tarayın. Araç nmap (apt install nmap, Windows ve macOS'ta nmap.org'daki yükleyici).
nmap your-server-ip
nmap -p- your-server-ip
nmap -p 22,80,443,3306 your-server-ip
İlk biçim en yaygın 1.000 portu, ikincisi 65.535 portun tamamını, üçüncüsü bir listeyi kontrol eder. Yeni sunucumuzda, henüz güvenlik duvarı yokken:
Not shown: 999 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
Nmap done: 1 IP address (1 host up) scanned in 6.83 seconds
65.535 portun tam taraması 8,9 saniye sürdü ve aynı tek portu buldu. Kapalı portlar hemen bir reset ile yanıt verir, bu yüzden taramaları hızlıdır.
Üç durum önemlidir:
- open: bir program bağlantıyı kabul etti. Saldırı yüzeyiniz budur.
- closed: sunucu orada hiçbir şeyin dinlemediğini yanıtladı. Güvenli, ama sunucunun var olduğunu ve neyi çalıştırmadığını doğrular.
- filtered: yanıt yok. Bir güvenlik duvarı paketi attı. Tarayıcı arkasında bir servis olup olmadığını bilemez.
Hiçbir şey kurmadan tek bir port için nc -zv sunucu-ip 443 succeeded ya da refused döner, filtrelenmiş bir portta ise zaman aşımına kadar bekler. UDP için nmap'e -sU ekleyin ve yavaşlığa hazır olun; sunucumuzda yaygın üç UDP portu, 53, 123 ve 161, closed idi.
NAT paketleri için bir not: internetten yalnızca size yönlendirdiğimiz SSH portuna ulaşılır. Paylaşılan adresin taranması sizin sunucunuzu değil bizim kenarımızı gösterir ve diğer portlarda ne dinlerse dinlesin onlara ulaşılamaz. Kendi IPv4 adresi olan bir pakette her açık portu siz yönetirsiniz.
4. Gerekmeyeni kapatın
En iyisinden en genişine üç yol.
localhost'a bağlayın. Bir servisi yalnızca sunucudaki programlar kullanıyorsa 127.0.0.1'i dinlemesini sağlayın. Küçük bir web uygulamasını --bind 127.0.0.1 8080 ile başlattık: ss onu 127.0.0.1:8080 üzerinde gösterdi, dışarıdan nmap 8080/tcp closed bildirdi. Veritabanları için doğru varsayılan budur: Ubuntu'da Redis, MySQL ve PostgreSQL kurulur kurulmaz localhost'u dinler ve Redis ile MySQL rehberlerimiz bunu böyle bırakır.
Servisi durdurun. sudo systemctl disable --now ad dinleyiciyi kalıcı olarak kaldırır. ss ile gittiğini kontrol edin.
Güvenlik duvarını açın. Önce SSH'ye, sonra sunduğunuz şeye izin verin, ardından etkinleştirin:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw enable
sudo ufw status verbose
Dışarıdan tarama tamamen değişti:
Not shown: 997 filtered tcp ports (no-response)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
8081/tcp open blackice-icecap
Nmap done: 1 IP address (1 host up) scanned in 10.18 seconds
İzin verilmeyen her port closed'dan filtered'a geçti ve 65.535 portun tam taraması artık 8,9 yerine 110 saniye sürdü. Tarayıcı için port başına daha fazla zaman, sunucunuz hakkında daha az bilgi. UFW rehberimiz hız sınırlamayı, tek bir IP'ye izin vermeyi ve IPv6'yı anlatıyor.
Ama üçüncü satıra bakın.
5. Docker sürprizi
8081 portu güvenlik duvarı açıkken ve ona izin veren bir kural olmadan açık kaldı. Bu port, docker run -p 8081:80 nginx:alpine ile başlattığımız bir container'a ait. Docker çekirdek güvenlik duvarına kendi kurallarını ekler ve bunlar ufw kurallarından önce değerlendirilir. Sunucumuza yazdığı kural:
-A DOCKER ! -i docker0 -p tcp --dport 8081 -j DNAT --to-destination 172.17.0.2:80
8081 portuna gelen her paket, ufw söz alamadan container'a yönlendirilir. -p veya ports: girdisi olan her container bunu yapar ve ss bunu dürüstçe 0.0.0.0:8081 üzerinde docker-proxy olarak gösterir.
Çözüm yalnızca localhost'a yayınlamaktır:
docker rm -f web
docker run -d --name web -p 127.0.0.1:8081:80 nginx:alpine
Compose'ta ports: altına "127.0.0.1:8081:80" yazın. Değişiklikten sonra ss 127.0.0.1:8081 gösterdi, Docker kuralına -d 127.0.0.1/32 eklendi ve dışarıdan tarama 8081/tcp filtered bildirdi. Dış taraf için önüne HTTPS'li bir nginx ters vekil sunucu koyun; böylece sunucuda açık portlar yalnızca 22, 80 ve 443 olur.
Her değişiklikten sonra kontrol listesi
sudo ss -tulpn:0.0.0.0veya[::]içeren her satır açmak istediğiniz bir şey mi?- Dizüstünüzden
nmap sunucu-ip: açık portlar eşleşiyor mu? - Genel bir adreste veritabanı, önbellek veya yönetim paneli: bugün
127.0.0.1'e ya da güvenlik duvarının arkasına taşıyın. - Her Docker
ports:girdisi: genel web portu değilse127.0.0.1:ile başlıyor mu? - Herkese açık SSH: fail2ban veya yalnızca anahtarla giriş ekleyin.
Windows Server'da aynı kontrol Get-NetTCPConnection -State Listen ile yapılır ve kurallar Windows Güvenlik Duvarı içindedir. $3'lık Nano ile başlayan her Linux paketinin kendi IPv4 adresi olan bir sürümü var; orada ss'te gördüğünüzü, güvenlik duvarınızın durdurdukları dışında tüm dünya görür.
Yorumlar
Henüz yorum yok. İlk olun.