Daftar port terbuka adalah daftar jalan menuju server Anda. Semua sisanya — firewall, WAF, deteksi penyusupan — dibangun di atasnya. Karena itulah «apa yang sedang mendengarkan di sini» selalu jadi yang pertama dalam audit mana pun, dan karena itu pula inilah pemeriksaan yang paling sering memberi jawaban tidak menyenangkan: separuh dari yang ditemukan dibuka bukan oleh Anda melainkan oleh pemasang suatu paket.

Membaca keluarannya

sudo ss -tulpn

Benderanya: t untuk TCP, u untuk UDP, l hanya yang mendengarkan, p untuk proses, n supaya angka tetap angka. Tanpa sudo kolom prosesnya kosong dan seluruh latihan ini kehilangan maknanya.

Yang penting adalah kolom Local Address:Port, dan perbedaan di sana bersifat mendasar:

  • 127.0.0.1:3306 — layanan hanya terjangkau dari mesin itu sendiri. Itu bagus;
  • 0.0.0.0:3306 — dari setiap alamat IPv4, artinya dari internet. Inilah yang perlu diperiksa;
  • [::]:3306 — hal yang sama untuk IPv6. Baris tersendiri, dan rutin terlewat;
  • 203.0.113.25:443 — pada alamat tertentu, biasanya disengaja.

Lalu untuk setiap baris dengan 0.0.0.0 atau [::], ajukan satu pertanyaan: apakah orang asing seharusnya bisa menjangkau ini. Untuk 80 dan 443 jawabannya ya. Untuk hampir semua sisanya tidak.

Temuan yang lazim

Redis, port 6379. Baris paling berbahaya di sana. Secara bawaan Redis tidak menuntut kata sandi, dan perintahnya memungkinkan menulis berkas ke disk — artinya kunci asing di authorized_keys. Antara Redis muncul di alamat publik dan mulai dimanfaatkan hanya berjarak beberapa jam, kadang kurang. Periksa bind 127.0.0.1 dan protected-mode yes di konfigurasi.

Memcached, 11211/UDP. Meskipun di dalamnya tidak ada yang berharga, server Anda menjadi penguat bagi serangan orang lain — dan keluhannya akan datang dari penyedia Anda.

MySQL dan PostgreSQL, 3306 dan 5432. Kata sandinya memang ada, tetapi penebakannya berlangsung terus-menerus, sementara versi basis data diperbarui lebih jarang dari yang diinginkan. Mereka hampir tidak pernah perlu menghadap keluar: aplikasinya ada di mesin yang sama, dan untuk pekerjaan Anda sendiri terowongan SSH sudah cukup.

Elasticsearch 9200, MongoDB 27017. Secara historis tanpa autentikasi bawaan. Instans publik keduanya adalah sumber berita kebocoran data yang tetap.

Docker API, 2375. Port kendali Docker yang terbuka adalah root pada host tanpa kata sandi apa pun. Ia biasanya muncul setelah percobaan akses jarak jauh ke Docker.

Panel kendali dan phpMyAdmin di port masing-masing: 8080, 8083, 10000. Bukan berarti tidak boleh dibuka sama sekali, tetapi justru merekalah yang mengumpulkan sebagian besar percobaan.

Perbaiki di layanannya, bukan di firewall

Keinginan menutup setiap temuan dengan aturan UFW itu bisa dimengerti, tetapi itu garis kedua, bukan yang pertama. Aturan bisa terhapus tanpa sengaja, firewall bisa dimatikan sementara saat penelusuran galat, dan Docker malah menerbitkan port sepenuhnya melewati UFW. Pengaturan pengikatan di konfigurasi layanan itu sendiri bertahan melewati semua itu:

  • MySQL/MariaDB — bind-address = 127.0.0.1;
  • PostgreSQL — listen_addresses = 'localhost';
  • Redis — bind 127.0.0.1 ::1;
  • Docker Compose — terbitkan sebagai "127.0.0.1:5432:5432".

Firewall dipasang di atasnya sebagai asuransi, bukan sebagai penggantinya.

Menemukan prosesnya kalau tidak jelas

ss memberi nama dan pid. Lalu:

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

Perintah pertama menyebut unit systemd milik proses itu — biasanya cukup untuk memahami itu apa dan perlu atau tidak. Sebuah proses asing yang mendengarkan di port tinggi dan dijalankan dari luar direktori sistem — misalnya dari /tmp atau /dev/shm — bukan lagi soal konfigurasi melainkan dasar untuk penyelidikan tersendiri.

Pemeriksaan dari luar itu wajib

ss menjawab «apa yang mendengarkan», bukan «apa yang bisa dijangkau». Di antara keduanya berdiri firewall, NAT dan aturan penyedia sendiri. Jawaban jujur hanya didapat dengan memindai dari mesin lain:

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

Jangan lewatkan perintah kedua: hampir setiap VPS punya alamat IPv6, aturannya ditulis terpisah, dan layanan mendengarkan pada kedua versi protokol sekaligus.

Ini bukan pemeriksaan sekali jalan

Daftar port terbuka berubah dengan sendirinya. Anda memasang sebuah paket dan ia membawa layanan lalu membuka port. Anda memperbarui panel dan ia mengembalikan nilai bawaan. Anda menjalankan kontainer dan ia menerbitkan port melewati firewall. Pemeriksaan sekali jalan menjawab untuk hari ini, tidak lebih.

Nilainya bukan pada daftarnya sendiri melainkan pada perubahannya: sebuah port baru yang kemarin belum ada adalah sinyal singkat dan sangat informatif. Persis begitulah cara ia layak diawasi — sebagai snapshot dengan riwayat, bukan sebagai keluaran ss yang diingat-ingat. Halaman demo di bawah menunjukkan persis hal itu.