Tidak ada sistem yang benar-benar aman; yang ada hanya sistem yang mahal dan melelahkan untuk dibobol. Linux mewarisi desain multi-user dari Unix, tetapi warisan itu hanya melindungi kita bila dipakai dengan sadar: menahan hak, memisahkan tugas, dan menutup pintu yang tidak dipakai. Chapter ini membangun kerangka berpikirnya sebelum kita menyentuh alat apa pun: apa yang dilindungi, prinsip least privilege, separation of privilege, attack surface, dan defense in depth. Seluruh chapter pada Section Security selanjutnya — dari pembaruan sistem hingga firewall — pada dasarnya adalah penerapan satu atau beberapa prinsip di sini.

Apa yang Dilindungi: Confidentiality, Integrity, Availability #

Kerangka paling ringkas untuk berpikir soal keamanan disebut CIA. Confidentiality berarti data hanya bisa dibaca pihak yang berhak; integrity berarti data tidak berubah tanpa izin; availability berarti layanan tetap bisa diakses saat dibutuhkan. Ketiganya saling menopang, dan Linux menyediakan alat berbeda untuk masing-masing:

AspekPertanyaan kuncinyaAlat utama di Linux
Confidentialitysiapa saja yang boleh membaca?permission, enkripsi disk
Integritysiapa saja yang boleh mengubah?permission, checksum
Availabilityapakah tetap hidup saat dibutuhkan?backup, monitoring, update

Serangan nyata selalu mengincer salah satunya: pencurian data menyerang confidentiality, situs yang isinya dibetot orang menyerang integrity, sementara serangan DoS menyerang availability. Perhatikan bahwa permission muncul di dua baris pertama — kontrol akses adalah fondasinya, dan lapisan lain berdiri di atasnya.

Least Privilege: Hak Sekecil yang Diperlukan #

Prinsip paling dasar sekaligus akar dari hampir semua praktik keamanan: setiap akun, proses, dan orang hanya boleh memegang hak yang benar-benar diperlukannya untuk menyelesaikan tugasnya. Kebalikannya adalah bekerja sebagai root sepanjang hari — satu kesalahan ketik rm -rf atau satu celah pada aplikasi langsung memberikan penyerang seluruh sistem. Alasan sudo diciptakan persis untuk ini, sebagaimana dibahas pada Chapter sudo dan root . Kita periksa dulu identitas akun root dan sesi kita sendiri:

bash
id root
if [ "$(id -u)" -eq 0 ]; then
  echo "sesi ini menjalankan root"
else
  echo "sesi ini user biasa (uid $(id -u))"
fi

Output yang Dihasilkan:

text
uid=0(root) gid=0(root) groups=0(root)
sesi ini user biasa (uid 1001)

Mari kita bedah blok di atas:

  1. Baris 1 (id root): menampilkan identitas akun root. Yang penting bukan namanya, melainkan angkanya: uid=0. Kernel Linux tidak mengenal nama login saat memeriksa hak — kernel memeriksa UID, dan UID 0 adalah satu-satunya UID yang melewati hampir semua pemeriksaan permission.
  2. Baris 2 (if [ "$(id -u)" -eq 0 ]): mengambil UID dari sesi sekarang lalu membandingkannya dengan 0. Pola ini sering dipakai di skrip untuk memastikan skrip tidak dijalankan sebagai root — atau sebaliknya, menolak jalan bila bukan root.
  3. Baris 4 (else): mesin latihan kita menjalankan user biasa dengan UID 1001. Nama dan angka di komputer Anda tentu berbeda; yang penting untuk keamanan adalah angkanya bukan 0.

Prinsip yang sama berlaku untuk proses. Web server Debian menjalankan proses pekerjanya sebagai user www-data yang nyaris tanpa hak apa pun, sehingga saat aplikasi web tertembus, penyerang mewarisi akun minim itulah — bukan root. Semakin kecil hak yang dipegang, semakin kecil pula ledakan saat satu bagian jatuh.

Separation of Privilege: Password dan Hashnya Berpisah #

Prinsip kedua: jangan menaruh dua hal yang butuh perlindungan berbeda pada satu tempat yang sama. Contoh klasiknya ada di file identitas user. Banyak alat — dari ls -l sampai login screen — perlu membaca pemetaan nama ke UID, sehingga /etc/passwd terpaksa terbaca untuk semua user. Namun file itu dulu juga menyimpan hash password, dan hash yang terbaca semua orang adalah bahan baku serangan offline cracking. Solusinya: memisahkan hash ke file /etc/shadow dengan permission jauh lebih ketat. Kita bandingkan keduanya:

bash
stat -c '%a %U %G %n' /etc/passwd /etc/shadow
getent passwd root

Output yang Dihasilkan:

text
644 root root /etc/passwd
640 root shadow /etc/shadow
root:x:0:0:root:/root:/bin/bash

Mari kita baca keluarannya:

  1. 644 root root /etc/passwd: mode 644 berarti owner root boleh baca-tulis, sedangkan group dan other hanya boleh membaca — file ini memang bacaan umum.
  2. 640 root shadow /etc/shadow: mode 640 membatasi pembacaan hanya untuk root dan group shadow. Angka 640 di sini bukan hiasan: hanya program yang berjalan sebagai root (misalnya sudo dengan bit setuid, dan passwd) yang berhak membaca hash.
  3. root:x:0:0:...: huruf x pada kolom kedua adalah penanda bahwa password root tidak ada di file ini — letak aslinya adalah /etc/shadow.

Batas itu bukan sekadar teori; kita bisa merasakannya langsung:

bash
cat /etc/shadow 2>&1

Output yang Dihasilkan:

text
cat: /etc/shadow: Permission denied

Akses ditolak: sesi kita bukan root dan tidak tergabung dalam group shadow. Berkat pemisahan ini, aplikasi biasa tetap bisa membaca /etc/passwd tanpa pernah menyentuh hash password — dua kebutuhan berbeda, dua tempat berbeda.

Attack Surface: Setiap Service adalah Pintu #

Attack surface adalah seluruh titik di mana sistem kita bisa disentuh dari luar: port yang mendengarkan, service yang berjalan, akun yang bisa login. Aturan praktisnya sederhana — service yang tidak berjalan tidak bisa ditembus. Karena itu audit pertama pada server baru selalu bertanya: apa saja yang sedang berjalan? Di sistem dengan systemd, jawabannya diambil dari systemctl list-units --type=service --state=running — berikut contoh tampilannya:

text
UNIT                    LOAD   ACTIVE SUB     DESCRIPTION
cron.service            loaded active running Regular background program processing
nginx.service           loaded active running A high performance web server
sshd.service            loaded active running OpenBSD Secure Shell server

Setiap baris running pada daftar itu adalah kandidat pintu. Untuk merasakan bagaimana satu perintah membuka pintu baru, kita jalankan server HTTP mini lalu periksa daftar port yang mendengarkan:

bash
printf 'dokumen-intern' > catatan.txt
python3 -m http.server 8791 --bind 0.0.0.0 >/dev/null 2>&1 &
server=$!
for i in 1 2 3 4 5; do
  curl -s 127.0.0.1:8791/catatan.txt && break
  sleep 0.2
done
printf '\n'
ss -tln 'sport = :8791'
kill "$server"
sleep 0.2

Output yang Dihasilkan:

text
dokumen-intern
State  Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0      5            0.0.0.0:8791      0.0.0.0:*   

Mari kita bedah baris demi baris:

  1. Baris 1 (printf ... > catatan.txt): menyiapkan satu file yang isinya meniru dokumen internal — nanti kita lihat file ini bisa diambil begitu saja oleh siapa pun yang menjangkau port tersebut.
  2. Baris 2-3: server HTTP Python dijalankan di background dengan --bind 0.0.0.0, artinya server mendengarkan di semua interface — termasuk kartu jaringan, bukan hanya loopback. PID-nya disimpan agar bisa dimatikan dengan bersih.
  3. Baris 4-7 (for i in ...): mencoba mengambil file berulang kali sampai server siap, lalu break. Ini pola menunggu yang lazim untuk demo server singkat.
  4. Baris 8 (ss -tln 'sport = :8791'): mendaftar socket TCP yang mendengarkan, difilter langsung oleh ss pada port 8791 — satu baris LISTEN pada 0.0.0.0:8791 itulah pintu yang baru kita buka.
  5. Baris 9-10 (kill dan wait): server dimatikan dan socket-nya tertutup — begitu proses mati, pintunya ikut hilang. Inilah pesannya: pintu hidup dan mati mengikuti prosesnya, bukan sebaliknya.

Konsekuensi praktisnya dua arah: matikan service yang tidak perlu (systemctl disable --now nama.service), dan bila sebuah service memang hanya untuk mesin sendiri, ikat ke 127.0.0.1 seperti yang sudah kita lakukan pada Chapter Network Diagnostics .

Defense in Depth: Pagar Berlapis, Bukan Pagar Tunggal #

Tidak ada satu lapisan pertahanan yang bebas dari kegagalan: permission bisa salah ketik, firewall bisa punya celah aturan, software yang mutakhir tetap punya celah yang belum ditemukan. Strategi yang realistis adalah defense in depth — menumpuk beberapa lapisan yang saling menutupi, sehingga kegagalan satu lapisan tidak langsung menjadi kebobolan total:

LapisanPertanyaan yang dijawabnyaContoh di Section ini
Permissionsiapa boleh membaca dan mengubah?Chapter File Permissions
Firewallpaket dari mana yang diterima?Chapter Firewall dan ufw dan firewalld
Updatecelah yang sudah ditambal, sudah terpasang?Chapter Security Updates
Monitoringada yang aneh sejak kapan?audit log dan file integrity

Di atas lapisan-lapisan itu berdiri tiga pilar rutin: patching untuk menutup celah yang sudah diketahui, backup sebagai jaring pengaman saat segalanya gagal, dan monitoring sebagai mata yang memberi tahu saat ada yang menyusup. Ketiganya adalah pekerjaan berulang, bukan sekali jadi — dan itu pula alasan Section ini disusun sebagai proses, bukan daftar produk. Dari semua lapisan di atas, ada satu yang paling murah namun paling sering ditunda orang: memperbarui sistem. Chapter berikutnya membahasnya serius, mulai dari alasan di balik CVE sampai otomasi dengan unattended-upgrades.

Referensi lanjut: wiki Arch Linux tentang Security untuk peta praktik hardening di Arch, halaman keamanan Debian untuk cara Debian menangani celah, serta shadow(5) untuk format file /etc/shadow.