Chapter Network Diagnostics memperkenalkan pola lima lapis — link, alamat IP, gateway, DNS, lalu port dan layanan — sebagai daftar periksa dari bawah ke atas. Chapter penutup section ini memakai pola itu untuk sungguhan: empat keluhan klasik dibedah satu per satu sebagai studi kasus, masing-masing dari gejala pertama yang terlihat sampai lapisan yang bersalah. Karena akhirnya semua diagnosis bermuara pada “ada yang mendengarkan dan menjawab”, kita menutup dengan skrip diagnosis berlapis yang bisa disimpan dan dijalankan ulang — latihan yang berlatar server lokal di loopback, persis pola latihan section ini.

Kasus 1: Kabel yang Tidak Terbaca #

Keluhan masuk: “mesin ini sama sekali tidak punya jaringan”. Pemeriksaan pertama selalu lapisan link — sebelum menyalahkan DHCP, DNS, atau aplikasi, kita pastikan kartunya hidup. Inilah contoh tampilan ip -br link pada mesin yang bermasalah:

console
$ ip -br link
lo               UNKNOWN        00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP>
enp3s0           DOWN           00:11:22:33:44:55 <NO-CARRIER,BROADCAST,MULTICAST,UP>

Kuncinya ada di dua bendera yang saling bertentangan itu: UP berarti kernel sudah menyalakan interface, tetapi NO-CARRIER berarti tidak ada sinyal yang terdeteksi di ujung kabel. Diagnosis selesai di lapisan paling bawah: ganti kabel, colok ulang, atau periksa port di switch — tidak ada perintah perangkat lunak yang bisa memperbaiki kabel yang putus. Aturan kerjanya: saat satu lapisan gagal, berhenti dan perbaiki di situ; masalah di atasnya hampir selalu cuma akibat. Untuk kartu wifi, padanan gejalanya adalah interface yang tidak muncul sama sekali — pertanyaannya menjadi apakah radio diblokir rfkill atau driver tidak termuat.

Kasus 2: Alamat 169.254.x.x, Tanda DHCP Gagal #

Kasus kedua lebih halus: kartu menyala, tautan bagus, tetapi mesin tidak bisa ke mana-mana. ip -br addr menunjukkan kartu punya alamat — tapi alamatnya berada di jangkauan 169.254.0.0/16, misalnya 169.254.7.13/16. Itu bukan hadiah dari DHCP: alamat link-local ini dipilih sendiri oleh mesin setelah permintaan DHCP gagal dijawab, sebagai jaringan darurat yang tidak bisa di-routing. Karena itu tidak ada default di ip route — paket keluar tidak punya pintu.

Penyebabnya berada di lapisan di atas link: server DHCP mati, mesin berada di VLAN yang salah, atau pool alamatnya habis. Jalur pemeriksaannya mengikuti proses DORA dari Chapter DHCP : pastikan tautan UP dan LOWER_UP dulu, lalu baca log client — journalctl -u NetworkManager memperlihatkan percakapan DISCOVER yang tidak pernah dijawab OFFER. Solusinya bisa sekecil menghubungkan kabel ke port yang benar, atau memanggil admin untuk menyalakan kembali server DHCP.

Kasus 3: IP Hidup, Nama Mati #

Kasus ketiga adalah yang paling sering menyesatkan: ping 192.0.2.1 dijawab baik-baik, tetapi curl ke nama domain gagal. Alamat IP berfungsi berarti lapisan link, alamat, dan gateway semuanya sehat — yang mati hanya penerjemahan nama. Konfirmasinya lewat jalur resolver persis seperti yang ditempuh aplikasi, bukan dengan bertanya langsung ke server DNS:

bash
getent hosts intranet.kantor.example.com

Perintah tersebut mencetak alamat bila nama terjawab, dan diam tanpa keluaran bila tidak — keluarannya kosong berarti lapisan DNS yang bersalah, bukan aplikasi. Pemeriksaan lanjutannya ada di Chapter DNS : isi /etc/resolv.conf (resolver mana yang dituju), lalu jangkauan server itu sendiri. Dalam latihan ini kita tidak bisa menguji nama eksternal secara deterministik, jadi cukup pastikan polanya: alamat IP hidup plus nama gagal hampir selalu berarti resolver, bukan aplikasi.

Kasus 4: Ditolak versus Timeout #

Kasus terakhir terjadi setelah semua lapisan bawah sehat: aplikasi tetap gagal menyambung. Di sini gejalanya terbelah dua, dan perbedaannya menentukan arah pencarian — paket yang ditolak berarti tujuan menjawab dengan tegas, sedangkan timeout berarti tidak ada yang menjawab sama sekali:

GejalaApa yang terjadiPenyebab khasPeriksa
gagal cepat, kode keluar 7kernel tujuan membalas RSTlayanan mati atau port salahss -tln di sisi server
menunggu lama lalu gagal, kode 28paket dibuang tanpa jawabanfirewall drop atau rute macetaturan firewall, ip route

Kita lihat gejala pertama langsung di loopback: server hidup, lalu kita sambung ke port yang tidak didengarkan siapa pun:

bash
curl -sS --max-time 2 127.0.0.1:9876/ 2>&1

Output yang Dihasilkan:

text
curl: (7) Failed to connect to 127.0.0.1 port 9876 after 0 ms: Could not connect to server

Kegagalan itu terjadi dalam hitungan milidetik — jaringan menolak dengan jujur. Bandingkan dengan firewall yang diam-diam membuang paket: curl akan menunggu sampai --max-time habis baru gagal dengan kode 28, tanpa pesan sama sekali. Dua gejala, dua tersangka, dua perintah pemeriksaan yang berbeda — inilah alasan tabel gejala seperti ini selalu lebih berguna daripada firasat.

Praktik: Skrip Diagnosis Berlapis #

Kalau pola lima lapis sudah melekat, menuliskannya sebagai skrip kecil membuat diagnosis bisa diulang dan dibagikan. Berkas diagnose.sh di bundle chapter ini memeriksa tiga lapisan secara berurutan — berkas layanan, port, lalu jawaban HTTP — dan mencetak status per langkah. Sebelum menguji skripnya, kita bangun dulu keadaan sehat sebagai patokan:

bash
printf 'layanan aktif\n' > index.html
python3 -m http.server 8765 --bind 127.0.0.1 >/dev/null 2>&1 &
server=$!
for i in 1 2 3 4 5; do curl -s -o /dev/null 127.0.0.1:8765/ && break; sleep 0.2; done
ss -tln | grep 8765
curl -s -o /dev/null -w 'jawaban: HTTP %{http_code}, %{size_download} byte\n' 127.0.0.1:8765/
kill "$server"

Output yang Dihasilkan:

text
LISTEN 0      5          127.0.0.1:8765       0.0.0.0:*   
jawaban: HTTP 200, 14 byte

Dua baris itu adalah definisi “sehat” versi Chapter Network Diagnostics : ada yang mendengarkan di 127.0.0.1:8765, dan layanan menjawab HTTP 200 dengan 14 byte isi. Sekarang skripnya, dijalankan pada keadaan yang sama:

bash
printf 'layanan aktif\n' > index.html
python3 -m http.server 8765 --bind 127.0.0.1 >/dev/null 2>&1 &
server=$!
for i in 1 2 3 4 5; do curl -s -o /dev/null 127.0.0.1:8765/ && break; sleep 0.2; done
bash diagnose.sh
kill "$server"

Output yang Dihasilkan:

text
== lapis 1: berkas layanan ==
OK: index.html ada
== lapis 2: port ==
OK: ada yang mendengarkan di port 8765
== lapis 3: jawaban layanan ==
OK: layanan menjawab

Tiga lapisan, tiga baris OK. Yang menarik adalah skrip itu sendiri — mari kita bedah bagian intinya:

  1. url=${1:-127.0.0.1:8765}: argumen pertama menjadi target, dengan 127.0.0.1:8765 sebagai bawaan — skrip bisa dipakai untuk host dan port mana pun tanpa diedit.
  2. port=${url##*:}: pemotongan parameter mengambil bagian setelah titik dua terakhir, yaitu nomor port.
  3. Lapis 1 ([ -f index.html ]): memeriksa syarat paling dasar layanan berbasis berkas — kalau asetnya tidak ada, dua lapisan di atasnya pasti ikut bingung.
  4. Lapis 2 (ss -tln | grep -q ":$port "): mendeteksi LISTEN pada port target, versi skrip dari pemeriksaan Chapter ss dan netstat .
  5. Lapis 3 (curl -s --max-time 2): menegaskan layanan benar-benar menjawab, bukan cuma membuka port; --max-time menjaga skrip tidak menggantung lama pada kasus timeout.

Terakhir, jalankan skrip yang sama pada keadaan rusak — tanpa berkas, tanpa server:

bash
bash diagnose.sh

Output yang Dihasilkan:

text
== lapis 1: berkas layanan ==
GAGAL: index.html tidak ada
== lapis 2: port ==
GAGAL: tidak ada pendengar di port 8765
== lapis 3: jawaban layanan ==
GAGAL: tidak ada jawaban (kode keluar 7)

Tiga baris GAGAL dengan kode keluar 7 pada lapisan terakhir menutup cerita dengan rapi: lapisan pertama yang gagal adalah tempat menghentikan pencarian. Perhatikan juga bahwa seluruh latihan section ini menempel di 127.0.0.1 — loopback memang tempat berlatih yang aman.

Dari interface sampai jawaban HTTP, seluruh perjalanan paket kini bisa kita susuri alat demi alat — dan dengan itu bagian jaringan dari Course ini ditutup. Mesin yang saling terhubung, sayangnya, juga berarti permukaan yang bisa diserang; memahami permission, privilege, dan prinsip least privilege adalah kelanjutan naturalnya di Section Security .

Referensi lanjut: halaman manual ip(8) untuk pemeriksaan link dan alamat, ss(8) untuk pemeriksaan socket, serta curl(1) untuk daftar lengkap kode keluarnya.

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

diagnose.sh

Unduh berkas
bash
#!/usr/bin/env bash
# diagnose.sh -- diagnosis berlapis untuk layanan HTTP lokal
# pemakaian: bash diagnose.sh [host:port]   (bawaan 127.0.0.1:8765)
url=${1:-127.0.0.1:8765}
port=${url##*:}

echo "== lapis 1: berkas layanan =="
if [ -f index.html ]; then
    echo "OK: index.html ada"
else
    echo "GAGAL: index.html tidak ada"
fi

echo "== lapis 2: port =="
if ss -tln | grep -q ":$port "; then
    echo "OK: ada yang mendengarkan di port $port"
else
    echo "GAGAL: tidak ada pendengar di port $port"
fi

echo "== lapis 3: jawaban layanan =="
if curl -s --max-time 2 -o /dev/null "$url"; then
    echo "OK: layanan menjawab"
else
    echo "GAGAL: tidak ada jawaban (kode keluar $?)"
fi