AizuDemy

Tutorial Landlock LSM Go: Sandboxing Akses File System di VPS

Tutorial Landlock LSM Go: Sandboxing Akses File System di VPS
๐ŸŽง
Dengarkan Artikel Ini
Suara AI Otomatis โ€ข 10 mnt baca baca
โšก TL;DR

Poin Kunci Artikel Ini:

  • Akses membaca file konfigurasi internal aplikasi.
  • Namun, risiko keamanan pada level aplikasi tetap ada.
  • Saat penyerang berhasil mengeksekusi kode arbitrer, tindakan pertama mereka adalah mengeksplorasi struktur file system.
๐Ÿ“‹ Daftar Isi Materi Tutup โ–ด

Ancaman File System: RCE dan Kerentanan Supply Chain

Aplikasi backend berbasis Go sering kali dianggap lebih aman karena sifat tipe datanya yang statis dan proses kompilasi langsung ke binary independen. Namun, risiko keamanan pada level aplikasi tetap ada. Dua vektor serangan utama yang mengintai aplikasi Go yang berjalan di Virtual Private Server (VPS) adalah Remote Code Execution (RCE) dan serangan rantai pasokan (supply chain attack).

Serangan RCE dapat terjadi jika terdapat celah eksekusi perintah shell (seperti penyalahgunaan paket os/exec tanpa sanitasi input) atau kerentanan buffer overflow pada dependensi berbasis C (Cgo). Saat penyerang berhasil mengeksekusi kode arbitrer, tindakan pertama mereka adalah mengeksplorasi struktur file system. Target utama penyerang meliputi kredensial sensitif pada file konfigurasi (.env), token kunci API, file kunci privat SSH (~/.ssh/id_rsa), kredensial basis data, hingga file rahasia sistem seperti /etc/passwd atau /proc/self/environ.

Di sisi lain, serangan supply chain mengeksploitasi ketergantungan paket eksternal. Library pihak ketiga yang diimpor melalui go get dapat disusupi kode jahat atau diambil alih repositorinya. Kode jahat tersebut berjalan dengan hak akses penuh sesuai izin proses Go utama. Tanpa isolasi file system, dependensi yang terinfeksi dapat membaca seluruh isi direktori server, memasang pintu belakang (backdoor), atau memodifikasi file eksekusi lain di VPS.

Prinsip Least Privilege menegaskan bahwa setiap proses aplikasi hanya boleh memiliki hak akses minimum ke file system yang benar-benar dibutuhkan untuk beroperasi. Aplikasi web Go umumnya hanya memerlukan:

  • Akses membaca sertifikat TLS/SSL (/etc/ssl/certs).
  • Akses membaca resolver DNS sistem (/etc/resolv.conf dan /etc/hosts).
  • Akses membaca file konfigurasi internal aplikasi.
  • Akses menulis direktori log khusus dan file temporary (/tmp atau /var/log/app).

Pendekatan isolasi tradisional memiliki keterbatasan operasional di lingkungan produksi VPS:

  1. Chroot Jail: Memerlukan pengaturan direktori root virtual yang rumit, duplikasi dependensi shared library, serta membutuhkan hak akses root untuk pengaturannya. Chroot juga terbukti rentan terhadap teknik jailbreak jika proses retain kapabilitas CAP_SYS_CHROOT.
  2. Containerization (Docker/Podman): Menambah overhead abstraksi runtime, daemon terpisah, dan konfigurasi volume kompleks. Jika kontainer dijalankan sebagai root (rootful), kerentanan container escape dapat mengekspose file system host VPS secara menyeluruh.
  3. Mandatory Access Control (AppArmor / SELinux): Memerlukan pembuatan profil keamanan eksternal yang terpisah dari siklus hidup kode aplikasi. Pengaturan profil ini membutuhkan akses root sistem dan berisiko mengalami pergeseran konfigurasi (configuration drift) antara lingkungan staging dan produksi.

Landlock LSM (Linux Security Module) hadir sebagai solusi sandboxing in-process modern. Landlock memungkinkan aplikasi Go membatasi akses file system untuk dirinya sendiri dan proses turunannya (child process) secara mandiri, tanpa memerlukan hak akses root, tanpa daemon eksternal, dan langsung didefinisikan di dalam kode sumber Go.

Arsitektur dan Cara Kerja Landlock LSM

Landlock adalah modul keamanan Linux yang diintegrasikan secara resmi ke dalam kernel utama (mainline kernel) sejak versi 5.13. Berbeda dengan LSM tradisional seperti AppArmor atau SELinux yang bertindak sebagai pengawas eksternal berbasis kebijakan administrator sistem, Landlock dirancang untuk sandboxing terprogram (programmatic unprivileged sandboxing).

Arsitektur Landlock beroperasi pada lapisan Virtual File System (VFS) di kernel Linux. Ketika aplikasi Go melakukan panggilan sistem (system call) seperti openat(), unlinkat(), atau mkdirat(), kernel mengeksekusi hook Landlock untuk memeriksa apakah hak akses path yang diminta terdaftar dalam aturan (ruleset) yang telah diberlakukan pada proses tersebut.

Proses kerja pembatasan Landlock terdiri dari tiga tahapan utama:

  1. Inisialisasi Ruleset: Aplikasi mendefinisikan kumpulan izin akses file system yang diizinkan (allowlist) dan versi ABI target.
  2. Penambahan Aturan Path: Aplikasi menambahkan path file atau direktori spesifik beserta atribut operasinya (misalnya Read-Only atau Read-Write) ke dalam ruleset.
  3. Enforcement (Restriksi): Aplikasi memanggil syscall landlock_restrict_self(). Sebelum tahap ini dijalankan, Landlock mewajibkan bit PR_SET_NO_NEW_PRIVS diaktifkan pada proses via prctl(). Hal ini menjamin proses tidak dapat mendongkrak hak aksesnya kembali melalui eksekusi binary setuid atau setgid.

Sifat penting Landlock adalah irreversible (tidak dapat dibatalkan) dan hereditary (diwariskan). Setelah ruleset diberlakukan pada suatu proses, proses tersebut tidak dapat menambah izin akses baru atau membatalkan batasan yang sudah dipasang. Seluruh proses anak (child process) dan thread yang diturunkan melalui fork() atau clone() secara otomatis mewarisi batasan aturan yang sama.

Evolusi Versi Application Binary Interface (ABI) Landlock

  • ABI v1 (Linux 5.13+): Mengontrol operasi dasar file system. Hak akses mencakup LANDLOCK_ACCESS_FS_EXECUTE, READ_FILE, READ_DIR, WRITE_FILE, MAKE_REG, MAKE_DIR, MAKE_FIFO, MAKE_BLOCK, MAKE_SYM, MAKE_SOCK, MAKE_CHR.
  • ABI v2 (Linux 5.19+): Menambahkan kontrol operasi pembuatan link dan manipulasi struktur direktori melalui hak akses LANDLOCK_ACCESS_FS_REFER. Aturan ini mencegah pemindahan file (rename) atau pembentukan hardlink antardirektori yang dapat dipakai untuk melompati batasan sandbox.
  • ABI v3 (Linux 6.2+): Menambahkan hak akses LANDLOCK_ACCESS_FS_TRUNCATE. Memberikan kontrol presisi terhadap operasi pengubahan ukuran file (truncation) via syscall truncate() dan ftruncate().
  • ABI v4 (Linux 6.5+): Memperluas jangkauan sandboxing ke domain jaringan (network sandboxing) dengan mengontrol LANDLOCK_ACCESS_NET_BIND_TCP dan LANDLOCK_ACCESS_NET_CONNECT_TCP.
  • ABI v5 (Linux 6.10+): Menambahkan kontrol atas operasi ioctl pada file khusus perangkat melalui LANDLOCK_ACCESS_FS_IOCTL_DEV.

Implementasi Step-by-Step di Golang

Langkah 1: Inisialisasi Proyek dan Library

Buka terminal VPS atau mesin pengembang Linux Anda, buat modul baru, dan install library resmi Go Landlock binding (github.com/landlock-lsm/go-landlock):

mkdir go-landlock-vps
cd go-landlock-vps
go mod init go-landlock-vps
go get github.com/landlock-lsm/go-landlock/landlock

Langkah 2: Kode Golang Sandboxing Lengkap

Buat file main.go dengan isi berikut. Kode ini mengisolasi proses Go sehingga hanya dapat membaca direktori sertifikat sistem serta konfigurasi DNS, dan hanya dapat membaca/menulis di direktori kerja khusus /tmp/appdata dan /tmp/applog.

package main

import (
	"fmt"
	"os"
	"path/filepath"

	"github.com/landlock-lsm/go-landlock/landlock"
)

func main() {
	// 1. Pastikan direktori kerja yang dibutuhkan sudah dibuat
	workDir := "/tmp/appdata"
	logDir := "/tmp/applog"

	if err := os.MkdirAll(workDir, 0755); err != nil {
		fmt.Printf("[ERROR] Gagal membuat workDir: %v\n", err)
		os.Exit(1)
	}
	if err := os.MkdirAll(logDir, 0755); err != nil {
		fmt.Printf("[ERROR] Gagal membuat logDir: %v\n", err)
		os.Exit(1)
	}

	fmt.Println("[INFO] Mengaktifkan Landlock LSM Sandbox...")

	// 2. Definisi Aturan Restriksi Landlock
	// Menentukan file Read-Only (RO) dan Read-Write (RW) yang diizinkan
	err := landlock.V3.BestEffort().RestrictPaths(
		// Izin Read-Only: Sertifikat TLS, Resolv DNS, dan Konfigurasi Hosts
		landlock.ROFiles(
			"/etc/ssl/certs",
			"/etc/ca-certificates",
			"/etc/resolv.conf",
			"/etc/hosts",
		),
		// Izin Read-Write: Tempat penyimpanan log dan data sementara aplikasi
		landlock.RWFiles(
			workDir,
			logDir,
		),
	)

	if err != nil {
		fmt.Printf("[FATAL] Gagal menerapkan aturan Landlock: %v\n", err)
		os.Exit(1)
	}

	fmt.Println("[SUCCESS] Sandbox Landlock berhasil diaktifkan secara irreversibel.")

	// 3. Pengujian Operasi Diizinkan (Write file ke /tmp/appdata)
	targetFilePath := filepath.Join(workDir, "session.log")
	data := []byte("Log audit aplikasi: Sistem berjalan normal di sandbox.")
	if err := os.WriteFile(targetFilePath, data, 0644); err != nil {
		fmt.Printf("[FAIL] Gagal menulis ke file terisolasi: %v\n", err)
	} else {
		fmt.Printf("[OK] Berhasil menulis file di: %s\n", targetFilePath)
	}

	// 4. Pengujian Operasi Diblokir (Read /etc/passwd)
	fmt.Println("[TEST] Memencoba membaca file sensitif /etc/passwd...")
	content, err := os.ReadFile("/etc/passwd")
	if err != nil {
		fmt.Printf("[BLOCKED] Akses ke /etc/passwd berhasil ditolak oleh Kernel: %v\n", err)
	} else {
		fmt.Printf("[CRITICAL WARNING] Kebocoran Keamanan! File berhasil dibaca: %d byte\n", len(content))
	}

	// 5. Pengujian Operasi Diblokir (Write ke /etc/environment)
	fmt.Println("[TEST] Mencoba menulis file ke /etc/environment...")
	err = os.WriteFile("/etc/environment", []byte("MALICIOUS=true"), 0644)
	if err != nil {
		fmt.Printf("[BLOCKED] Akses menulis ke /etc/environment ditolak: %v\n", err)
	} else {
		fmt.Println("[CRITICAL WARNING] Kebocoran Keamanan! Berhasil menulis ke file sistem!")
	}
}

Langkah 3: Kompilasi dan Eksekusi Binary

Lakukan kompilasi statis binary Go agar siap dijalankan di VPS Linux tanpa ketergantungan runtime luar:

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o landlock-app main.go

Jalankan binary sebagai user non-root biasa:

./landlock-app

Output eksekusi yang diharapkan:

[INFO] Mengaktifkan Landlock LSM Sandbox...
[SUCCESS] Sandbox Landlock berhasil diaktifkan secara irreversibel.
[OK] Berhasil menulis file di: /tmp/appdata/session.log
[TEST] Memencoba membaca file sensitif /etc/passwd...
[BLOCKED] Akses ke /etc/passwd berhasil ditolak oleh Kernel: open /etc/passwd: permission denied
[TEST] Mencoba menulis file ke /etc/environment...
[BLOCKED] Akses menulis ke /etc/environment ditolak: open /etc/environment: permission denied

Best Practice, Troubleshooting, dan Debugging

1. Verifikasi Dukungan Kernel VPS

Sebelum mengandalkan Landlock di server produksi, periksa versi kernel dan status pengaktifan LSM pada OS Linux VPS:

uname -r

Output harus menunjukkan versi kernel >= 5.13.

Periksa modul LSM yang sedang aktif di kernel:

cat /sys/kernel/security/lsm

Pastikan kata landlock muncul dalam daftar output (misal: landlock,lockdown,yama,apparmor,bpf).

Jika landlock belum tercantum, aktifkan melalui parameter boot GRUB. Edit file /etc/default/grub:

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash lsm=landlock,lockdown,yama,apparmor,bpf"

Kemudian perbarui konfigurasi GRUB dan restart VPS:

sudo update-grub
sudo reboot

2. Diagnosis Syscall Permission Denied (EACCES) dengan strace

Saat mengaktifkan Landlock, aplikasi Go Anda mungkin mendadak mengalami error permission denied (syscall.EACCES). Hal ini terjadi karena runtime Go atau paket standar secara diam-diam mengakses file sistem yang lupa dimasukkan ke daftar izin ROFiles (misalnya file timezone /usr/share/zoneinfo, sertifikat SSL, atau file localized locale).

Gunakan tool strace untuk melacak file system call yang dipanggil binary sebelum pembatasan Landlock diterapkan:

strace -f -e trace=openat,stat,readlink ./landlock-app

Analisis log strace untuk mendeteksi file apa saja yang diakses aplikasi saat startup dan runtime execution. Tambahkan path tersebut ke dalam aturan landlock.ROFiles() pada kode Go.

3. Penanganan Mode Fallback (BestEffort) vs Enforcement Ketat

Library Go Landlock menyediakan dua mode eksekusi:

  • landlock.V3.BestEffort().RestrictPaths(...): Mengaktifkan batasan jika kernel mendukungnya. Jika aplikasi berjalan di kernel lama (< 5.13), fungsi mengabaikan pembatasan secara tertutup tanpa mematikan aplikasi. Sangat ideal untuk kompatibilitas aplikasi lintas OS (seperti saat dijalankan di macOS/Windows pengembang).
  • landlock.V3.RestrictPaths(...): Mengunci proses secara ketat. Jika kernel VPS tidak mendukung versi ABI Landlock yang diminta, fungsi mengembalikan error dan menghentikan eksekusi. Mode ini disarankan untuk lingkungan produksi VPS yang mewajibkan kepatuhan keamanan tinggi.

4. Kombinasi Landlock dengan Systemd Service

Tingkatkan pertahanan bertapis (Defense in Depth) dengan mengombinasikan Landlock di dalam kode Go dan pengerasan (hardening) file layanan Systemd (/etc/systemd/system/myapp.service):

[Unit]
Description=Go Production Service with Landlock
After=network.target

[Service]
Type=simple
User=www-data
Group=www-data
ExecStart=/usr/local/bin/landlock-app
Restart=always

# Hardening tingkat Systemd
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ReadOnlyPaths=/

[Install]
WantedBy=multi-user.target

Checklist Implementasi Security VPS

  • Audit Kernel VPS: Pastikan kernel VPS Linux minimal versi 5.13 dan parameter lsm=landlock aktif di bootloader.
  • Pemetaan Hak Akses File System: Klasifikasikan secara presisi path yang butuh izin Read-Only (sertifikat TLS, resolver DNS, file .env) dan izin Read-Write (direktori log, upload folder).
  • Inisialisasi Posisi Sandbox: Panggil RestrictPaths() sedini mungkin pada fungsi main(), sesaat setelah membaca file konfigurasi awal dan membuka port listener.
  • Eksekusi Unprivileged User: Pastikan binary Go dijalankan sebagai user biasa (misalnya www-data atau user khusus tanpa privilege root).
  • Pengujian Staging: Jalankan pengujian integrasi (integration testing) komprehensif di lingkungan staging untuk memastikan tidak ada fitur aplikasi yang gagal akibat terblokir kernel.
  • Logging Error Audit: Tangkap dan catat error inisialisasi Landlock ke sistem monitoring log (seperti Journald atau Datadog) untuk mendeteksi anomali kegagalan sandboxing.

Kesimpulan

Landlock LSM mengubah paradigma pengamanan aplikasi Go di server VPS. Dengan memindahkan kontrol keamanan file system langsung ke dalam kode aplikasi, pengembang Go tidak lagi tergantung sepenuhnya pada konfigurasi infrastruktur eksternal atau hak akses root. Penyerang yang berhasil menemukan celah RCE atau mengeksploitasi dependensi jahat akan terisolasi penuh di dalam ruang sandbox file system yang sangat terbatas. Terapkan Landlock LSM pada layanan Go produksi Anda hari ini untuk membangun arsitektur pertahanan bertapis yang tangguh dan modern.

๐Ÿ“– Artikel Terkait