Troubleshooting di Linux

Ada banyak masalah di dunia IT setiap hari meskipun software dan hardware sudah terpasang dan tidak diubah sama sekali. Beberapa contohnya: sesuatu menjadi semakin lambat (misalnya karena jumlah data menumpuk terlalu banyak), sesuatu tidak bekerja sama sekali (disk penuh, hardware rusak), mendapat serangan DDOS, ISP tiba-tiba memblok suatu website, dsb.

Jika ada sesuatu yang baru, masalahnya bisa lebih banyak lagi. Sesuatu yang baru ini bisa dari hal rutin misalnya upgrade software (contohnya baru-baru ini: ada masalah SSL di Chrome terbaru jika memakai SSL certificate tertentu) ataupun dari penambahan hardware maupun software karena ada kebutuhan baru.

Program top

Di posting ini saya ingin membahas cara troubleshooting generik berbagai masalah yang berhubungan dengan Linux. Pendekatan saya adalah pendekatan programmer: semua masalah admin sebenarnya adalah masalah debugging software. Pada dasarnya administrasi sistem (selain bagian memasang hardware) hanyalah menjalankan program dengan parameter/setting tertentu. Prinsip “debugging” ini bisa diaplikasikan ke sistem operasi apapun tapi saya hanya akan membahas tools khusus Linux di artikel ini.

Bagi sebagian orang ini merupakan hal yang jelas/obvious (“tentu saja mencari masalah itu sama seperti debugging program”). Sayangnya saya masih sering orang yang bingung dalam troubleshooting, dan akhirnya hanya coba-coba. Dan kadang solusinya meskipun “berhasil” tapi ternyata membuka masalah security. Contohnya ketika ingin mengkonfigurasi agar DBMS (misalnya postgres atau mysql) bisa diakses dari jaringan lokal, tapi ternyata malah bisa diakses dari seluruh internet. Dalam kasus ini karena dari jaringan lokal berhasil diakses dan sudah dianggap OK.

Semua program sifatnya sama: membaca input, memproses sesuai dengan algoritma tertentu, dan membuat output. Bahkan masalah jaringan pun sama: inputnya adalah paket data di jaringan dan konfigurasi jaringan (IP, routing, rule firewall, dsb), dan sistem operasi akan menjalankan beberapa algoritma (filtering, routing, dsb), lalu outputnya adalah paket yang diberikan ke program atau diteruskan ke host lain.

Tiga jenis masalah utama yang saya temui adalah sesuatu tidak berjalan sama sekali, sesuatu lambat (masalah kinerja), dan sesuatu tidak bekerja sesuai yang diharapkan. Contoh kasus terakhir misalnya: seharusnya direktori ini yang muncul di web, tapi kok direktori lain yang muncul atau muncul pesan warning/error walaupun program berjalan.

Prekondisi

Sebuah program akan berjalan benar jika prekondisi dipenuhi. Contoh: program konversi citra bisa berjalan jika ada input yang valid, ada disk space yang cukup untuk output. Beberapa program berasumsi bahwa ini pasti benar, sehingga jika disk space habis, kasus tersebut tidak ditangani, dan hanya muncul error generik. Jadi langkah pertama adalah: cek prekondisi dasar sebuah sistem.

Sebelum masuk ke debugging spesifik Linux, hal pertama adalah mengecek hal-hal yang jelas dulu. Apakah koneksi internet jalan? tidak ada masalah di ISP, cloud provider, dsb. Apakah hardware baik-baik saja? misalnya ternyata komputer mati karena kabel dimakan tikus. Jika masalah non-software yang bisa dicek eksternal tidak ada masalah, kita bisa masuk ke bagian berikutnya.

Prekondisi berikutnya adalah: disk tidak error. Hal ini bisa dicek dengan dmesg,  apakah ada pesan error dari kernel.  Ini penting karena jika ada hardware bermasalah maka akan muncul error di sini. Jika ada error, sebuah filesystem akan di-remount menjadi readonly, artinya log file tidak bisa diandalkan (tidak valid).

Lalu cek disk space sistem. Jika disk space penuh, maka log mungkin akan gagal ditulis jadi kita tidak mendapatkan error message yang benar.  Disk space bisa dicek dengan df (disk free). Jika ternyata memang penuh, kita bisa memakai program du (disk usage) untuk mencari tahu direktori/file mana yang memakan space banyak. Masalah disk ini juga kadang bisa dilihat dari “wa” (berapa banyak I/O yang menunggu) di program “top“. Secara umum, pelajarilah berbagai nilai yang muncul di program top, karena ini sangat berguna.

Membaca Pesan Error

Jika hardware dan disk space sudah aman, maka prekondisi dasar sudah terpenuhi. Berikutnya ketika melihat sesuatu yang error adalah: membaca pesan error yang memang sudah diberikan oleh program. Kadang program perlu dikonfigurasi agar mengoutputkan log dan kadang level loggingnya perlu ditingkatkan agar lebih jelas errornya.

Log system biasanya bisa dibaca di /var/log. Tapi ini belum tentu benar, log system bisa dikirim ke sistem lain. Kita baca membaca konfigurasi program di mana log disimpan. Jika program memakai syslog, kita perlu membaca konfigurasi syslog.

Jika memang sudah jelas dari error messagenya (misalnya: “file abc not found”) maka tanganilah error itu (buat file abc-nya, atau mungkin salah path file-nya). Sayangnya kadang  error message tertentu seperti “resource temporarily unavailable”, penyebabnya bisa banyak. Salah satu cara mencari solusi tentunya adalah dengan mencari pesan error di internet plus nama program yang berhubungan, misalnya “docker resource temporarily unavailable” (jika konteksnya ketika memakai docker). Jika ketemu orang dengan masalah yang sama dan gejala yang sama, maka mungkin itu solusinya.

Mencari masalah di internet juga sering kali merupakan cara terbaik, karena kadang solusi suatu masalah sangat panjang. Tapi jika kita tidak mengerti akar suatu permasalahan, kadang solusinya juga bisa melenceng jauh.

Membaca status program

Kita bisa mengecek apakah program sudah dijalankan dengan parameter yang benar dan dengan environment yang benar menggunakan filesystem /proc. Ini terutama dibutuhkan jika program dijalankan oleh skrip atau program lain. Dengan mengetahui PID (process id , proses adalah instance program yang sedang berjalan) kita bisa membaca status di /proc/PID.

Beberapa yang penting misalnya “cwd” adalah link ke direktori program saat ini. File “environ” berisi environment variable ketika aplikasi dijalankan. File “cmdline” berisi parameter ketika program dijalankan. Masih banyak lagi file-file lain yang berguna untuk mengecek status program saat ini.

Membaca Dokumentasi dan Changelog

Masalah lain yang mungkin ditemui ketika upgrade software adalah: suatu fitur diubah atau hilang. Dalam kasus ini yang perlu dibaca bukan hanya file log tapi juga  dokumentasi aplikasi tersebut.

Beberapa aplikasi memiliki tool atau opsi untuk mengecek apakah file konfigurasi sudah benar atau belum (terutama untuk mengetahui apakah di versi terbaru opsi masih valid), ini bisa digunakan untuk mencari tahu sumber error. Contohnya apache memiliki “apachectl configtest”.

Debugging Masalah Jaringan

Untuk masalah jaringan  biasanya masalahnya adalah tentang konektivitas (sesuatu tidak bisa diakses atau paket tidak diteruskan). Saya memakai gabungan banyak tool untuk debugging. Tool dasar pertama adalah “ping” (mengecek konektivitas ke host lain) dan traceroute untuk mengetahui route yang diambil paket. Program “ip” juga memiliki opsi untuk mengecek route di host saat ini: “ip route get to TUJUAN” (misalnya “ip route get to 192.168.1.2").

Sering kali program tidak bisa diakses dari host lain karena memang hanya menerima koneksi dari localhost. Ini bisa dicek dengan program netstat (terutama dengan opsi -l untuk melihat program yang statusnya “listening”). Setelah diperbaiki konfigurasinya kadang program menolak karena filter di dalam program tersebut. Contohnya: postgreSQL memiliki opsi listen_interface di postgresql.conf, tapi jika sudah diset, postgresSQL akan mengecek ke pg_hba.conf untuk mengecek apakah IP spesifik tertentu diijinkan untuk melakukan koneksi atau tidak. Dalam semua kasus kita perlu memahami hal-hal seperti ini.

Jika host bisa dihubungi dengan ping tapi ada service yang tidak bisa diakses dari host lain, maka saya akan memakai netcat untuk mengetes. Kadang saya pakai juga  “nmap”  untuk mengecek semua port untuk mengecek apakah ISP memblock port tertentu.

Jika masalahnya ada di firewall yang kita kontrol (bukan firewallnya ISP) maka kita perlu mendebug masalahnya dengan logging. Baik iptables maupun nftables mendukung logging untuk mencari tahu kenapa sebuah paket di-drop.

Senjata andalan terakhir adalah tcpdump dan wireshark. Kedua program ini dapat menangkap semua paket yang lewat. Jika yang bermasalah adalah komputer lokal, saya akan langsung memakai wireshark dengan GUI yang enak dilihat. Jika masalahnya di komputer remote, saya akan memakai tcpdump. Kadang output tekstual tcdump sudah cukup, tapi jika masih kurang, saya akan memakai opsi -w untuk menuliskan hasil capture ke file pcap yang bisa dicopy ke desktop lalu dilihat isinya secara visual.

Debugging Program

Kebanyakan program memiliki beberapa opsi dasar untuk debugging. Biasanya opsi  yang penting adalah: menampilkan log, atau menaikkan level logging dan membuat agar program tidak berjalan di latar belakang (foreground mode atau no daemon mode). Dua hal ini biasanya sudah cukup untuk mencari tahu kebanyakan error.

Jika semua pendekatan sudah mentok maka pendekatan programming akan saya ambil. Pertama adalah dengan  strace dan ltrace. Kedua program low level ini berguna untuk tracing, strace untuk syscall dan ltrace untuk library call. Kadang program-program ini bisa dipakai tanpa pengetahuan programming, tapi biasanya butuh pengetahuan programming terutama jika masalahnya kompleks.

Tracing di sini berarti semua pemanggilan library (untuk ltrace) dan system call (untuk strace) akan ditampilkan. Contoh paling sederhana adalah untuk debugging: kenapa aplikasi tidak membaca file sesuatu yang tercantum di konfigurasi. Dari hasil tracing bisa dilihat apakah filenya namapakcagegagal dibuka (misalnya masalah permission) atau ternyata tidak ditemukan (mungkin karena salah nama file, atau programnya menambahkan prefix/suffix tertentu sehingga tidak ketemu).

Contoh memakai strace untuk mengecek file apa yang dicoba dibuka oleh sebuah aplikasi dalah dengan membatasi output hanya syscall open dan access saja.

strace -e open,access namaprogram

Debugging berikutnya sudah sangat butuh skill programming, yaitu memakai debugger gdb. Dengan menginstall debug symbol, umumnya berbagai masalah crash bisa dicari tahu sebabnya. Andaikan debug symbol tidak cukup, maka langkah berikutnya adalah: compile ulang aplikasinya, lalu debug di level source code.

Compile ulang ini tidak sesulit jaman dulu. Di Debian kita bisa dengan mudah menggunakan “apt-get source namapackage” untuk mendownload source code package tertentu, dan “apt-get build-dep namapackage” untuk mendownload seluruh library/tool yang diperlukan untuk membuat package tersebut. Selanjutnya kita bisa mengcompile dan mendebug program dengan mudah.

Masalah performance

Masalah yang cukup sulit dicari adalah masalah performance karena biasanya tidak ada pesan di log. Masalah performance juga biasanya sangat spesifik pada aplikasi atau software server tertentu. Tapi Sebelum mengecek spesifik software tersebut cek dulu penggunaan CPU dan memory dengan top.

Apakah ada proses yang memakan banyak CPU atau memori? jika ada, harus diperhatikan karena itu mungkin sumber masalah utama. Jadi ketika database tiba-tiba lambat, belum tentu server databasenya bermasalah, mungkin saja ada proses lain yang memakan terlalu banyak CPU atau memori dan efeknya terasa ke query database.

Sebuah program bisa melakukan banyak langkah, dan kadang langkah tertentu menghambat langkah berikutnya, dan secara total aksi tertentu menjadi sangat lambat. Contoh sederhana: sebuah program bisa melakukan reverse DNS lookup untuk memetakan IP menjadi nama, dan menampilkan informasi tersebut ke log file. Jika ada masalah dengan DNS, maka proses yang tujuannya hanya informatif (melog informasi) ini butuh waktu lama karena masih menunggu respons dari server DNS.

Dari sudut pandang programmer, ada banyak tool yang bisa dipakai untuk debugging masalah performance. Tool ini meliputi software profiler spesifik untuk bahasa/teknologi tertentu (misalnya ada profiler khusus untuk Java, Python dsb), dan juga profiler system secara umum (misalnya Systemtap dan perf).

Penutup

Semua langkah ini biasanya cukup untuk menemukan masalah dan memperbaiki masalah tertentu. Namun demikian tidak semua masalah bisa diselesaikan dengan mudah.

Beberapa masalah tiba-tiba hilang karena restart program  (jika masalahnya ada di programnya), atau restart komputer (jika masalahnya ada di kernelnya). Dalam kasus ini akar permasalahan harus dicari, karena pasti akan muncul lagi.

Selain itu tidak semua masalah bisa diatasi dengan singkat, contohnya: ketika upgrade program tertentu, program tersebut butuh upgrade library, dan setelah upgrade library, program lain yang closed source ternyata berhenti berjalan. Akhirnya program harus dijalankan di chroot atau Docker dengan library lama dan ini butuh waktu.

Semoga langkah-langkah yang diberikan di tulisan ini berguna. Intinya sih jangan semuanya hanya proses coba-coba, tapi pahamilah akar masalahnya.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.