Praktik menulis profil AppArmor pertama: sintaks profile dengan aturan di dalam kurung kurawal, aturan file r w m k, path globbing untuk pola direktori, aturan deny untuk melarang akses eksplisit, hingga penggunaan include dan abstraksi yang disediakan distro.

Di episode 3 kita belajar memuat, melepas, dan mengubah mode profil — tapi semua itu kita lakukan terhadap profil yang sudah ada. Kini saatnya bagian paling kreatif: menulis profil dari nol. Ini keterampilan inti series ini; di episode 5 nanti kalian akan membuat profil yang sama dengan bantuan tools otomatis, dan di episode-episode setelahnya kalian akan memperluasnya untuk layanan nyata.
Bayangkan kalian menulis SOP (Standard Operating Procedure) untuk sebuah mesin. SOP itu harus spesifik: siapa yang boleh masuk ruangan mana, dokumen apa yang boleh dibaca, dan apa yang dilarang keras. Terlalu longgar dan SOP itu tidak berguna; terlalu ketat dan mesinnya berhenti bekerja. Menulis profil AppArmor adalah seni yang sama.
Profil AppArmor adalah file teks dengan struktur sederhana. Sintaks paling dasar:
profile <nama-profil> {
<aturan akses>
}Baris profile <nama-profil> memberi nama profil — biasanya diambil dari path executable yang dilindungi. Di dalam kurung kurawal, kita menulis aturan akses. Mari lihat profil nyata yang paling sederhana:
profile /usr/bin/cat {
/usr/bin/cat r,
/etc/ld.so.cache r,
/lib/x86_64-linux-gnu/libc.so.6 mr,
/etc/localtime r,
owner /home/*/ r,
}Perhatikan beberapa hal dari contoh di atas:
/usr/bin/cat./usr/bin/cat harus bisa membaca file-nya sendiri, maka baris /usr/bin/cat r mengizinkannya.libc.so.6 diizinkan dengan akses mr (baca dan mmap) karena m krusial untuk memuat library, seperti yang kita bahas di episode 2.owner /home/*/ r mengizinkan membaca file yang dimiliki user yang sama di direktori home — pola owner membatasi aturan hanya untuk file milik pemilik proses.Empat akses dasar file yang wajib kalian pahami (dari episode 2):
| Akses | Arti | Kapan dibutuhkan |
|---|---|---|
r | Baca file | Membaca konfigurasi, log, data |
w | Tulis file | Menulis log, cache, lock file |
m | Memory-map (mmap) | Memuat library .so ke memori |
k | File lock | Mengunci file untuk sinkronisasi |
Dalam satu aturan, beberapa akses bisa digabung: mr berarti boleh baca dan mmap, rw berarti baca dan tulis. Contoh baris aturan:
/etc/apparmor.d/nginx r,
/var/log/nginx/access.log rw,
/lib/x86_64-linux-gnu/libc.so.6 mr,
/var/run/nginx.pid rwk,Baris terakhir memakai rwk — baca, tulis, dan lock — karena pid file sering dikunci saat proses menulisnya. Memahami kombinasi inilah yang membedakan profil yang berfungsi dengan profil yang membuat aplikasi error.
Dunia nyata jarang sesederhana satu file. Untuk mengizinkan akses ke banyak file dengan satu pola, AppArmor menyediakan glob:
| Pola | Makna | Contoh cocok |
|---|---|---|
* | Segmen path apa pun (bukan /) | /usr/bin/* cocok dengan /usr/bin/cat |
** | Segmen path apa pun termasuk / | /etc/** cocok dengan /etc/nginx/nginx.conf |
? | Satu karakter | /usr/bin/ngin? cocok dengan /usr/bin/nginx |
{a,b} | Salah satu dari daftar | /etc/{hosts,resolv.conf} |
Contoh pemakaian glob dalam profil:
/etc/nginx/** r,
/var/log/nginx/*.log rw,
/usr/share/nginx/** r,
{var,etc}/** r,Pola {var,etc}/** pada baris terakhir mengizinkan akses baca ke seluruh isi /var dan /etc — pola ini sering muncul di profil milik daemon yang berjalan lama. Hati-hati: glob yang terlalu lebar seperti /etc/** rw pada dasarnya menghilangkan proteksi, jadi selalu seminimal mungkin.
Kadang langkah paling aman bukan mengizinkan, melainkan melarang secara eksplisit. Aturan deny ditulis dengan kata kunci deny:
profile /usr/bin/git {
/usr/bin/git r,
deny /root/** w,
deny /etc/shadow r,
deny /home/*/.ssh/** r,
}Mengapa perlu deny padahal prinsip default-nya tertutup kecuali diizinkan? Karena ada celah: pada awalnya kalian mungkin memberi aturan luas seperti /home/*/** r, lalu ingin menutup sebagian — misalnya ~/.ssh. Aturan deny bertindak sebagai pagar di dalam pagar: ia mempersempit akses yang sebelumnya diizinkan oleh pola yang lebih lebar, dan selalu menang atas aturan allow.
Warning
Prinsip keamanan AppArmor tetap "tertutup kecuali diizinkan" — deny bukan pengganti minimalisme. Namun deny sangat berguna untuk menutup lubang spesifik dalam pola yang luas, atau untuk menunjukkan niat ("folder ini jangan pernah diakses") agar terbaca jelas oleh anggota tim lain.
Menulis library path secara manual di setiap profil itu membosankan dan rawan salah. Solusinya: include. Direktori /etc/apparmor.d/tunables berisi variabel dan nilai konfigurasi, dan direktori /etc/apparmor.d/abstractions berisi blok aturan siap pakai. Tiga include yang hampir selalu muncul di profil daemon:
#include <tunables/global> memuat variabel global seperti definisi path umum.#include <abstractions/base> menyediakan aturan dasar semua proses: akses library standar, /etc/ld.so.cache, dan sejenisnya.#include <abstractions/openssl> menambahkan akses yang dibutuhkan untuk mengamankan koneksi TLS.Ini profil yang lebih realistis: aturan inti ditulis manual, dan bagian boilerplate diambil dari abstraksi. Bila kalian masih muda dalam menulis profil, abstraksi adalah cara tercepat belajar — buka file abstraksinya dan pelajari polanya:
ls /etc/apparmor.d/abstractionsMari gabungkan semuanya dalam satu profil lengkap untuk nginx. Perhatikan bahwa ini profil minimal untuk demonstrasi — versi production akan lebih panjang:
profile /usr/sbin/nginx {
#include <tunables/global>
#include <abstractions/base>
#include <abstractions/openssl>
capability net_bind_service,
capability setuid,
capability setgid,
network inet tcp,
/usr/sbin/nginx mr,
/etc/nginx/** r,
/var/log/nginx/** w,
/var/lib/nginx/** rw,
/var/run/nginx.pid rwk,
deny /etc/shadow r,
}Untuk mengaktifkan profil ini, simpan sebagai /etc/apparmor.d/usr.sbin.nginx, lalu ikuti alur yang kita pelajari di episode 3:
sudo apparmor_parser -Q /etc/apparmor.d/usr.sbin.nginx
sudo apparmor_parser -a /etc/apparmor.d/usr.sbin.nginx
sudo aa-status | grep nginxJika -Q tidak menampilkan error dan grep menemukan profil nginx di output aa-status, profil kalian berhasil dimuat. Jangan lupa test aplikasi: jalankan service dan pastikan tidak ada denial di log — jika ada, lakukan penyesuaian. Di episode 5, tools aa-genprof dan aa-logprof akan membantu proses penyesuaian ini secara otomatis.
/usr/sbin/nginx mr, aplikasi tidak bisa dijalankan sama sekali.m). Aplikasi yang error "cannot open shared object" biasanya karena library tidak diizinkan di-mmap. Gunakan abstraksi base untuk menutup kasus ini./etc/** rw hampir menghapus nilai proteksi. Mulai sempit, perluas hanya saat ada denial yang sah.apparmor_parser -Q gagal.Pada episode 4 ini kita belajar menulis profil dari nol: struktur profile <nama> { ... }, aturan file r w m k dan kombinasinya, path globbing dengan * ** ? dan {a,b}, aturan deny untuk melarang eksplisit, serta include tunables dan abstraksi untuk memakai ulang aturan siap pakai.
Inti yang harus kalian bawa:
r baca, w tulis, m mmap, k lock — pahami kapan masing-masing dibutuhkan.* satu segmen, ** semua, {a,b} alternatif.<abstractions/base> menghapus boilerplate; biasakan -Q sebelum load.Di episode 5 selanjutnya, kita akan melipatgandakan produktivitas kalian: aa-genprof dan aa-logprof — membuat profil secara interaktif dari executable target, mengizinkan atau menolak setiap request yang muncul, serta memperbarui profil dari log denial. Pastikan tetap semangat, karena dengan kedua tools ini kalian tidak akan pernah menulis profil dari halaman kosong lagi!