Tutorial Landlock LSM Go: Sandboxing Akses File System di VPS
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.
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.confdan/etc/hosts). - Akses membaca file konfigurasi internal aplikasi.
- Akses menulis direktori log khusus dan file temporary (
/tmpatau/var/log/app).
Pendekatan isolasi tradisional memiliki keterbatasan operasional di lingkungan produksi VPS:
- 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. - 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.
- 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:
- Inisialisasi Ruleset: Aplikasi mendefinisikan kumpulan izin akses file system yang diizinkan (allowlist) dan versi ABI target.
- Penambahan Aturan Path: Aplikasi menambahkan path file atau direktori spesifik beserta atribut operasinya (misalnya Read-Only atau Read-Write) ke dalam ruleset.
- Enforcement (Restriksi): Aplikasi memanggil syscall
landlock_restrict_self(). Sebelum tahap ini dijalankan, Landlock mewajibkan bitPR_SET_NO_NEW_PRIVSdiaktifkan pada proses viaprctl(). Hal ini menjamin proses tidak dapat mendongkrak hak aksesnya kembali melalui eksekusi binarysetuidatausetgid.
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 syscalltruncate()danftruncate(). - ABI v4 (Linux 6.5+): Memperluas jangkauan sandboxing ke domain jaringan (network sandboxing) dengan mengontrol
LANDLOCK_ACCESS_NET_BIND_TCPdanLANDLOCK_ACCESS_NET_CONNECT_TCP. - ABI v5 (Linux 6.10+): Menambahkan kontrol atas operasi
ioctlpada file khusus perangkat melaluiLANDLOCK_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/landlockLangkah 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.goJalankan binary sebagai user non-root biasa:
./landlock-appOutput 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 deniedBest 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 -rOutput harus menunjukkan versi kernel >= 5.13.
Periksa modul LSM yang sedang aktif di kernel:
cat /sys/kernel/security/lsmPastikan 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 reboot2. 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-appAnalisis 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.targetChecklist Implementasi Security VPS
- Audit Kernel VPS: Pastikan kernel VPS Linux minimal versi 5.13 dan parameter
lsm=landlockaktif 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 fungsimain(), sesaat setelah membaca file konfigurasi awal dan membuka port listener. - Eksekusi Unprivileged User: Pastikan binary Go dijalankan sebagai user biasa (misalnya
www-dataatau 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.


