FAQ

Ini adalah panduan untuk instalasi, konfigurasi, dan pemeliharaan Arcivéo Monitor. Bagian-bagiannya dikelompokkan: ikhtisar umum, penerapan dashboard, penyambungan alat keamanan, modul bawaan, dan diagnostik. Perintah dapat disalin dengan tombol di sebelah kanan.

Mulai dari mana

01. Instalasi panel — pilih metode

Instalasi panel tersedia di halaman langkah demi langkah tersendiri. Pilih metode:

Jika ragu, pilih yang otomatis. Panduan ini tetap menjadi sumber tunggal untuk SSL, alat, cron, dan diagnostik — halaman instalasi merujuk ke bagian-bagiannya tanpa menduplikasi apa pun.

Ikhtisar

02. Apa itu Arcivéo Monitor

Arcivéo Monitor — dashboard keamanan server. Mengumpulkan data dari alat yang terpasang (Fail2ban, UFW, Lynis, ModSecurity, AIDE, ClamAV, Auditd, CrowdSec, Suricata, Falco, dll.) dan menampilkannya dalam satu antarmuka dengan dashboard, peta serangan, dan halaman rinci untuk setiap alat.

Monitor bukan alat perlindungan aktif — ia tidak memblokir serangan sendiri. Tugasnya adalah menggabungkan informasi dari alat yang sudah berjalan dan menyajikannya dalam bentuk yang mudah dipahami.

03. Cara kerja monitor di server

Monitor bekerja hanya secara lokal — harus dipasang di server yang sama dengan yang dipantau. Tidak ada SSH atau API jarak jauh.

Semua perintah (fail2ban-client, ufw status, ipset list dsb.) dijalankan panel atas nama pengguna web server (biasanya www-data, di panel hosting — akun situs) dengan hak akses terbatas sudo — hanya untuk utilitas tertentu, tanpa akses root umum. Hasilnya diurai dan ditampilkan di browser.

Untuk beberapa server, pasang monitor di masing-masing secara terpisah, dengan domain unik.

04. Bagaimana Skor keamanan dihitung

Skor dimulai dari nilai maksimum dan berkurang untuk setiap masalah yang ditemukan:

  • UFW tidak aktif — −30
  • Fail2ban tidak berjalan (tidak ada jail aktif) — −25
  • Tidak ada kunci WebAuthn — −15
  • Lynis hardening index < 60 — −20; 60–79 — −10
  • IPset ipsum tidak dimuat — −10
  • Ancaman ditemukan ClamAV — −20
  • Perubahan berkas AIDE — −15
  • SSL kedaluwarsa — −30, kedaluwarsa <14 hari — −15, <30 hari — −5
  • CrowdSec terpasang, tetapi tidak berjalan — −5
  • Suricata terpasang, tetapi tidak berjalan — −5
  • DBMS/cache (MySQL, PostgreSQL, Redis…) dapat diakses dari luar — −10
  • Login root via SSH diizinkan (PermitRootLogin yes) — −20
  • Pembaruan keamanan menunggu pemasangan — −5

Hasil: 80+ = Terlindungi, 60–79 = Perhatian, <60 = Terancam.

Pengurangan untuk ClamAV, AIDE, CrowdSec, dan Suricata hanya berlaku jika alat terpasang. Lynis dan AIDE tanpa basis data yang terinisialisasi ditampilkan sebagai “tidak ada data” dan tidak mengurangi skor. Jumlah serangan hari ini ditampilkan di dasbor, tetapi tidak memengaruhi Skor keamanan.

Pengaturan dan lisensi

05. WebAuthn — autentikasi dua faktor

WebAuthn — standar autentikasi tanpa kata sandi melalui kunci keamanan perangkat keras. Mendukung YubiKey, Touch ID, Face ID, Windows Hello, Passkey.

Setelah masuk dengan kata sandi, sistem meminta konfirmasi melalui kunci keamanan yang terdaftar. Sekalipun kata sandi bocor — tanpa kunci fisik atau biometrik, masuk tidak dimungkinkan.

Untuk mengatur, buka Kunci WebAuthn di menu samping lalu klik “Daftarkan kunci”. Daftarkan dua kunci sekaligus: jika satu-satunya kunci hilang atau rusak, masuk ke dashboard dengan kunci itu tidak akan mungkin.

WebAuthn hanya bekerja melalui HTTPS. Pada koneksi HTTP, pendaftaran dan masuk dengan kunci tidak tersedia.

06. Notifikasi: Telegram dan Email

Dashboard bisa mengirim laporan keamanan ke Telegram dan email (lewat tombol dan terjadwal). Diatur di bagian “Setelan”.

Telegram. Diperlukan token bot dan chat id:

  1. Di Telegram, kirim pesan ke @BotFather/newbot → dapatkan token berbentuk 123456:ABC....
  2. Kirim pesan apa saja ke bot baru Anda (agar ia bisa membalas Anda).
  3. Cari tahu chat id Anda: kirim pesan ke bot @userinfobot, atau buka https://api.telegram.org/bot<TOKEN>/getUpdates dan temukan "chat":{"id":...}.
  4. Masukkan token dan chat id ke “Setelan” → Telegram, lalu klik “Simpan dan kirim tes”.

Email. Dua cara pilihan di “Setelan” → Email:

  • SMTP — host, port (465/SSL atau 587/TLS), login dan kata sandi kotak surat Anda;
  • Resend — API modern: masukkan kunci API (re_...) dan domain pengirim yang sudah diverifikasi.
Tombol “Kirim tes” akan langsung menguji saluran. Jadwal laporan otomatis — lewat cron (bagian “Semua tugas cron”): cron memicu pengiriman, sedangkan saluran diambil dari setelan.

Status laporan: “PERHATIAN” atau “OK”. Judul menjadi “PERHATIAN” hanya saat ada masalah nyata atau tindakan yang tertunda: ClamAV menemukan ancaman, perubahan file di AIDE, event kritis Falco (Emergency/Alert/Critical dalam 24 jam terakhir), layanan mati di Monit, perlu reboot, SSL akan kedaluwarsa (≤14 hari) atau ada pembaruan keamanan yang menunggu. Derau latar — percobaan brute force SSH oleh bot, IP yang dibanned fail2ban, alert Suricata, peringatan Lynis, serta permintaan ModSecurity yang sudah ditangkis — tidak menaikkan status, jadi angka-angka seperti itu dalam laporan bukan berarti “PERHATIAN” dengan sendirinya.

07. Lisensi — memasukkan dan mengaktifkan

Modul pemantauan terperinci (Lynis, UFW, ModSecurity, peta serangan, AIDE, ClamAV, dll.) terbuka jika ada lisensi aktif. Tanpanya, dasbor, pengaturan, dan akun tetap berfungsi, sedangkan modul menampilkan kartu “Perlu lisensi”.

Setelah membeli di akun, Anda punya kode aktivasi berformat ARCIVEO-XXXX-XXXX-XXXX-XXXX. Kode itu perlu “diaktifkan” ke domain panel Anda — ini mengubah kode menjadi berkas lisensi bertanda tangan (blok [license]) yang Anda tempelkan ke panel.

Cara mengaktifkan (3 langkah):

  1. Ambil kode aktivasi. Akun my.arciveo.com → bagian “Lisensi” / “Aktivasi lisensi” — salin kode ARCIVEO-….
  2. Aktifkan kode ke domain Anda. Di akun yang sama, buka “Aktivasi lisensi”, masukkan: kode aktivasi, email Anda, dan domain panel (alamat tempat monitor terbuka, mis. monitor.example.com). Klik aktifkan — sistem akan membuat berkas lisensi yang terikat ke domain itu dan menampilkannya di kolom dengan tombol “Salin”.
  3. Tempel kunci ke panel. Salin seluruh teks lisensi → di panel buka “Pengaturan” → blok “Lisensi”, tempel dan klik “Simpan”. Modul langsung terbuka.

Panel memverifikasi kunci secara kriptografis: tanda tangan, keterikatan ke domain, dan masa berlaku.

Domain saat aktivasi harus sama persis dengan alamat panel. Ambil dari konstanta APP_URL di config.php dan masukkan hanya nama host — tanpa https:// dan tanpa awalan www. Aktivasi hanya sekali: kode berubah menjadi lisensi untuk domain yang dimasukkan dan tidak dapat diaktifkan ulang — jika domain salah, kunci tidak cocok dengan panel Anda, dan kode terbuang. Karena itu masukkan domain dengan teliti.
Jika masa berlaku habis atau domain berubah — peringatan akan muncul di bagian atas panel. Lisensi terikat ke domain selamanya dan tidak dapat dipindahkan ke domain lain: untuk masa berlaku baru atau domain baru diperlukan kunci baru (dibeli di akun dan diaktifkan sekali pakai).

08. Berkas config.php — semua pengaturan panel

Semua parameter utama panel diatur dalam satu berkas config.php di root (di samping folder public/) berupa konstanta define() biasa. Berkas dibuat saat instalasi; menyuntingnya secara manual jarang diperlukan — biasanya hanya saat mengganti domain, memindahkan, atau menyambung ke basis data lain. Setelah setiap perubahan mulai ulang PHP-FPM (jika tidak, perubahan tak akan diterapkan karena OPcache).

Isikan nilai Anda pada bagian yang disorot; sisanya biarkan apa adanya:

// --- Basis data --- define('DB_HOST', 'localhost'); // biarkan define('DB_NAME', 'db_name'); // yang Anda tetapkan saat membuat BD define('DB_USER', 'user'); // yang Anda tetapkan saat membuat BD define('DB_PASS', 'db_password'); // yang Anda tetapkan saat membuat BD define('DB_CHARSET', 'utf8mb4'); // biarkan // --- Aplikasi --- define('APP_URL', 'https://monitor.example.com'); // alamat panel, tanpa garis miring di akhir define('TIMEZONE', 'Asia/Jakarta'); // zona waktu Anda // --- Waktu sesi --- define('SESSION_LIFETIME', 28800); // idle sampai masuk ulang, detik (28800 = 8 jam)

Basis data. Kredensial koneksi ke MySQL/MariaDB:

  • DB_HOST — host DBMS, hampir selalu localhost;
  • DB_NAME — nama basis data panel;
  • DB_USER — pengguna BD (akses hanya ke basisnya sendiri);
  • DB_PASS — kata sandi pengguna ini;
  • DB_CHARSET — enkode koneksi, biarkan utf8mb4.

Aplikasi.

  • APP_URL — alamat lengkap panel (mis. https://monitor.example.com). Harus sama dengan domain tempat lisensi diaktifkan — jika tidak, kunci akan ditolak (lihat bagian “Lisensi”);
  • TIMEZONE — zona waktu PHP: hanya memengaruhi cara panel menampilkan tanggal dan waktu. Tidak memengaruhi waktu jalannya tugas cron — di sana berlaku zona sistem (lihat “Semua tugas cron”).

Waktu sesi. SESSION_LIFETIME — batas waktu idle sesi dalam detik (bergulir: diperbarui saat ada aktivitas). Bawaannya 28800 = 8 jam; setelah durasi tak aktif ini, panel akan meminta masuk kembali. Misalnya, 3600 = 1 jam, 86400 = sehari.

Pencatatan galat. Galat tak pernah ditampilkan ke pengunjung, melainkan ditulis ke logs/php_errors.log — terlihat di halaman “Log aplikasi”. Baris-baris ini (display_errors=0, log_errors=1, jalur error_log) biasanya tak perlu diubah — pengaturan ditetapkan langsung di berkas dan tidak bergantung pada php.ini.

config.php — berkas rahasia. Di dalamnya ada kata sandi BD. Berkas ini terletak di root panel (di samping public/), dan web-root (DocumentRoot) panel ini adalah root panel itu sendiri, bukan public/. Berkas ini tidak “bocor” dengan sendirinya: di .htaccess root ada larangan eksplisit untuknya (Require all denied) — server mengembalikan 403. Bahkan tanpa aturan ini, sumbernya tak akan bocor: ini PHP — server mengeksekusinya, bukan menyajikannya sebagai teks. Untuk berjaga-jaga: jangan unggah ke repositori publik dan jangan kirim ke dukungan dengan kata sandi asli. Izin berkas — 640.
Saat memindahkan atau memulihkan akses, berkas ini adalah sumber utama kredensial: nama BD, pengguna, dan kata sandi diambil dari sini (lihat bagian “Pembaruan dan pemindahan panel” dan “Pemulihan akses”).

Alat keamanan

09. Firewall UFW

UFW (Uncomplicated Firewall) — antarmuka sederhana untuk nftables/iptables. Menutup semua port masuk kecuali yang diizinkan secara eksplisit. Halaman “Firewall UFW” menampilkan status dan aturan.

sudo apt install ufw # Izinkan SSH (wajib SEBELUM mengaktifkan!) dan web sudo ufw allow OpenSSH sudo ufw allow 80,443/tcp # Tutup basis data dari luar (akses hanya lokal) sudo ufw deny 3306 # Aktifkan dan periksa sudo ufw enable sudo ufw status verbose
Sebelum ufw enable, wajib izinkan SSH (ufw allow OpenSSH), jika tidak Anda akan kehilangan akses ke server.
“Eksposur eksternal” pada dashboard memperhitungkan UFW: port yang ditutup dengan aturan deny tidak dianggap dapat diakses dari luar.
Skipping adding existing rule — ini bukan kesalahan. Dengan begitu UFW memberi tahu bahwa aturan yang sama persis sudah ada, dan tidak menambahkannya lagi. Saat menjalankan ulang konfigurasi otomatis (yang bersifat idempoten), ini adalah pesan normal — tidak perlu ditanggapi.

10. Instalasi Fail2ban

Memblokir IP secara otomatis setelah jumlah percobaan login gagal melebihi batas. Menganalisis log SSH, nginx, Apache, dan layanan lainnya.

sudo apt install fail2ban sudo systemctl enable --now fail2ban # Periksa status: sudo fail2ban-client status
Konfigurasi kerja (jail.local dengan puluhan jail dan autoban dari ipsum) — ada di bagian berikutnya.

11. Konfigurasi kerja Fail2ban + ipsum

Instalasi dasar ada di atas. Di sini adalah konfigurasi kerja yang menghasilkan puluhan jail aktif dan ribuan blokir: pengaturan umum, jail utama, dan autoban IP berbahaya dari daftar ipsum.

Berkas /etc/fail2ban/jail.local — pengaturan umum dan jail terpenting:

[DEFAULT] bantime = 1w findtime = 900 maxretry = 3 backend = systemd banaction = nftables-multiport ignoreip = 127.0.0.1/8 ::1 <YOUR_IP> <TRUSTED_NETS> # Ban progresif: tiap pengulangan makin lama bantime.increment = true bantime.factor = 2 bantime.maxtime = 5w bantime.rndtime = 300 [sshd] enabled = true maxretry = 5 bantime = -1 # ban permanen untuk brute-force SSH findtime = 3600 # Residivis: yang kena beberapa kali ban akan diban selamanya [recidive] enabled = true logpath = /var/log/fail2ban.log banaction = %(banaction_allports)s bantime = -1 findtime = 86400 maxretry = 2 [http-get-dos] enabled = true maxretry = 100 findtime = 300 bantime = 1w # Layanan web (apache-*, nginx-*, php-url-fopen, phpmyadmin-syslog): [nginx-http-auth] enabled = true port = http,https [apache-badbots] enabled = true port = http,https # … dan jail lainnya per layanan (dovecot, exim, postfix-sasl, # mysqld-auth, vsftpd, portscan, pam-generic) — enabled = true
Pada ignoreip wajib masukkan IP Anda sendiri dan jaringan tepercaya, jika tidak Anda bisa memblokir diri sendiri. Setelah perubahan: sudo fail2ban-client reload.

Pemuatan otomatis daftar blokir ipsum — ke cron root (sudo crontab -e): level 1 (100+ ribu IP) dimuat ke set ipsum, yang diblokir di firewall (selengkapnya di bagian “Daftar blokir IPset”):

# 04:00 — pembaruan ipset ipsum (level 1, cakupan maksimal): 0 4 * * * /usr/local/bin/load-ipsum.sh >> /path/to/monitor/logs/cron.log 2>&1
Set harus bernama ipsum — itulah yang dibaca dasbor (kartu “IPset ipsum”). Level: levels/1.txt — cakupan maksimal, levels/3.txt — lebih akurat (3+ sumber).

Mengapa “Monitor keamanan” dibagi menjadi dua zona. Perlindungan bekerja di dua tingkat, dan dasbor tidak mencampurnya:

  • Serangan nyata (reaktif) — semua yang ditangkap fail2ban: upaya peretasan langsung (jail sshd, apache-*, nginx-* dsb.) dan residivis berat (jail recidive — yang sudah diban beberapa kali). Ini IP yang benar-benar menyerang Anda — mereka ada di peta serangan dan “Garis waktu”.
  • Blokir preventif (proaktif) — daftar blokir publik berisi IP berbahaya yang diketahui ipset ipsum, diblokir di firewall dengan aturan DROP. Sebagian besar alamat ini bahkan tidak pernah menyentuh server Anda — mereka diblokir lebih awal; penghitung “IPset ipsum” menunjukkan berapa banyak yang diblokir secara preventif.

Bedanya sederhana: reaktif — “mereka menyerang lalu diban”, preventif — “mereka diblokir bahkan sebelum mencoba”. Dulu recidive diisi secara artifisial dengan list-3 ipsum (dari sinilah muncul pembagian lama “recidive daftar”); kini recidive hanya berisi residivis asli, sedangkan preventif sepenuhnya di firewall.

12. Daftar blokir IPset (ipsum)

ipsum — daftar publik IP berbahaya yang diperbarui setiap hari. Monitor menampilkan jumlah alamat yang dimuat di dasbor dan peta serangan serta memperhitungkannya dalam Skor Keamanan (−10 jika kumpulan tidak dimuat).

Varian minimal tanpa fail2ban — kumpulan ipsum tersendiri dengan pemblokiran lewat iptables:

# Buat kumpulan (sekali saja): sudo ipset create ipsum hash:ip # Skrip pembaruan /usr/local/bin/update-ipsum.sh: #!/bin/bash ipset flush ipsum for ip in $(curl -s https://raw.githubusercontent.com/stamparm/ipsum/master/levels/3.txt); do ipset add ipsum "$ip" 2>/dev/null done iptables -C INPUT -m set --match-set ipsum src -j DROP 2>/dev/null \ || iptables -I INPUT -m set --match-set ipsum src -j DROP # Cron (sudo crontab -e, setiap hari pukul 4:00): 0 4 * * * /usr/local/bin/update-ipsum.sh
Varian lanjutan dengan fail2ban-recidive — di bagian “Konfigurasi kerja Fail2ban + ipsum”.
ipset tersimpan di memori dan hilang saat reboot. Cron harian saja akan membuat kumpulan kosong sejak reboot hingga eksekusi berikutnya (dasbor menampilkan 0). Muat kumpulan juga saat start — pindahkan pemuatan ke skrip dan pasang pada @reboot. Sekalian perintah create … -exist menetapkan batas maxelem 300000 (secara default 65536 — level 1 tidak muat, akan muncul “Hash is full”):
# /usr/local/bin/load-ipsum.sh #!/bin/bash curl -s https://raw.githubusercontent.com/stamparm/ipsum/master/levels/1.txt \ | grep -v '^#' | sed 's/^/add ipsum /' \ | (echo "create ipsum hash:ip hashsize 131072 maxelem 300000 -exist"; echo "flush ipsum"; cat) \ | ipset restore -exist # sudo crontab -e — setiap hari pukul 04:00 DAN setiap start: 0 4 * * * /usr/local/bin/load-ipsum.sh @reboot sleep 60 && /usr/local/bin/load-ipsum.sh
Cara kerja saat instalasi otomatis. Skrip memuat seluruh daftar level 1 (100+ ribu IP) ke kumpulan ipsum dan, jika firewall dikelola oleh penginstal (VPS baru — profil “Penuh”/“Ringan”), menautkan kumpulan ke UFW dengan aturan DROP — trafik dari IP ini benar-benar diblokir. Aturan ditempatkan setelah ESTABLISHED,RELATED, sehingga koneksi yang sedang berjalan (termasuk SSH Anda) tidak terputus — hanya koneksi baru dari daftar yang dipotong. Kumpulan dipulihkan saat pemuatan layanan ipsum-load.service sebelum firewall (jika tidak, UFW tidak akan aktif), dan diperbarui oleh cron pada pukul 04:00. Pada server yang sudah dikonfigurasi (panel, firewall sendiri), penginstal tidak menyentuh firewall — di sana ipsum tetap menjadi daftar untuk dasbor dan peta serangan, sedangkan aturan DROP dapat ditambahkan manual bila diinginkan (varian minimal dengan iptables … --match-set ipsum … -j DROP — di atas). Saat instalasi otomatis, Anda tidak perlu melakukan apa pun secara manual.

13. Instalasi CrowdSec

Pengganti modern untuk Fail2ban dengan threat intelligence kolektif: pemblokiran dari komunitas plus aturan buatan sendiri. Membutuhkan bouncer terpisah untuk menerapkan pemblokiran ke firewall.

curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash sudo apt install crowdsec sudo systemctl enable --now crowdsec # Bouncer untuk iptables/nftables: sudo apt install crowdsec-firewall-bouncer-iptables # Periksa status: sudo systemctl status crowdsec sudo cscli decisions list sudo cscli bouncers list
Status “Tidak berjalan” di panel = layanan terpasang, tetapi service tidak aktif (monitor memeriksanya melalui systemctl is-active crowdsec). Aktifkan: sudo systemctl enable --now crowdsec; jika gagal, lihat sudo journalctl -u crowdsec -n 30. Aturan yang sama berlaku untuk layanan apa pun berstatus “Tidak berjalan” (Suricata, Falco, Monit, MySQL).
“0 skenario” atau “0 bouncers” di dasbor. CrowdSec bawaan hampir kosong — tanpa koleksi ia tidak mendeteksi apa pun, dan tanpa bouncer yang terdaftar pemblokiran tidak diterapkan ke firewall. Pasang koleksi dasar dan pastikan bouncer ada di daftar:
# Koleksi dasar (Linux + SSH + server web): sudo cscli collections install crowdsecurity/linux crowdsecurity/sshd crowdsecurity/base-http-scenarios sudo systemctl reload crowdsec # Bouncer harus ada di daftar dan berstatus koneksi aktif: sudo cscli bouncers list
Di log bouncer muncul stream halted / pemblokiran tidak diterapkan. Ini kunci api yang terlantar: bouncer telah dihapus dari cscli bouncers list, tetapi kunci lamanya masih ada di /etc/crowdsec/bouncers/*.yaml. Daftarkan ulang bouncer dan tuliskan kunci baru:
sudo cscli bouncers add fw-bouncer # menampilkan api_key baru # tuliskan kunci ini ke api_key: di /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml sudo systemctl restart crowdsec-firewall-bouncer
Instalasi otomatis (profil “Perlindungan penuh”) secara otomatis memasang koleksi dan mendaftarkan firewall-bouncer — secara manual ini hanya diperlukan saat instalasi manual atau setelah intervensi manual pada CrowdSec.

14. Instalasi AIDE

AIDE (Advanced Intrusion Detection Environment) membuat snapshot sistem berkas dan pada setiap pemeriksaan melaporkan perubahan di /etc, /bin, /usr. Setelah instalasi, inisialisasi basis data wajib dilakukan (aideinit).

sudo apt install aide # Inisialisasi basis data (5–15 menit): sudo aideinit sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db # Ubuntu 24.04: direktori /var/lib/aide dibuat dengan mode 700 (pemilik _aide), # dan dasbor (www-data) tidak melihat basis data → menampilkan “Belum diinisialisasi”. # Buka direktori agar dapat dilewati (berkas basis data tetap 600): sudo chmod 755 /var/lib/aide # Pemeriksaan pertama DENGAN MENULIS ke log yang dibaca monitor. # Di Ubuntu/Debian aide membutuhkan --config eksplisit (jika tidak “missing configuration”; # biner aide.wrapper tidak disertakan pada versi baru): sudo bash -c 'aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1'
Selama aideinit terminal berhenti selama 5–15 menit pada baris Running aide --init... — ini normal (hashing seluruh sistem berkas, beban pada disk). Jangan hentikan dengan Ctrl+C. Jika proses “menggantung” tetapi tidak menulis apa pun — mungkin ia menunggu jawaban atas permintaan tersembunyi Overwrite existing aide.db.new [Yn]? (tekan Y). Periksa aktivitas dari sesi lain: pgrep -af aide.
Kesalahan aideinit: “21_aide_spamassassin … printf: invalid number” (return code 20) — bug yang dikenal pada snippet konfigurasi AIDE di Ubuntu 22.04. Basis data tidak dibuat. Keluarkan snippet yang rusak lalu ulangi:
sudo mv /etc/aide/aide.conf.d/21_aide_spamassassin /etc/aide/21_aide_spamassassin.disabled sudo aideinit sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db
Status pada dasbor. “Belum diinisialisasi” = panel tidak melihat berkas basis data: entah aideinit belum dijalankan, atau (Ubuntu 24.04) direktori /var/lib/aide dibuat dengan mode 700 dan tidak dapat diakses www-data — diperbaiki dengan sudo chmod 755 /var/lib/aide (lihat blok di atas). “Belum ada pemeriksaan” = basis data ada, tetapi pemeriksaan belum pernah dijalankan — ini bukan kesalahan. Hasilnya dibaca monitor dari /var/log/aide/aide.log.
Pemeriksaan rutin → log untuk panel. /etc/cron.daily/aide bawaan pada Ubuntu/Debian baru mungkin tidak menulis /var/log/aide/aide.log dalam bentuk yang diperlukan (dan aide.wrapper sudah tidak ada di dalamnya). Lebih andal menambahkan cron sendiri dengan --config eksplisit — ia menulis log sebagai root dengan mode 644, dan monitor membacanya tanpa grup tambahan:
# sudo crontab -e — pemeriksaan harian pukul 02:00: 0 2 * * * /usr/bin/aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1 # Jalankan sekarang, tanpa menunggu jadwal: sudo bash -c 'aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1'
Instalasi otomatis sudah melakukan semua ini: chmod 755 /var/lib/aide dan cron pemeriksaan pukul 02:00 — tidak perlu apa pun secara manual.
Lakukan inisialisasi pertama pada server yang bersih — sebelum memasang aplikasi web. Setelah perubahan yang sah, buat ulang basis data: sudo aideinit && sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db.

15. Instalasi ClamAV

Pemindai antivirus untuk Linux. Sangat berguna untuk memeriksa /var/www dari PHP-shell dan kode berbahaya.

sudo apt install clamav clamav-daemon sudo systemctl enable --now clamav-daemon # Perbarui basis data signature: sudo freshclam # Pindai folder secara manual: sudo clamscan -r /var/www --infected
Daemon clamd menampilkan “Tidak aktif” setelah enable --now? Tiga penyebab umum:

1. Baris Example masih ada di konfigurasi — clamd menolak start selama baris itu ada:

sudo sed -i '/^Example/d' /etc/clamav/clamd.conf sudo systemctl restart clamav-daemon

2. Basis data signature belum diunduh — clamd tidak start tanpanya:

sudo systemctl stop clamav-freshclam sudo freshclam sudo systemctl start clamav-freshclam sudo systemctl restart clamav-daemon

3. Sedang memuat saja — clamd memuat ~8 juta signature ke memori selama 30–60 detik. Tunggu dan periksa: systemctl is-active clamav-daemon (status activating → masih memuat).

Diagnostik: sudo journalctl -u clamav-daemon -n 30 --no-pager.
Di dashboard “File diperiksa: 0” / “Pemindaian terakhir: —”? Daemon clamd hanya menyimpan signature di memori, ia sendiri tidak memindai apa pun secara terjadwal. Dashboard menampilkan hasil pemindaian terjadwal, jadi diperlukan cron yang memindai dan menulis log. Instalasi otomatis memasang wrapper /usr/local/bin/clamav-scan.sh dan cron pada 01:30 — setelah menjalankan pertama kali, “File diperiksa” dan “Pemindaian terakhir” akan terisi. Jalankan langsung tanpa menunggu jadwal: sudo /usr/local/bin/clamav-scan.sh.

16. Instalasi Linux Malware Detect (maldet)

Linux Malware Detect (LMD) — pemindai malware untuk ancaman web: PHP-shell, backdoor web, downloader. Menggunakan mesin ClamAV dan melengkapinya dengan signature miliknya sendiri.

wget https://www.rfxn.com/downloads/maldetect-current.tar.gz tar -xzf maldetect-current.tar.gz dir=$(ls -d maldetect-*/ | head -1) && cd "$dir" && sudo bash install.sh && cd ~ rm -rf maldetect-* maldetect-current.tar.gz # Perbarui signature: sudo maldet -u # Pindai /var/www: sudo maldet -a /var/www
LMD dan ClamAV bekerja baik berpasangan. Laporan terakhir: maldet --report.
Saat instalasi mungkin muncul baris update-rc.d: error: unable to read /etc/init.d/maldet — baris ini tidak berbahaya. maldet tidak menggunakan init.d, pembaruan signature dan pemindaian dijalankan melalui /etc/cron.daily/maldet. Jika di bawah terlihat installation completed — semuanya sudah terpasang.
Di halaman LMD tertulis “Tidak terpasang”, padahal sudah terpasang? maldet dipasang bukan melalui apt, melainkan di /usr/local/maldetect, dan saat open_basedir aktif keberadaannya diperiksa melalui shell — lihat bagian “Halaman kosong padahal data ada di server”.

17. Instalasi Suricata

Sistem deteksi intrusi jaringan: menganalisis lalu lintas pada tingkat paket dan mengenali ribuan signature serangan. Melengkapi ModSecurity (yang bekerja pada tingkat HTTP, sedangkan Suricata pada tingkat TCP/IP).

sudo add-apt-repository ppa:oisf/suricata-stable sudo apt update && sudo apt install suricata # Unduh aturan terbaru: sudo suricata-update sudo systemctl enable --now suricata
Suricata “Aktif”, tetapi dashboard tidak menampilkan alert / jumlah kejadian 0? Suricata menulis /var/log/suricata/eve.json sebagai root dengan mode 750 pada direktori, dan server web (www-data) tidak dapat membacanya. Buka akses lintas direktori — file di dalamnya tetap terlindungi:
sudo chmod o+rx /var/log/suricata
Instalasi otomatis melakukan ini sendiri — tidak perlu manual.

18. Instalasi Falco

Menangkap system call melalui eBPF/kernel module dan mendeteksi anomali secara real-time: shell dari nginx, pembacaan /etc/passwd oleh proses web, penulisan ke /bin, dsb.

curl -fsSL https://falco.org/repo/falcosecurity-packages.asc > /tmp/falco.asc gpg --dearmor < /tmp/falco.asc | sudo tee /usr/share/keyrings/falco-archive-keyring.gpg > /dev/null sudo chmod 644 /usr/share/keyrings/falco-archive-keyring.gpg && rm /tmp/falco.asc echo "deb [signed-by=/usr/share/keyrings/falco-archive-keyring.gpg] https://download.falco.org/packages/deb stable main" \ | sudo tee /etc/apt/sources.list.d/falcosecurity.list sudo apt update && sudo apt install falco sudo systemctl enable --now falco
Monitor membaca peristiwa Falco melalui journalctl -u falco (tanpa sudo — lewat grup systemd-journal). Pastikan www-data ada di grup ini — lihat “Konfigurasi sudo” (poin 2) pada halaman instalasi manual.
“0 peristiwa dalam 24 jam” adalah hal normal, bukan kesalahan. Falco bersifat event-driven: ia diam selama semuanya baik-baik saja, dan hanya mencatat peristiwa saat terjadi anomali (shell dari proses web, pembacaan /etc/passwd, penulisan ke direktori sistem). Nol peristiwa kritis dalam sehari pada server yang tenang adalah kondisi yang sehat.
Untuk panel, output ke file lebih andal. Pembacaan melalui journalctl memerlukan izin atas jurnal; agar panel melihat peristiwa secara stabil, instalasi otomatis mengaktifkan file_output pada Falco → /var/log/falco/falco.log dan mengatur UMask=0022 pada layanan (log dapat dibaca web server). Pada instalasi baru, ini tidak perlu dikonfigurasi secara manual.

19. Instalasi ModSecurity (WAF)

ModSecurity — firewall web (WAF) untuk Apache atau Nginx. Memblokir serangan di lapisan aplikasi: injeksi SQL, XSS, path traversal, pemindai.

# Apache: sudo apt install libapache2-mod-security2 sudo a2enmod security2 # Set aturan OWASP Core Rule Set: sudo apt install modsecurity-crs # WAJIB: tanpa file ini mesin aturan dalam keadaan mati sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf sudo sed -i 's/^SecRuleEngine DetectionOnly/SecRuleEngine On/' /etc/modsecurity/modsecurity.conf sudo apache2ctl configtest && sudo systemctl reload apache2 # Pemeriksaan: harus mengembalikan 403 curl -s -o /dev/null -w '%{http_code}\n' "https://monitor.example.com/?id=1%20UNION%20SELECT%201,2--"
Instalasi paket saja tidak melindungi apa pun. Apache memuat konfigurasi dengan baris IncludeOptional /etc/modsecurity/*.conf, sedangkan paket hanya meletakkan modsecurity.conf-recommended — file ini tidak cocok dengan pola *.conf. Jika tidak disalin ke modsecurity.conf, SecRuleEngine tetap Off: modul termuat, aturan CRS termuat, tetapi trafik tidak diperiksa dan log audit tidak dibuat. Mode antara DetectionOnly hanya menulis peristiwa ke log tanpa memblokir permintaan — dashboard menampilkannya dengan warna kuning.

Akses dashboard ke log audit. Log /var/log/apache2/modsec_audit.log dimiliki oleh root (hak 640), pengguna web tidak bisa membacanya. Dashboard mengambil data melalui pembungkus — buatlah:

sudo tee /usr/local/bin/monitor-modsec >/dev/null <<'EOF' #!/bin/sh echo "ENGINE=$(grep -hE '^SecRuleEngine[[:space:]]+' /etc/modsecurity/*.conf 2>/dev/null | tail -1 | awk '{print $2}')" echo "---LOG---" tail -n 3000 /var/log/apache2/modsec_audit.log 2>/dev/null echo "---RULES---" for f in /etc/modsecurity/crs/rules/*.conf /usr/share/modsecurity-crs/rules/*.conf /etc/modsecurity/custom-rules.conf; do [ -f "$f" ] && { echo "===FILE:$(basename "$f")==="; cat "$f"; } done EOF sudo chown root:root /usr/local/bin/monitor-modsec sudo chmod 755 /usr/local/bin/monitor-modsec # di /etc/sudoers.d/monitor (pengguna = yang menjalankan PHP-FPM): # www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-modsec
Pembungkus mengambil direktif SecRuleEngine terakhir tanpa indentasi: baris berindentasi berada di dalam blok <LocationMatch>/<Directory> (misalnya mematikan WAF untuk phpMyAdmin) dan tidak menentukan mode global.
Pengguna di sudoers harus sama dengan pengguna pool FPM: pada Apache/Debian biasa itu adalah www-data, di HestiaCP pool situs berjalan sebagai pemilik situs (misalnya admin) — periksa dengan grep -E '^user' /etc/php/*/fpm/pool.d/monitor.example.com.conf.
Jika situs berada di belakang proxy Nginx (HestiaCP), Apache melihat proxy itu sendiri sebagai klien — dashboard mengambil IP asli penyerang dari header X-Forwarded-For. Yang masuk ke statistik hanya transaksi dengan aturan yang terpicu: direktif SecAuditLogRelevantStatus menulis semua respons 4xx/5xx ke log audit, sehingga 403/500 biasa pun ikut masuk — dashboard tidak menghitungnya sebagai peristiwa WAF.
Blok ---RULES--- dibutuhkan oleh bagian “Semua aturan aktif” — dashboard menampilkan bukan hanya aturan yang terpicu, melainkan seluruh aturan CRS + kustom yang termuat. Tiga path dalam loop for f in … adalah lokasi khas untuk aturan CRS dan tambahan lokal; jika tata letak Anda berbeda (paket meletakkan file di direktorinya sendiri, atau aturan kustom tidak berada di /etc/modsecurity/custom-rules.conf), temukan path sebenarnya dengan perintah sudo grep -rl 'IncludeOptional\|^Include ' /etc/apache2/mods-enabled/security2.conf /etc/apache2/conf-enabled/*.conf 2>/dev/null dan masukkan ke daftar. Jika pembungkus versi lama (tanpa bagian ini) — bagian tersebut hanya akan menampilkan peringatan “tidak tersedia”, sisa halaman berfungsi seperti sebelumnya.

20. Instalasi Auditd

Auditd (Linux Audit Daemon) mencatat panggilan sistem pada level kernel: login dan logout, perintah sudo, upaya autentikasi yang gagal, perubahan berkas. Monitor menampilkan login, upaya yang gagal, dan perintah sudo hari ini.

sudo apt install auditd audispd-plugins sudo systemctl enable --now auditd # Periksa status dan peristiwa: sudo systemctl status auditd sudo ausearch -m USER_LOGIN -ts today
Monitor membaca peristiwa melalui ausearch (/usr/sbin/ausearch) dan bila perlu dari /var/log/audit/audit.log dengan perintah tail. Keduanya harus ada di sudoers.

21. Instalasi Monit

Memantau layanan (nginx, php-fpm, mysql, dll.) dan memulai ulang saat gagal. Bisa mengirim peringatan ke email.

sudo apt install monit sudo systemctl enable --now monit # Konfigurasi: sudo nano /etc/monit/monitrc ls /etc/monit/conf.d/
Monitor mengambil daftar layanan melalui monit status. Di /etc/monit/monitrc antarmuka HTTP harus diaktifkan (blok set httpd dengan allow localhost), jika tidak monit status akan mengembalikan error.
Di dasbor tertera “0 layanan dipantau”? Ada dua penyebab. (1) Antarmuka HTTP dimatikan — di monitrc baris set httpd dikomentari (secara default tertulis sebagai # set httpd port 2812 …). Hapus komentar pada blok itu dan izinkan localhost. (2) httpd yang aktif saja tidak memantau apa pun — Monit hanya menghitung yang dijelaskan pada stanza check; tanpa itu daftarnya kosong meski antarmuka berjalan. Konfigurasi minimal yang berfungsi:
# /etc/monit/conf.d/00-httpd — antarmuka HTTP untuk localhost: set httpd port 2812 use address localhost allow localhost # contoh stanza check (yang dipantau): check process sshd with pidfile /run/sshd.pid start program = "/usr/bin/systemctl start ssh" stop program = "/usr/bin/systemctl stop ssh" check filesystem rootfs with path / if space usage > 90% then alert
sudo monit -t # periksa sintaks (Control file syntax OK) sudo systemctl reload monit sudo monit status
Instalasi otomatis meletakkan conf.d siap pakai dengan httpd di 2812 beserta seperangkat pemeriksaan — pada instalasi baru tidak perlu diatur manual.
Layanan berstatus “Bermasalah”? Monitor hanya menampilkan status dan sengaja tidak memulai ulang layanan dari panel web (itu akan menjadi eksekusi perintah root jarak jauh di panel keamanan). Diagnostik dan mulai ulang — lewat SSH via Monit:
sudo monit status <service> # penyebab error sudo monit restart <service> # mulai ulang via Monit # jika Monit tidak berhasil menghidupkan layanan — lihat unit-nya sendiri: sudo systemctl status <unit> --no-pager sudo journalctl -u <unit> -n 50 --no-pager

22. Instalasi PSAD (deteksi pemindaian port)

PSAD menganalisis log iptables dan mendeteksi pemindaian port serta serangan jaringan, memberikan tingkat ancaman (1–5) ke setiap sumber. Melengkapi fail2ban dan Suricata.

sudo apt install psad # PSAD membaca log iptables — logging harus diaktifkan (UFW melakukannya sendiri). # Untuk iptables murni, tambahkan aturan LOG ke rantai INPUT/FORWARD. sudo psad --sig-update sudo systemctl enable --now psad
Monitor membaca data melalui psad --Status (perlu ada di sudoers). Tanpa logging iptables, halaman akan kosong — ini normal selama belum ada pemindaian.

23. AppArmor / SELinux (kontrol akses)

Mandatory Access Control membatasi file dan sumber daya apa saja yang bisa diakses sebuah program, bahkan jika program itu telah diretas. Di Ubuntu/Debian, AppArmor dipakai secara default (biasanya sudah terpasang dan aktif).

# AppArmor (Ubuntu/Debian): sudo apt install apparmor apparmor-utils sudo systemctl enable --now apparmor sudo aa-status # periksa profil
Monitor membaca status melalui aa-status (perlu ada di sudoers). Menampilkan jumlah profil dalam mode enforce/complain dan proses tanpa profil.

“Profil dimuat” lebih banyak daripada enforce + complain — itu normal. Pada AppArmor 4.x (Ubuntu 24.04 dan lebih baru) muncul mode unconfined: profil dimuat ke kernel, tetapi tidak membatasi apa pun. Ubuntu menandai puluhan profil seperti ini untuk program yang memakai user namespaces (peramban, klien torrent, dan sejenisnya). Ketika profil semacam itu ada, kartu “Profil dimuat” menjadi kuning dan menampilkan jumlahnya — misalnya unconfined: 90 dari 120 yang dimuat dan 26 dalam enforce. Yang benar-benar melindungi hanya profil dalam enforce; di Ubuntu 22.04 (AppArmor 3.x) mode ini tidak ada sehingga angkanya selalu cocok.

sudo aa-status | grep -E "profiles are" # rincian per mode sudo aa-enforce /etc/apparmor.d/profile-name # ubah profil ke enforce
Mengubah ke enforce profil yang sengaja dibiarkan Ubuntu dalam unconfined hanya layak dilakukan secara sadar: profil itu dimatikan bukan karena kesalahan, melainkan karena kalau tidak, program itu sendiri jadi rusak. Profil dalam complain berbeda halnya: di situ aturannya sudah ditulis dan hanya belum diterapkan.

24. Instalasi debsums (integritas paket)

debsums memverifikasi bahwa file paket yang terpasang cocok dengan checksum dari repositori — mendeteksi biner sistem yang dipalsukan (melengkapi AIDE). Pemindaian penuh memakan 1–2 menit, sehingga dijalankan lewat cron, dan dashboard membaca hasilnya dari data/debsums/debsums.log lalu mengelompokkannya sendiri per kategori (hanya biner dan pustaka yang penting).

Tugas ditempatkan di cron root (sudo crontab -e). Pembungkus siap pakai debsums-scan.sh diletakkan di /usr/local/bin/ (chmod +x; lihat ringkasan tugas cron) dan menulis laporannya sendiri ke data/debsums/ dashboard.

sudo apt install debsums # Baris cron (setiap hari 4:30): 30 4 * * * /usr/local/bin/debsums-scan.sh >> /path/to/monitor/logs/cron.log 2>&1

Pembungkus debsums-scan.sh menemukan sendiri data/ dashboard — path tidak perlu dituliskan.

Perubahan di /etc/ (konfigurasi) dan /usr/share/ (sumber daya) pada server biasanya wajar — dashboard menandainya dengan warna tersendiri. Yang mengkhawatirkan adalah perubahan pada biner dan pustaka (/bin, /sbin, /usr/lib dsb.) — kartu “Biner / pustaka” menampilkan tepat perubahan tersebut.

25. Konfigurasi laporan Lynis

Lynis dijalankan manual atau lewat cron. Laporan harus disimpan ke folder data/lynis/ proyek — monitor membaca file lynis-report.dat.

# Jalankan sekali (isi dengan path root panel Anda): sudo lynis audit system --report-file /path/to/monitor/data/lynis/lynis-report.dat # Audit harian — baris cron (wrapper lynis-scan.sh siap pakai di /usr/local/bin/, lihat ringkasan): 0 3 * * * /usr/local/bin/lynis-scan.sh >> /path/to/monitor/logs/cron.log 2>&1
Setelah dijalankan pertama kali, halaman “Audit Lynis” langsung menampilkan hardening index, peringatan, dan rekomendasi.
Tombol “Jalankan audit” di halaman Lynis. Tombol ini menjalankan lynis-scan.sh di latar belakang langsung dari panel (tanpa menunggu cron): menampilkan “Memindai…” dan setelah selesai laporan diperbarui otomatis. Untuk itu, pengguna web memerlukan baris sudoers agar bisa menjalankan skrip — installer menambahkannya otomatis ke /etc/sudoers.d/monitor. Jika panel dipasang manual/sebelumnya, tambahkan baris tersebut dengan pengguna yang sama yang sudah tercantum di file:
u=$(sudo awk '/NOPASSWD/ && !/lynis-scan/ {print $1; exit}' /etc/sudoers.d/monitor) [ -n "$u" ] && echo "$u ALL=(ALL) NOPASSWD: /usr/local/bin/lynis-scan.sh" | sudo tee -a /etc/sudoers.d/monitor sudo visudo -c && sudo chmod 440 /etc/sudoers.d/monitor

26. Konfigurasi laporan Logwatch

Logwatch harus menyimpan laporan harian ke folder data/logwatch/ proyek dalam format .txt. Monitor menampilkan laporan terbaru dan arsipnya.

# Harian (6:00) — baris cron (wrapper siap pakai logwatch_daily.sh di /usr/local/bin/, lihat ringkasan): 0 6 * * * /usr/local/bin/logwatch_daily.sh >> /path/to/monitor/logs/cron.log 2>&1

Modul dashboard

27. Monitor jaringan (bawaan)

Monitor jaringan tidak perlu diinstal — ini halaman dashboard bawaan. Halaman ini menampilkan status jaringan server dari sumber lokal:

  • antarmuka dan trafik — dari /proc/net/dev;
  • status link (UP/DOWN) dan IP — via ip;
  • koneksi dan port yang mendengarkan — via ss;
  • peristiwa jaringan kernel selama 24 jam — via journalctl -k.

Tiga sumber pertama bekerja tanpa sudo, jadi antarmuka, trafik, koneksi, dan port langsung terlihat. Blok “Peristiwa kernel” memakai journalctl -k — dibaca melalui grup systemd-journal (“Konfigurasi sudo”, poin 2), tidak perlu sudo. Untuk memastikan semuanya bisa diakses pengguna web:

# Pemeriksaan sebagai www-data (PHP berjalan di bawahnya): sudo -u www-data bash -c 'cat /proc/net/dev' sudo -u www-data bash -c 'ip -o link show' sudo -u www-data bash -c 'ss -s' sudo -u www-data journalctl -k --no-pager -n 5
Blok “Peristiwa jaringan kernel” menampilkan peristiwa stack jaringan kernel (perubahan link up/down, error carrier, “network unreachable”). Entri firewall UFW BLOCK tidak masuk ke sini — ada di halaman “Firewall UFW” dan “Peta serangan”. Blok kosong dengan centang hijau = tidak ada gangguan jaringan selama sehari.

28. Disk dan SMART

Halaman bawaan menampilkan tiga hal:

  • Sistem berkas — pemakaian partisi (df); skala memerah saat ≥90%;
  • Penyimpanan — daftar disk (lsblk), hanya yang nyata (loop/snap disembunyikan);
  • Kesehatan (SMART) — status disk dan atribut (smartctl).

Ruang dan daftar perangkat langsung berfungsi tanpa pengaturan. Untuk SMART diperlukan paket smartmontools. Proses web tidak memiliki akses langsung ke perangkat disk, sehingga SMART diambil lewat cron ke berkas data/disk/smart.txt, lalu dibaca oleh dashboard.

Tugasnya ada di cron root (sudo crontab -e). Pembungkus siap pakai smart-scan.sh ditaruh di /usr/local/bin/ (chmod +x; lihat ringkasan tugas cron) dan langsung menulis ke data/disk/ dashboard.

sudo apt install smartmontools # Baris cron (setiap 30 menit): */30 * * * * /usr/local/bin/smart-scan.sh >> /path/to/monitor/logs/cron.log 2>&1

Pembungkus smart-scan.sh menemukan sendiri data/ dashboard — jalurnya tidak perlu ditulis. Di dalamnya lsblk -e7,11 mengecualikan loop/cdrom.

Pada disk virtual (QEMU/KVM dan sejenisnya) biasanya hanya tersedia status umum “kesehatan: OK”, sedangkan suhu, jam operasi, dan sektor yang dialihkan bisa kosong — ini normal. Pada server fisik semua atribut ditampilkan.

29. Performa (CPU/RAM/Jaringan/Disk)

Halaman ini menampilkan riwayat beban server selama 24 jam terakhir — Load Average, pemakaian CPU dan waktu tunggu I/O, RAM/Swap, trafik jaringan (terima/kirim), I/O disk (baca/tulis), pengisian disk dan inode, deskriptor file yang terbuka serta koneksi MySQL, ditambah jumlah koneksi TCP dan proses saat ini.

Data dikumpulkan oleh cron/collect_metrics.php — setiap 5 menit menulis satu snapshot “mentah” dari penghitung (/proc/loadavg, /proc/meminfo, /proc/stat, /proc/net/dev, /proc/diskstats, df/df -i, /proc/sys/fs/file-nr, SHOW GLOBAL STATUS LIKE 'Threads_connected') ke tabel basis data system_metrics; persentase dan kecepatan dihitung sendiri oleh halaman berdasarkan selisih antara snapshot berdekatan (pengisian disk/inode/deskriptor/koneksi MySQL — nilai sesaat, tanpa perhitungan ulang). Sudo tidak diperlukan — sumber dibaca tanpa hak root. Titik data yang lebih lama dari 24 jam dihapus otomatis pada setiap penulisan.

# Baris cron (setiap 5 menit): */5 * * * * /usr/local/bin/collect-metrics-all.sh >> /path/to/monitor/logs/cron.log 2>&1

Pembungkus collect-metrics-all.sh (lihat ringkasan tugas cron) secara otomatis menemukan semua instans panel yang terpasang di server dan menjalankan cron/collect_metrics.php masing-masing atas nama pemilik situs.

Selama kolektor belum berjalan setidaknya dua kali (sekitar 10 menit pertama setelah pemasangan), halaman menampilkan “data sedang dikumpulkan” — grafik membutuhkan minimal satu pasang titik berdekatan untuk menghitung kecepatan dan persentase.

Peringatan beban (bagian “Pengaturan” → “Peringatan beban”) — saat ambang batas CPU/RAM/disk/inode terlampaui, panel mengirim notifikasi ke Telegram/Email (kanal yang sama seperti laporan harian — tidak perlu mengaktifkannya terpisah untuk peringatan), dan satu lagi — ketika metrik kembali normal. Selama ambang batas tetap terlampaui tidak dikirim ulang: notifikasi berikutnya baru datang setelah siklus “kembali normal → terlampaui lagi”.

Ambang batas diperiksa oleh collect_metrics.php yang sama pada setiap kali dijalankan (setiap 5 menit) — tidak perlu cron terpisah. Status “sudah diberi tahu / belum” disimpan di data/alerts_state.json, ambang batas — di pengaturan panel.

30. Peta serangan (GeoIP)

Halaman “Peta serangan” menentukan negara berdasarkan IP dengan perintah geoiplookup. Tanpa paket GeoIP, negara tidak terdeteksi dan titik pada peta tidak muncul:

sudo apt install geoip-bin geoip-database # Pemeriksaan: geoiplookup 8.8.8.8
Sudo tidak diperlukan — basis data /usr/share/GeoIP/GeoIP.dat dapat dibaca semua, hasilnya di-cache di tmp/geoip_cache.json. Petanya sendiri (Leaflet + tile OpenStreetMap) dimuat di browser — perlu internet pada komputer tempat dashboard dibuka.

31. Eksposur eksternal, pembaruan, dan pembaruan otomatis

Dua kartu bawaan pada dasbor yang menampilkan bukan status “aktif/nonaktif” sebuah alat, melainkan tingkat keamanan server yang sebenarnya. Tidak perlu instalasi, dibaca secara lokal tanpa sudo.

Eksposur eksternal — berapa banyak layanan yang mendengarkan semua antarmuka (0.0.0.0/[::]) dan dapat diakses dari luar. Menyorot merah bila DBMS atau cache terbuka ke luar (MySQL, PostgreSQL, Redis, MongoDB, Memcached, Elasticsearch) — ini celah langsung (−10 pada Skor Keamanan). Sumber: ss -tuln.

Jika kartu berwarna merah — tutup DBMS dari dunia luar: ikatkan ke 127.0.0.1 (bind-address pada konfigurasi MySQL/PostgreSQL, bind 127.0.0.1 pada Redis) atau tutup port di UFW.
“Port terbuka” ≠ “dapat diakses dari luar”. Layanan yang mendengarkan 127.0.0.1 (loopback) hanya terlihat oleh server itu sendiri — dari luar tidak dapat dijangkau, meski port “terbuka”. Karena itu Postfix pada port 25 yang terikat ke loopback tetap aman: penyetelan otomatis mengatur inet_interfaces = loopback-only (plus smtpd_banner netral — menutup temuan Lynis MAIL-8818 soal pengungkapan versi). Kartu “Eksposur eksternal” hanya menghitung yang mendengarkan 0.0.0.0/[::] sebagai terbuka ke luar; layanan loopback tidak termasuk.
Lynis MAIL-8818 secara manual (jika Anda memasang mail sendiri): pada /etc/postfix/main.cf atur smtpd_banner = $myhostname ESMTP (tanpa versi dan OS) dan inet_interfaces = loopback-only, lalu sudo systemctl restart postfix.

Pembaruan keamanan — berapa banyak patch keamanan yang menunggu dipasang dan apakah perlu boot ulang setelah pembaruan kernel (−5 pada Skor Keamanan bila ada patch). Sumber: /usr/lib/update-notifier/apt-check, berkas /var/run/reboot-required. Daftar rincinya ada di halaman “Pembaruan keamanan”.

# Pasang pembaruan: sudo apt update && sudo apt upgrade # Periksa apa yang mendengarkan ke luar: ss -tuln | grep -E '0\.0\.0\.0|\[::\]'
Kartu pembaruan bekerja pada Ubuntu/Debian (update-notifier-common). Jika apt-check tidak ada — monitor menghitung patch melalui apt-get -s upgrade.

Pembaruan keamanan otomatis (unattended-upgrades) — pada halaman “Pembaruan keamanan” ada kartu terpisah yang menampilkan apakah pemasangan otomatis patch keamanan aktif dan kapan terakhir dijalankan. Sudo tidak diperlukan — statusnya dibaca melalui apt-config dump.

sudo apt install unattended-upgrades sudo dpkg-reconfigure -plow unattended-upgrades # aktifkan # Periksa apa yang aktif: apt-config dump | grep Unattended-Upgrade

Pemeliharaan

32. Pencadangan

Cadangan adalah asuransi utama: kehilangan data lebih parah daripada peretasan mana pun. Ada dua hal yang diperlukan — cadangan server/situs dan secara terpisah cadangan basis data panel (di sana ada pengguna, kunci WebAuthn, pengaturan, lisensi).

Opsi A — HestiaCP: tab Backup pada pengguna → tombol pembuatan cadangan (atau terjadwal di pengaturan server). Cadangan mencakup situs dan basis datanya.

Opsi B — manual (cron): dump basis data + arsip direktori data/ panel:

# cron root (sudo crontab -e) — cadangan harian pada 2:30 (ganti dengan nama/jalur Anda): 30 2 * * * mysqldump -u root MY_DB | gzip > /var/backups/monitor-db-$(date +\%F).sql.gz 40 2 * * * tar czf /var/backups/monitor-data-$(date +\%F).tar.gz -C /path/to/monitor data # Hapus arsip yang lebih lama dari 14 hari: 0 3 * * * find /var/backups -name 'monitor-*' -mtime +14 -delete
Cadangan di server yang sama menyelamatkan dari kesalahan, tetapi bukan dari kehilangan server. Salin arsip ke penyimpanan eksternal (server lain, S3, rclone ke cloud). Pastikan pemulihan benar-benar berfungsi.

33. Pembaruan dan pemindahan panel

Pembaruan ke versi baru. Buat cadangan terlebih dahulu. Lalu unggah ulang berkas kode, dengan menyimpan data Anda:

  • timpa (kode): public/, includes/, assets/, cron/, database/, serta .htaccess di root (front controller — perutean tidak boleh dibiarkan dari versi lama), manifest.json, sw.js;
  • jangan disentuh: config.php (data DB), data/ (laporan), logs/, tmp/ (sesi dan cache).
# Setelah pengunggahan — reset cache PHP (jika opcache aktif): sudo systemctl reload php*-fpm
FileZilla menampilkan SSH_FX_PERMISSION_DENIEDPermission denied. File panel dimiliki www-data (begitulah pengaturannya saat instalasi), sedangkan klien SFTP terhubung sebagai pengguna Anda sendiri yang tidak punya hak tulis. Memberikan seluruh panel ke www-data “agar berfungsi” justru itulah yang menyebabkan error ini; di bawah ada tiga cara, mana pun menyelesaikan masalahnya.
# Opsi A (disarankan) — pisahkan pemilik: kode milik Anda, folder kerja milik server web. # Server web sama sekali tidak mendapat hak tulis ke KODE panel: sudo chown -R deploy:www-data /path/to/monitor sudo chown -R www-data:www-data /path/to/monitor/data /path/to/monitor/tmp /path/to/monitor/logs sudo find /path/to/monitor -type d -exec chmod 755 {} \; sudo find /path/to/monitor -type f -exec chmod 644 {} \; sudo chmod 750 /path/to/monitor/data /path/to/monitor/tmp /path/to/monitor/logs sudo chmod 640 /path/to/monitor/config.php # Opsi B — ACL di atas pemilik saat ini (tidak memindahkan apa pun): sudo apt install -y acl sudo setfacl -R -m u:deploy:rwX /path/to/monitor sudo setfacl -R -d -m u:deploy:rwX /path/to/monitor # Opsi C — lewat grup www-data. Lebih sederhana, tetapi hak tulis ke file panel # juga didapat server web (dengan celah di PHP kode bisa diganti): sudo usermod -aG www-data deploy sudo find /path/to/monitor -type d -exec chmod 2775 {} \; sudo find /path/to/monitor -type f -exec chmod 664 {} \; sudo chmod 640 /path/to/monitor/config.php sudo chmod 2750 /path/to/monitor/data /path/to/monitor/tmp /path/to/monitor/logs
Mengapa opsi A aman. Panel hanya menulis ke tiga direktori — data/ (laporan), tmp/ (sesi dan cache), logs/; ketiganya tetap dimiliki www-data. Sisanya adalah kode, dan server web hanya perlu membacanya, yang diberikan oleh grup www-data dengan hak 644. Keuntungan sampingan: saat ada celah di PHP, file panel sudah tidak bisa ditimpa. Pada panel hosting (HestiaCP dan sejenisnya) opsi A tidak diperlukan: di sana file situs memang sudah dimiliki akun yang Anda gunakan untuk masuk lewat SFTP, dan server web membacanya lewat grup.
Jebakan opsi B: setiap chmod berikutnya pada file akan mereset masker ACL, dan akses hilang tanpa pemberitahuan. Jika setelah “merapikan hak akses” pengunggahan kembali terhenti oleh Permission denied — ulangi kedua perintah setfacl.
Bit 2 pada opsi C adalah setgid: file yang diunggah lewat SFTP tetap berada di grup www-data, jika tidak panel tak bisa menimpanya. Setelah opsi C, sambungkan ulang di FileZilla — grup baru hanya berlaku pada login baru. Pemeriksaan: id deploy (grup www-data harus muncul) dan ls -ld /path/to/monitor (drwxrwsr-x — huruf s berarti setgid sudah aktif).

Pemindahan ke server lain:

  1. Di server baru, siapkan situs + HTTPS (lihat halaman instalasi manual).
  2. Salin semua berkas panel bersama config.php, data/.
  3. Pindahkan DB: mysqldump di server lama → impor di server baru; sesuaikan data DB di config.php.
  4. Ulangi di server baru: sudoers, keanggotaan grup adm, tugas cron.
  5. Lisensi terikat ke domain — jika domain sama, kunci akan tetap berfungsi.

34. Pemulihan akses (kunci hilang, kata sandi, blokir IP)

Jika Anda tidak bisa masuk — semuanya bisa diperbaiki langsung di basis data dari server. Buka basis data (namanya — dari config.php):

sudo mysql MY_DB

Kunci WebAuthn hilang (faktor kedua gagal) — nonaktifkan 2FA, masuk dengan kata sandi, daftarkan kunci baru:

UPDATE users SET webauthn_enabled = 0;

Lupa kata sandi — tetapkan hash baru (buat di server lalu masukkan):

# Buat hash kata sandi baru: php -r "echo password_hash('NEW_PASSWORD', PASSWORD_BCRYPT), \"\n\";" # Di basis data (masukkan hash yang diperoleh): # UPDATE users SET password = '$2y$10$...' WHERE username = 'admin';

Terkunci sendiri oleh filter IP — nonaktifkan pembatasan:

UPDATE settings SET value = '0' WHERE name = 'ip_restriction_enabled';
Akses ke basis data selalu tersedia: sudo mysql di server, atau phpMyAdmin / bagian basis data di panel hosting. Setelah pemulihan, aktifkan kembali WebAuthn dan filter IP.

35. Semua tugas cron dalam satu tempat

Ringkasan tugas ada di cron root server (ditambahkan lewat sudo crontab -e). Sisakan hanya baris untuk alat yang Anda gunakan; sesuaikan path dengan server Anda.

# Cron server monitor (root) — masukkan lewat: sudo crontab -e # 01:30 — pindai ClamAV pada path berisiko (web, home, temp) → kartu “File diperiksa” dan “Pemindaian terakhir” 30 1 * * * /usr/local/bin/clamav-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 02:00 — cek integritas file AIDE (perlu --config eksplisit) 0 2 * * * /usr/bin/aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1 # saat start — pulihkan hak akses /var/lib/aide (file tmpfiles paket # aide-common.conf mengaturnya ke 0700, dan panel tak lagi melihat basis data) @reboot chmod 755 /var/lib/aide # 03:00 — audit keamanan Lynis 0 3 * * * /usr/local/bin/lynis-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 04:00 — perbarui block-list ipsum (level 1) 0 4 * * * /usr/local/bin/load-ipsum.sh >> /path/to/monitor/logs/cron.log 2>&1 # set ipsum saat start dinaikkan oleh service ipsum-load.service (SEBELUM firewall, jika tidak # UFW tak melihat set di before.rules) — bukan cron. Di sini hanya refresh harian di atas. # 06:00 — laporan Logwatch 0 6 * * * /usr/local/bin/logwatch_daily.sh >> /path/to/monitor/logs/cron.log 2>&1 # setiap 30 mnt — cek disk SMART */30 * * * * /usr/local/bin/smart-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 04:30 — integritas paket debsums 30 4 * * * /usr/local/bin/debsums-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 08:00 — laporan terjadwal ke Email dan Telegram 0 8 * * * /usr/local/bin/daily-report-all.sh >> /path/to/monitor/logs/cron.log 2>&1 # setiap jam — perbarui daftar paket (untuk kartu “Pembaruan keamanan”) 0 * * * * /usr/bin/apt-get update -qq >/dev/null 2>&1 # setiap 5 mnt — snapshot sumber daya (CPU/RAM/jaringan/disk) untuk halaman “Performa” */5 * * * * /usr/local/bin/collect-metrics-all.sh >> /path/to/monitor/logs/cron.log 2>&1
Detail masing-masing ada di bagian terkait. Tugas backup (bagian sebelumnya) ditambahkan ke cron yang sama. Setelah pengeditan, periksa: sudo crontab -l dan pastikan layanan cron aktif.
Waktu cron = zona waktu server, bukan TIMEZONE dari config.php. Konstanta TIMEZONE hanya memengaruhi PHP (cara panel menampilkan tanggal), tetapi daemon cron menjalankan tugas berdasarkan waktu sistem OS. Jika zona server tidak sama dengan zona Anda, laporan “08:00” akan datang pada waktu yang salah. Contoh: server berada di zona lain (Asia/Dhaka, UTC+6), sedangkan Anda di Jakarta (UTC+7) → laporan “08:00” akan datang pukul 09:00 menurut waktu Anda. Periksa dan bila perlu sesuaikan zona sistem dengan zona Anda:
# Periksa zona server saat ini: timedatectl # Atur zona Anda (contoh) dan mulai ulang cron: sudo timedatectl set-timezone Asia/Jakarta sudo systemctl restart cron
Setelah itu baris 0 8 * * * akan berjalan pukul 08:00 waktu setempat. Jika tidak, Anda harus menggeser cron itu sendiri, tetapi saat pergantian ke waktu musim dingin/panas pergeseran akan melenceng lagi — karena itu lebih tepat mengatur zona sistem.
Skrip pembungkus siap pakai. Salinan kerjanya dan contoh crontab (crontab.txt) berada di folder system/ di samping proyek, di luar public_html. Ini bukan bagian dari situs — tidak perlu diunggah ke web-root; tempatkan di server sesuai path sistem (seperti pada crontab di atas):
  • lynis-scan.sh/usr/local/bin/ (chmod +x) — menjalankan lynis audit system, selama pemindaian memasang flag /tmp/lynis-running dan menyalin lynis-report.dat ke data/lynis/ panel;
  • logwatch_daily.sh/usr/local/bin/ (chmod +x) — membuat laporan harian Logwatch (sshd, fail2ban, sudo, postfix) di data/logwatch/;
  • smart-scan.sh/usr/local/bin/ (chmod +x) — mengambil status disk (smartctl) di data/disk/;
  • debsums-scan.sh/usr/local/bin/ (chmod +x) — memeriksa integritas paket (debsums) di data/debsums/;
  • clamav-scan.sh/usr/local/bin/ (chmod +x) — pemindaian antivirus ClamAV pada path berisiko (web, home, temp); menulis ringkasan ke /var/log/clamav/scan.log, tempat halaman ClamAV membacanya (baris 01:30 pada crontab di atas);
  • load-ipsum.sh/usr/local/bin/ (chmod +x) — memperbarui set ipset ipsum (level 1) di tempat, tanpa memutus aturan firewall yang aktif (baris 04:00 pada crontab di atas);
  • daily-report-all.sh/usr/local/bin/ (chmod +x) — menjalankan laporan cron/daily_report.php panel (baris 08:00 pada crontab di atas);
  • daily_report.php — sudah termasuk dalam panel (cron/daily_report.php), dijalankan lewat daily-report-all.sh, tidak perlu dipasang terpisah;
  • collect-metrics-all.sh/usr/local/bin/ (chmod +x) — menjalankan cron/collect_metrics.php panel (halaman “Performa”, baris */5 pada crontab di atas); collect_metrics.php sudah termasuk dalam panel, tidak perlu dipasang terpisah;
  • crontab.txt (system/cron/) — contoh tugas; masukkan baris yang diperlukan lewat sudo crontab -e.
Path skrip di crontab harus sama dengan tempat Anda meletakkannya.
Cara meletakkan skrip di /usr/local/bin/. Langsung dari FileZilla tak bisa menulis ke sana — direktori itu dimiliki root, dan klien SFTP akan mendapatkan SSH_FX_PERMISSION_DENIED. Urutannya begini: pertama unggah file ke /tmp (semua bisa menulis di sana), lalu pindahkan ke tempatnya dengan satu perintah:
# di FileZilla: pada kolom “Situs jarak jauh” masukkan /tmp dan unggah skrip ke sana, # lalu lewat SSH (install langsung mengatur pemilik dan hak akses, chown/chmod tak perlu): sudo install -o root -g root -m 755 /tmp/lynis-scan.sh /usr/local/bin/lynis-scan.sh rm -f /tmp/lynis-scan.sh # pemeriksaan: file di tempatnya, hak akses rwxr-xr-x, sintaks utuh bash -n /usr/local/bin/lynis-scan.sh && ls -l /usr/local/bin/lynis-scan.sh
Jangan tertukar direktori: yang diperlukan adalah /tmp di root server — bukan /var/tmp dan bukan tmp/ di dalam panel itu sendiri (yang terakhir dimiliki www-data dan tertutup dari pengguna Anda). Di pohon FileZilla /tmp adalah cabang tingkat atas, di sebelah var, bukan di dalamnya.
Memasang server dengan konfigurasi otomatis? Pembungkus ini dan tugas cron-nya sudah terpasang oleh skrip (di /usr/local/bin/, log — /var/log/arciveo-cron.log) — tidak perlu melakukan apa pun secara manual.
Tempat skrip mencari panel. Pembungkusnya bersifat domain-netral: menemukan instalasi panel dengan menelusuri /home/*/web/*/public_html dan /var/www/*, lalu meletakkan laporan di data/ masing-masing. Jika panel berada di path lain — tambahkan path itu ke baris for app in … di dalam skrip, jika tidak laporan Lynis/SMART/debsums/Logwatch tak akan sampai ke panel.
cron.log dan hak akses. File logs/cron.log pertama kali dibuat oleh cron root — file itu akan dimiliki root, dan tab “Log cron” di panel tak dapat membacanya maupun mengosongkannya. Buat file itu terlebih dahulu atas nama pengguna web (pemilik direktori situs; pada HestiaCP ini akun, misalnya admin) — dengan begitu cron root hanya menambahkan, tanpa mengubah pemilik:
# buat terlebih dahulu atas nama pengguna web (sebelum menambahkan baris cron): sudo -u OWNER touch /path/to/monitor/logs/cron.log # jika cron.log sudah dibuat oleh cron root — serahkan ke pengguna web: sudo chown OWNER:OWNER /path/to/monitor/logs/cron.log sudo chmod 644 /path/to/monitor/logs/cron.log
Cari tahu pemilik direktori: stat -c %U /path/to/monitor.
Pengelolaan dari panel. Di bagian “Sistem” ada halaman “Crontab” — Anda dapat melihat dan menambahkan tugas tanpa SSH. Panel hanya mengedit tugas yang ditambahkan lewat panel itu sendiri (blok terpisah di root-crontab, ditandai dengan komentar khusus); semua yang sudah ada di crontab (daftar di atas) ditampilkan di sana sebagai daftar read-only “Tugas server lainnya” dengan tombol “Salin ke editor” — tombol itu hanya memindahkan jadwal/perintah ke formulir penambahan, tanpa menyentuh baris aslinya. Untuk “memindahkan” tugas yang ada ke bawah kendali panel — salin ke editor, simpan, lalu hapus baris lama secara manual (sudo crontab -e), jika tidak tugas itu akan berjalan dua kali.
Pengaturan sekali di server. Halaman ini memerlukan skrip pembungkus berhak istimewa — bukan sudo crontab mentah (itu akan menjadi eskalasi langsung ke root bagi siapa pun yang mengakses sesi panel), melainkan skrip terbatas dengan dua perintah (list/set) yang hanya menyentuh bloknya sendiri di antara komentar khusus. Pasang sekali:
sudo install -m 0755 -o root -g root /dev/stdin /usr/local/sbin/arciveo-cron <<'ARCIVEO_CRON_EOF' #!/bin/bash set -euo pipefail BEGIN='# >>> ARCIVEO-CRON-MANAGED (edited from the panel; do not edit by hand) >>>' END='# <<< ARCIVEO-CRON-MANAGED <<<' cmd=${1:-} case "$cmd" in list) [ "$#" -eq 1 ] || { echo "usage: ${0##*/} list" >&2; exit 2; } crontab -l -u root 2>/dev/null || true ;; set) [ "$#" -eq 1 ] || { echo "usage: ${0##*/} set (body on stdin)" >&2; exit 2; } body=$(cat) if grep -qF "$BEGIN" <<<"$body" || grep -qF "$END" <<<"$body"; then echo "invalid body: markers not allowed" >&2; exit 2 fi current=$(crontab -l -u root 2>/dev/null || true) tmp=$(mktemp); trap 'rm -f "$tmp"' EXIT { if grep -qF "$BEGIN" <<<"$current"; then awk -v b="$BEGIN" '{print} $0==b{exit}' <<<"$current" else [ -n "$current" ] && printf '%s\n' "$current" echo "$BEGIN" fi printf '%s\n' "$body" echo "$END" if grep -qF "$END" <<<"$current"; then awk -v e="$END" 'f{print} $0==e{f=1}' <<<"$current" fi } > "$tmp" crontab -u root "$tmp" ;; *) echo "usage: ${0##*/} <list|set>" >&2; exit 2 ;; esac ARCIVEO_CRON_EOF echo "www-data ALL=(ALL) NOPASSWD: /usr/local/sbin/arciveo-cron" | sudo tee -a /etc/sudoers.d/monitor sudo visudo -c
Pengguna web bisa berbeda dari www-data — periksa di bawah pengguna mana pool PHP-FPM situs berjalan (ps -o user= -C php-fpm), dan masukkan pengguna itu ke baris sudoers.
File baru terunggah dengan pemilik yang salah — halaman menjawab “Access denied.”. Jika file public/crontab_monitor.php diunggah lewat FTP/SFTP di bawah pengguna sistem yang berbeda (misalnya root) dari file situs lainnya, web-server tak akan dapat membacanya. Bandingkan pemilik dan hak akses dengan file di sebelahnya lalu samakan:
ls -la public/crontab_monitor.php public/ssl_monitor.php sudo chown OWNER:OWNER public/crontab_monitor.php sudo chmod 644 public/crontab_monitor.php

Diagnostik

36. Alat sudah terpasang, tapi tertulis “Belum terpasang”

Monitor mendeteksi keberadaan alat melalui dpkg-query — basis data paket APT. Jika alat tidak dipasang melalui apt (secara manual, dari snap, atau dari sumber), dpkg tidak dapat melihatnya.

# Periksa melalui dpkg: dpkg -l fail2ban | grep '^ii' dpkg -l auditd | grep '^ii' # Cari jalur ke biner: which ufw fail2ban-client auditctl # Uji sudo dari www-data: sudo -u www-data sudo fail2ban-client status sudo -u www-data sudo ufw status verbose

37. Mengatasi masalah (500, tidak ada data)

Error 500 — periksa log PHP, nginx, dan monitor itu sendiri:

tail -50 /var/log/nginx/error.log tail -50 /var/log/php*-fpm.log # Log monitor: tail -50 logs/monitor_$(date +%Y-%m-%d).log # Hak akses folder: ls -la data/ tmp/ logs/
Dashboard di panel hosting (HestiaCP, ISPmanager, cPanel)? Di sana PHP berjalan bukan sebagai www-data, melainkan sebagai akun pengguna (misalnya admin — pemilik direktori situs). Semua aturan sudo dan keanggotaan grup (adm, systemd-journal) harus didaftarkan ke pengguna itu, jika tidak modul akan menampilkan “Tidak aktif / 0” meski layanan berjalan. Untuk mengetahui pengguna PHP yang sebenarnya: ps -o user= -C php-fpm | sort -u atau pemilik direktori situs stat -c '%U' /path/to/monitor. Selanjutnya, pada semua perintah di bawah gantilah www-data dengannya. Instalasi otomatis mendeteksi pengguna web sendiri dan mendaftarkan sudoers ke pengguna tersebut.

Data tidak muncul — hampir selalu karena hak sudo belum diatur. Periksa perintah tertentu sebagai pengguna web (ganti www-data dengan milik Anda). Flag -n = tanpa kata sandi, seperti PHP — jika diminta kata sandi, berarti aturannya belum ada di sudoers:

sudo -u www-data sudo -n fail2ban-client status sudo -u www-data sudo -n ufw status verbose sudo -u www-data sudo -n ipset list -t ipsum sudo -u www-data sudo -n /usr/sbin/ausearch -m USER_LOGIN -ts today sudo -u www-data sudo -n /usr/sbin/aa-status sudo -u www-data sudo -n /usr/sbin/psad --Status sudo -u www-data journalctl -u falco --no-pager -n 5
Modul menampilkan “Tidak aktif” / “0”, padahal alatnya berjalan (misalnya sudo aa-status di terminal menampilkan profil, tetapi halaman “AppArmor” menampilkan “Tidak aktif”). Penyebabnya: pengguna web tidak punya hak sudo untuk perintah modul tersebut. Periksa perintahnya dari daftar di atas: jika diminta kata sandi — tambahkan baris yang hilang ke /etc/sudoers.d/monitor (“Pengaturan sudo”). Perintah “baru” yang umum: /usr/sbin/aa-status (MAC), /usr/sbin/psad --Status (PSAD).
Jika halaman tertentu (Falco, ModSecurity, Auditd, port UFW yang terbuka) kosong — cocokkan dengan daftar di bagian tentang sudo: kemungkinan apache2ctl, ausearch, aa-status, atau ss belum diizinkan, atau pengguna web tidak ada di grup adm/systemd-journal (dari situ log fail2ban/auth/modsec dan journalctl dibaca — Falco dan event kernel).

38. Halaman kosong padahal data ada di server

Gejala: data ada di server (terlihat lewat shell), tetapi halaman menampilkan “tidak ada data” atau status yang salah — misalnya AIDE menulis “Belum diinisialisasi” padahal basisnya sudah dibuat.

Penyebabnya adalah open_basedir: banyak panel dan hosting membatasi pool PHP-FPM ke direktori domain, sehingga fungsi PHP file_exists(), file_get_contents(), filemtime() pada path sistem (/var/lib/aide, /var/log, /proc…) diblokir. Monitor menyiasatinya dengan membaca path tersebut lewat perintah sistem standar (cat, test, stat).

# Apakah file terlihat lewat shell (begitulah monitor membacanya): sudo -u www-data bash -lc 'test -e /var/lib/aide/aide.db && echo VISIBLE || echo NO' # Nilai open_basedir saat ini untuk pool domain: grep -ri open_basedir /etc/php/*/fpm/pool.d/ 2>/dev/null
Jika shell “melihat” file (VISIBLE) tetapi halaman tidak — ini open_basedir. Solusi yang tepat adalah pembacaan lewat perintah sistem (sudah diterapkan untuk AIDE dan Monitor Jaringan). Memperluas open_basedir ke /var, /proc tidak perlu dan kurang aman.

39. Halaman SSL tidak berfungsi

Monitor memeriksa sertifikat dengan terhubung langsung ke domain melalui port 443. Jika domain tidak dapat diakses dari server itu sendiri atau port ditutup oleh firewall, pemeriksaan akan gagal.

# Periksa sertifikat secara manual: echo | openssl s_client -connect monitor.example.com:443 2>/dev/null \ | openssl x509 -noout -dates # Periksa ketersediaan: curl -I https://monitor.example.com
Domain diambil oleh monitor secara otomatis dari konfigurasi nginx (/etc/nginx/sites-enabled/, /etc/nginx/conf.d/) dan Apache (/etc/apache2/sites-enabled/) ditambah host saat ini dari HTTP_HOST.
Deteksi otomatis subdomain. Subdomain dideteksi secara otomatis dari log publik Certificate Transparency dan diperiksa melalui jaringan — bahkan jika ditempatkan di server lain. Tidak perlu menambahkan apa pun secara manual.

40. Hanya satu dari beberapa basis data yang terlihat

Monitor terhubung ke MySQL sebagai pengguna dari config.php yang hanya punya akses ke basis datanya sendiri. MySQL hanya menampilkan basis data yang punya hak akses di information_schema — karena itu yang lain tidak terlihat.

Agar monitor dapat melihat semua basis data, berikan pengguna ini hak baca saja (sekali sebagai root; ganti dengan nama pengguna dari config.php):

sudo mysql -u root GRANT SELECT, PROCESS, SHOW DATABASES ON *.* TO 'DB_USER'@'localhost'; FLUSH PRIVILEGES; EXIT;
SELECT ON *.* hanya memberi hak baca — tidak bisa mengubah, menghapus, atau membuat apa pun, jadi aman untuk pemantauan.
Tanpa GRANT ini, panel hanya melihat basis datanya sendiri — ini bukan kesalahan, melainkan batasan hak akses. Panel tidak menggunakan sudo mysql sama sekali: daftar basis data diambil melalui koneksi PDO-nya sendiri.

41. PostgreSQL tidak muncul di halaman “Basis data”

PostgreSQL memerlukan akses pada tingkat pengguna postgres, yang tidak dimiliki oleh pengguna web panel. Menjalankan sudo psql yang luas dari PHP tidak aman — sebagai gantinya panel memanggil pembungkus sempit tanpa parameter yang hanya mencetak versi, jumlah koneksi, dan daftar basis data beserta ukurannya. Buat pembungkus tersebut:

sudo tee /usr/local/bin/monitor-pgstat >/dev/null <<'EOF' #!/bin/sh # Arciveo Monitor - read-only PostgreSQL version, connections and per-database size sudo -u postgres psql -tAc "SELECT version();" | grep -oE 'PostgreSQL [0-9.]+' echo "---" sudo -u postgres psql -tAc "SELECT count(*) FROM pg_stat_activity;" echo "---" sudo -u postgres psql -tAc "SELECT datname || '|' || pg_size_pretty(pg_database_size(datname)) FROM pg_database WHERE datistemplate = false;" EOF sudo chown root:root /usr/local/bin/monitor-pgstat sudo chmod 755 /usr/local/bin/monitor-pgstat # di /etc/sudoers.d/monitor (pengguna = yang menjalankan PHP-FPM): # www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-pgstat
Jika tidak menggunakan PostgreSQL — hapus baris monitor-pgstat dari sudoers (langkah 13 pemasangan manual) dan jangan buat skripnya: kartu PostgreSQL hanya akan tetap tidak aktif.

42. Alert terpicu — apa yang harus dilakukan

Dashboard menunjukkan apa yang terjadi; di bawah ini — apa yang harus dilakukan pada situasi umum. Prinsip utama: jangan panik, cocokkan dengan aktivitas sah (tindakan Anda, pembaruan, cadangan), dan tanggapi sesuai tingkat keseriusannya.

  • Peta serangan / banyak ban fail2ban — ini normal untuk server mana pun di internet (bot terus-menerus mencoba SSH/web). Yang penting, ban berfungsi. Pastikan login SSH — hanya lewat kunci (kata sandi dinonaktifkan), dan IP Anda ada di ignoreip.
  • ModSecurity memblokir permintaan — WAF menangkis serangan ke situs, itu memang tugasnya. Jika trafik sah Anda ikut terblokir (false positive) — cari rule id di detailnya dan tambahkan pengecualian ke konfig CRS.
  • AIDE: file berubah — cocokkan daftarnya dengan apa yang Anda lakukan (pembaruan paket, penyuntingan konfig — normal). Perubahan biner sistem yang tidak Anda sentuh — patut diwaspadai. Setelah perubahan yang sah, perbarui basis data AIDE.
  • debsums: biner/pustaka berubah (di luar /etc, di luar /usr/share) — berpotensi disusupi. Cocokkan paketnya: debsums PACKAGE_NAME, jika ragu pasang ulang (apt install --reinstall).
  • ClamAV / maldet: ditemukan ancaman — periksa file di karantina, jangan membukanya. Jika ini web shell di direktori situs — isolasi server dan cari titik masuknya (plugin rentan, kebocoran akses).
  • Falco: peristiwa kritis (menjalankan shell dalam kontainer, akses ke file sensitif) — telaah peristiwanya: proses milik siapa, apa yang menjalankannya. Sering kali ini aktivitas admin yang sah.
  • Paparan eksternal: DBMS/cache merah — segera tutup: ikat layanan ke 127.0.0.1 atau tutup port di UFW. Ini celah nyata.
  • SSL akan/telah kedaluwarsa — perpanjang sertifikat (Let's Encrypt memperpanjang otomatis; jika tidak — periksa certbot renew atau pengaturan di dashboard).
  • Pembaruan keamanan menunggu — pasang: sudo apt update && sudo apt upgrade; setelah pembaruan kernel, boot ulang server.
Tanda peretasan nyata (proses/pengguna tak dikenal, biner berubah, spam keluar, tugas cron tak dikenal): putuskan server dari akses eksternal, ambil cadangan untuk analisis, dan jika datanya kritis, siapkan server bersih dari cadangan tepercaya — membersihkan rootkit secara andal itu sulit.
Arcivéo - Security Monitor © 2026