Açık portların listesi, sunucunuza ulaşma yollarının listesidir. Geri kalan her şey — güvenlik duvarları, WAF’lar, saldırı tespiti — onun üzerine kurulur. Bu yüzden herhangi bir denetimde ilk sırada «burada ne dinliyor» gelir ve bu yüzden en sık hoş olmayan yanıtı veren kontrol de odur: karşınıza çıkanların yarısını siz değil, bir paketin kurulum betiği açmıştır.

Çıktıyı okumak

sudo ss -tulpn

Bayraklar: TCP için t, UDP için u, yalnızca dinleyenler için l, süreç için p, sayıları sayı olarak bırakmak için n. sudo olmadan süreç sütunu boş kalır ve alıştırma anlamını yitirir.

Önemli olan Local Address:Port sütunudur ve oradaki fark temeldir:

  • 127.0.0.1:3306 — servise yalnızca makinenin kendisinden erişilebilir. Bu iyidir;
  • 0.0.0.0:3306 — her IPv4 adresinden, yani internetten. Kontrol edilmesi gereken budur;
  • [::]:3306 — IPv6 için aynısı. Ayrı bir satırdır ve düzenli olarak gözden kaçar;
  • 203.0.113.25:443 — belirli bir adreste, genellikle kasıtlıdır.

Sonra 0.0.0.0 ya da [::] içeren her satır için tek bir soru sorun: bir yabancı buraya erişebilmeli mi. 80 ve 443 için yanıt evettir. Neredeyse her şey için hayırdır.

Alışıldık bulgular

Redis, 6379 portu. Oradaki en tehlikeli satır. Redis varsayılan olarak parola istemez ve komutları diske dosya yazmaya izin verir — yani authorized_keys içinde başkasının anahtarına. Redis’in genel bir adreste belirmesiyle kullanılması arasında saatler, bazen daha azı geçer. Yapılandırmada bind 127.0.0.1 ve protected-mode yes olup olmadığına bakın.

Memcached, 11211/UDP. İçinde değerli hiçbir şey olmasa bile sunucunuz başkalarının saldırıları için bir yükselteç haline gelir — ve şikâyet sağlayıcınızdan gelir.

MySQL ve PostgreSQL, 3306 ve 5432. Parola vardır, ama ona karşı sürekli tahmin denemeleri yapılır ve veritabanı sürümleri istenenden daha seyrek güncellenir. Neredeyse hiçbir zaman dışarıya bakmaları gerekmez: uygulama aynı makinededir ve kendi çalışmanız için bir SSH tüneli yeter.

Elasticsearch 9200, MongoDB 27017. Tarihsel olarak varsayılanda kimlik doğrulamasızdırlar. Bunların herkese açık örnekleri, veri sızıntısı haberlerinin değişmez kaynağıdır.

Docker API, 2375. Açık bir Docker denetim portu, hiçbir parola olmadan ana makinede root demektir. Genellikle Docker’a uzaktan erişim denemelerinden sonra ortaya çıkar.

Yönetim panelleri ve phpMyAdmin kendi portlarında: 8080, 8083, 10000. Asla açılmamalıdır demiyoruz, ama denemelerin büyük kısmını toplayan tam olarak onlardır.

Güvenlik duvarında değil, servisin kendisinde düzeltin

Her bulguyu bir UFW kuralıyla kapatma dürtüsü anlaşılırdır, ama bu ikinci hattır, birincisi değil. Bir kural yanlışlıkla silinebilir, hata ayıklarken güvenlik duvarı geçici olarak kapatılabilir ve Docker portları UFW’nin tamamen etrafından yayımlar. Servisin kendi yapılandırmasındaki bir bağlama ayarı bunların hepsinden sağ çıkar:

  • MySQL/MariaDB — bind-address = 127.0.0.1;
  • PostgreSQL — listen_addresses = 'localhost';
  • Redis — bind 127.0.0.1 ::1;
  • Docker Compose — "127.0.0.1:5432:5432" olarak yayımlayın.

Güvenlik duvarı bunun yerine değil, üstüne sigorta olarak gelir.

Belirsizken süreci bulmak

ss adı ve pid’i verir. Sonrası:

sudo systemctl status <pid>
sudo lsof -i :8080

İlk komut, sürecin ait olduğu systemd birimini adlandırır — genellikle onun ne olduğunu ve gerekli olup olmadığını anlamak için yeterlidir. Yüksek bir portta dinleyen, sistem dizinlerinin dışından — örneğin /tmp ya da /dev/shm içinden — başlatılmış tanıdık olmayan bir süreç artık bir yapılandırma sorusu değil, ayrı bir soruşturmanın gerekçesidir.

Dışarıdan kontrol zorunludur

ss «ne dinliyor» sorusuna yanıt verir, «neye erişilebiliyor» sorusuna değil. İkisinin arasında güvenlik duvarı, NAT ve sağlayıcının kendi kuralları durur. Tek dürüst yanıt başka bir makineden yapılan taramadan gelir:

nmap -Pn -p- 203.0.113.25
nmap -Pn -p- -6 2001:db8::1

İkinci komutu atlamayın: neredeyse her VPS’in bir IPv6 adresi vardır, kuralları ayrı yazılır ve servis protokolün iki sürümünü aynı anda dinler.

Bu bir kerelik bir kontrol değildir

Açık portların listesi kendiliğinden değişir. Bir paket kurdunuz, o bir servis getirdi ve bir port açtı. Bir paneli güncellediniz, o bir varsayılanı geri getirdi. Bir konteyner başlattınız, o güvenlik duvarının etrafından bir port yayımladı. Bir kerelik kontrol yalnızca bugün için yanıt verir, fazlası değil.

Değer listenin kendisinde değil, değişimindedir: dün olmayan yeni bir port, kısa ve son derece bilgilendirici bir sinyaldir. İzlemeye değer olan tam olarak budur — akıldan hatırlanan bir ss çıktısı olarak değil, geçmişiyle birlikte bir anlık görüntü olarak. Aşağıdaki demo sayfası tam da bunu gösterir.