5 poin oleh GN⁺ 2025-08-20 | 1 komentar | Bagikan ke WhatsApp
  • systemd menyediakan fitur manajemen layanan yang kuat, tetapi konfigurasi default-nya dioptimalkan untuk kemudahan penggunaan alih-alih keamanan, sehingga perlu menerapkan opsi hardening secara terpisah
  • Melalui perintah systemd-analyze security, Anda dapat menganalisis indikator paparan keamanan untuk seluruh layanan atau layanan tertentu, lalu menentukan prioritas
  • Tersedia berbagai opsi keamanan yang dapat diterapkan pada unit layanan, dan ini bisa dimodifikasi satu per satu melalui /etc/systemd/system/ServiceName.service.d/override.conf dan sejenisnya
  • Opsi utama mencakup ProtectSystem, PrivateTmp, NoNewPrivileges, SystemCallFilter, MemoryDenyWriteExecute, dan lainnya yang membatasi hak proses serta akses ke sumber daya
  • Daripada menargetkan keamanan yang sempurna, lebih efektif memprioritaskan hardening pada layanan yang terekspos ke luar untuk mengurangi risiko, dan ini juga sangat bermanfaat di lingkungan self-hosting

Gambaran umum systemd

  • systemd menyediakan pendekatan yang sangat matang dan tangguh untuk manajemen layanan
  • Namun, karena memprioritaskan kemudahan penggunaan langsung dibanding keamanan, konfigurasi default-nya dibuat cukup longgar
  • Dokumen ini memperkenalkan berbagai opsi penguatan keamanan yang dapat diterapkan pada unit layanan systemd dan podman quadlet untuk mengurangi kemungkinan kompromi serta meminimalkan cakupan dampaknya saat kompromi terjadi
  • Ini bukan panduan untuk diterapkan sekaligus ke semua layanan; diperlukan eksperimen terpisah, pemeriksaan log, dan penyesuaian sesuai karakteristik serta kebutuhan fungsi masing-masing layanan
  • Tanggung jawab keamanan infrastruktur sepenuhnya berada pada operator, dan dokumen ini hanyalah alat referensi

Analisis keamanan systemd

  • Dengan perintah systemd-analyze security, Anda dapat memeriksa status keamanan seluruh layanan atau menganalisis pengaturan detail layanan tertentu (misalnya sshd.service)
    • Output mencakup status pemeriksaan, nama fitur, penjelasan, dan skor Exposure; semakin tinggi Exposure, semakin besar risikonya
  • Opsi keamanan dapat ditambahkan pada bagian [Service] (systemd) atau [Container] (podman quadlet)
  • Disarankan membuat file override melalui systemctl edit ServiceName.service; jika gagal, periksa hak akses yang diperlukan lalu sesuaikan

Opsi keamanan layanan

  • systemd menyediakan berbagai kata kunci opsi keamanan yang dapat dilihat melalui man systemd.exec 5, man capabilities 7, dan lainnya
  • Opsi keamanan yang representatif
    • ProtectSystem → opsi untuk membatasi filesystem menjadi hanya-baca
    • ProtectHome → opsi untuk memblokir akses ke /home, /root, /run/user
    • PrivateDevices → opsi untuk memblokir akses ke perangkat fisik dan hanya mengizinkan perangkat virtual seperti /dev/null
    • ProtectKernelTunables, ProtectKernelModules, ProtectKernelLogs → opsi untuk memblokir akses ke sumber daya kernel
    • NoNewPrivileges → opsi untuk mencegah perolehan hak baru melalui setuid/setgid dan sejenisnya
    • MemoryDenyWriteExecute → memblokir penggunaan memori yang dapat ditulis dan dieksekusi secara bersamaan; dapat menimbulkan masalah pada sebagian bahasa JIT
    • SystemCallFilter → opsi untuk membatasi system call yang diizinkan; jika dilanggar, proses dapat dihentikan atau mengembalikan EPERM

Penjelasan tiap opsi

  • ProtectSystem: saat diatur ke strict, seluruh filesystem di-mount sebagai hanya-baca; /dev, /proc, /sys memerlukan opsi perlindungan terpisah
  • ReadWritePaths: mengatur agar hanya beberapa path tertentu yang bisa ditulis kembali
  • ProtectHome: memblokir akses ke /home, /root, /run/user
  • PrivateDevices: menonaktifkan akses ke perangkat fisik, hanya mengizinkan perangkat pseudo seperti /dev/null
  • ProtectKernelTunables: menjadikan /proc, /sys hanya-baca
  • ProtectControlGroups: hanya mengizinkan akses baca ke cgroup
  • ProtectKernelModules: melarang pemuatan eksplisit modul kernel
  • ProtectKernelLogs: membatasi akses ke buffer log kernel
  • ProtectProc: saat diatur ke invisible, proses milik pengguna lain disembunyikan dari /proc/
  • ProcSubset: memblokir isi /proc selain item terkait PID tertentu
  • NoNewPrivileges: memblokir eskalasi hak baru melalui setuid, setgid, dan capability filesystem
  • ProtectClock: memblokir penulisan ke jam sistem/perangkat keras
  • SystemCallArchitectures: saat diatur ke native, hanya mengizinkan syscall native seperti x86-64
  • RestrictNamespaces: membatasi namespace yang khusus untuk kontainer
  • RestrictSUIDSGID: memblokir pengaturan bit setuid dan setgid pada file
  • LockPersonality: mencegah perubahan domain eksekusi (biasanya hanya diperlukan untuk aplikasi lama)
  • RestrictRealtime: membatasi penjadwalan real-time (hanya diperlukan untuk sebagian layanan tujuan khusus)
  • RestrictAddressFamilies: membatasi keluarga alamat soket yang diizinkan (misalnya menentukan AF_INET, AF_INET6, AF_UNIX, dll.)
  • MemoryDenyWriteExecute: memblokir pembuatan tambahan area memori yang dapat ditulis+dieksekusi (layanan yang memakai JIT perlu berhati-hati)
  • ProtectHostname: melarang penggunaan syscall sethostname, setdomainname
  • SystemCallFilter: mengatur syscall yang diizinkan/diblokir per layanan, dengan pemfilteran yang sangat rinci
    • Dapat disesuaikan berdasarkan grup, syscall individual, serta metode izinkan/blokir
    • Saat terjadi pelanggaran, juga mendukung pengaturan agar mengembalikan kode error seperti EPERM alih-alih langsung dihentikan
    • Daftar lengkap dapat dilihat melalui systemd-analyze syscall-filter atau man systemd.exec(5)
    • Daftar dapat dinegasikan seluruhnya dengan prefiks ~ (misalnya CapabilityBoundingSet=~CAP_SETUID dan seterusnya)

Proses penyesuaian pembatasan SystemCallFilter

  • Dengan auditd, Anda dapat memeriksa log syscall mana yang diblokir saat layanan gagal
    • Jalankan sudo ausearch -i -m SECCOMP -ts recent, lalu periksa nilai syscall
    • Tambahkan syscall tersebut atau grup terkait ke SystemCallFilter untuk menyelesaikan masalah secara bertahap

Prioritas penerapan hardening dan tips operasional

  • Tidak perlu menerapkannya semua ke setiap layanan
  • Threat model dan manajemen risiko adalah inti; khususnya layanan yang terekspos ke luar (httpd, nginx, ssh, dll.) wajib dipertimbangkan
  • Penerapan proaktif juga efektif untuk custom command, unit timer (pengganti cron lama), dan sejenisnya
  • Semakin sederhana sebuah layanan, semakin besar kemungkinan melakukan penyesuaian yang rinci

Checklist: kombinasi opsi keamanan yang direkomendasikan (prioritas awal penerapan)

  • ProtectSystem=strict
  • PrivateTmp=yes
  • ProtectHome=yes atau ProtectHome=tmpfs
  • ProtectClock=yes, ProtectKernelLogs=yes, ProtectKernelModules=yes
  • RestrictSUIDGUID=yes
  • UMask=0077
  • LockPersonality=yes
  • RestrictRealtime=yes
  • MemoryDenyWriteExecute=yes
  • DynamicUser=yes atau menetapkan User ke pengguna tertentu selain root
  • Butir-butir di atas umumnya adalah kombinasi yang dapat digunakan dengan hampir tanpa mengganggu layanan
  • Jika ingin menambahkan pemfilteran syscall (SystemCallFilter), diperlukan pengujian yang lebih rinci

Contoh konfigurasi Traefik

  • Ini adalah contoh menjalankan layanan Traefik berbasis kontainer dengan systemd quadlet, sambil menerapkan banyak opsi keamanan
    • Menerapkan ProtectSystem=full, ProtectHome=yes, SystemCallFilter=@system-service @mount @privileged, dan lainnya
    • Menghapus hak tertentu dengan CapabilityBoundingSet=~CAP_SETUID CAP_SETPCAP
    • Menerapkan pembatasan akses jaringan seperti RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK

Kesimpulan

  • Opsi hardening keamanan systemd adalah sarana praktis yang layak dimiliki dalam kotak alat administrator sistem keluarga Unix
  • Ini bukan solusi keamanan yang sempurna, melainkan alat untuk mengurangi risiko, dan tidak perlu menerapkan pengaturan keamanan secara sembarangan ke semua layanan
  • Terutama bagi administrator di lingkungan self-hosting, ini dapat sangat membantu meningkatkan tingkat keamanan
  • Dengan memprioritaskan “kepraktisan daripada kesempurnaan”, disarankan menerapkannya setidaknya sebagian dalam cakupan yang sesuai dengan pekerjaan dan lingkungan

1 komentar

 
GN⁺ 2025-08-20
Komentar Hacker News
  • Menurut saya menarik bahwa hardening layanan systemd yang terotomatisasi bisa diwujudkan lewat profiling strace
    https://github.com/desbma/shh

    • Saya menemukan cara yang bagus: meski ProtectSystem= tidak digunakan dalam contoh,
      dengan TemporaryFileSystem=/:ro, BindReadOnly=/usr/bin/binary /lib /lib64 /usr/lib usr/lib64
      Anda bisa menyertakan hanya biner yang diinginkan dan path yang ingin dibaca
      ProtectSystem= saat ini tidak kompatibel dengan perilaku ini
      Lihat detail lebih lanjut di sini

    • Saya rasa pendekatan ini bisa bermasalah untuk layanan yang memerlukan tindakan tambahan saat error, seperti mengirim email

  • Dibanding tulisan tentang hardening systemd yang diposting kemarin, yang ini jauh lebih realistis dan penuh tip bagus yang bisa langsung diterapkan
    Saya berusaha memberi contoh yang lebih praktis di komentar tulisan kemarin, tetapi tulisan hari ini merangkum hal-hal yang benar-benar berguna dengan sangat baik dan menunjukkan cara memperkuat isolasi serta keamanan dengan cepat dan mudah menggunakan systemd
    Menurut saya ini tulisan yang luar biasa
    Sebagai referensi, saya tinggalkan juga tulisan kemarin
    https://us.jlcarveth.dev/post/hardening-systemd.md
    https://news.ycombinator.com/item?id=44928504

    • Akan bagus kalau masalah sertifikat situsnya diperbaiki
      Di beberapa browser, situsnya bahkan tidak bisa diakses karena error sertifikat
  • Terima kasih sudah membagikannya
    Jika systemd-analyze digunakan bersama flag --user, Anda bisa memeriksa keamanan unit pengguna systemd (systemd-analyze --user security)
    Sejak memindahkan container ke Podman saya mulai lebih sering memakai systemd, dan alat ini akan sangat membantu meningkatkan keamanan layanan unit/container systemd

  • Skrip init lama dulu semuanya berbeda-beda, jadi hardening yang konsisten seperti ini tidak memungkinkan

    • Tentu saja hardening seperti ini juga bisa dilakukan dengan skrip init lama, tetapi systemd membantu memakai fitur-fitur kernel yang bagus dengan cara yang standar, konsisten, dan mudah
      Saya masuk ke Linux agak terlambat, jadi sulit membayangkan sistem tanpa systemd, dan sistem tanpa systemd terasa sangat tidak nyaman untuk dikelola
      Belakangan saya menemukan alat bernama unshare, jadi saya bisa bereksperimen seperti me-remount seluruh /nix sebagai RW tanpa memengaruhi proses lain
      Kegunaan systemd memang agak kasar di beberapa sisi, tetapi jujur bagi saya satu-satunya alternatif hanyalah Windows
  • Saya penasaran kenapa distro Linux tidak lebih banyak mengaktifkan switch keamanan seperti ini secara default
    Saya bertanya-tanya apakah ada kekurangan dalam hardening yang konservatif
    Bagi banyak pengguna, pengaturannya mungkin terlalu banyak dan terlalu rumit

    • Jika pengaturan diubah terlalu agresif, konfigurasi lama bisa rusak tanpa disengaja
      Misalnya, jika NetworkManager di-hardening, Anda harus memverifikasi satu per satu apakah IPv4 dan IPv6 tetap terhubung, apakah mode dns=systemd-resolved dan dns=default berfungsi normal, integrasi ModemManager dan seluler, plugin openvpn atau cisco anyconnect, hook NetworkManager-dispatcher, dan banyak bagian lainnya
      Masalah lainnya adalah seberapa banyak maintainer distro bisa yakin sampai titik mana mereka boleh mengubah switch pada paket yang mereka kelola tanpa merusak lebih dari 0,01% lingkungan pengguna
      Jika flag seperti ini dikelola distro, setiap rilis upstream akan membawa isu kompatibilitas tambahan; sebaliknya, jika diatur upstream, mereka tak punya banyak pilihan selain memakainya dengan lebih hati-hati demi kompatibilitas mundur

    • Pertanyaan ini mirip dengan "mengapa distro tidak menggunakan MAC (seperti SELinux) secara ketat secara default?"
      Membatasi hal seperti sshd lebih jauh memang bagus

      1. biaya pengembangan awal untuk menerapkannya
      2. biaya menangani bug report dari berbagai lingkungan pengguna
      3. biaya pemeliharaan berkelanjutan agar tetap selaras dengan perubahan distro/upstream
        Karena hal-hal ini, beban untuk distro besar cukup tinggi
        SELinux dan AppArmor juga sama; para maintainer sering menilai manfaatnya tidak sebanding dengan investasi yang dibutuhkan
    • Alasan besar lainnya adalah tidak adanya kemampuan atau sumber daya untuk melakukan integration test satu per satu terhadap perilaku normal layanan sistem inti untuk tiap parameter
      Diskusi terkait
      https://news.ycombinator.com/item?id=29995566
      Hasil systemd-analyze security juga berbeda antar distro
      desbma/shh secara otomatis menghasilkan rule per unit seperti SyscallFilter dari data yang dikumpulkan lewat strace, mirip audit2allow pada SELinux
      Namun, memasang strace di lingkungan produksi bisa menjadi hal yang diperdebatkan
      https://github.com/desbma/shh

    • Saya juga tidak terlalu tahu, tetapi beberapa pengaturan ini relatif baru, jadi banyak pengguna mungkin belum mengetahuinya
      Tidak semua orang adalah ahli systemd, dan jika pengaturan diaktifkan, ada risiko ia tidak berjalan normal pada versi systemd yang lebih lama
      Ada berbagai fitur seperti SELinux dan AppArmor, tetapi banyak distro, developer, dan pengguna tidak merasa itu benar-benar perlu, sehingga sulit untuk menerapkannya secara otomatis

  • Opsi untuk hardening terlalu banyak, jadi menurut saya akan bagus jika ada repositori yang mengumpulkan contoh hardening umum per layanan
    Pengguna sering memakai skrip hardening yang umum digunakan, tetapi kadang justru ditemukan bahwa izin perlu dibuat lebih longgar agar kasus pengecualian tidak menimbulkan masalah

    • Saat melakukan packaging di distro dengan dukungan upstream yang minim seperti nixpkgs,
      hal yang paling berguna adalah melihat bagaimana distro mainstream melakukan packaging dan hardening
      Karena metode hardening seperti itu biasanya sudah cukup teruji, jika Anda penasaran dengan contoh hardening seperti postgresql, ada baiknya mulai dari paket Debian, Ubuntu, atau RHEL
  • Salah satu fitur keamanan hebat yang disediakan systemd adalah manajemen credential
    Dengan ini, kredensial bisa diberikan ke aplikasi dengan lebih aman daripada menyimpannya di environment variable atau filesystem
    Di lingkungan tanpa Vault dan sejenisnya, misalnya proyek pribadi, saya selalu lebih memilih cara ini
    Saya bahkan membuat sendiri paket Go yang terintegrasi dengan fitur tersebut
    credentials di systemd
    paket credential-go

    • Rasanya seperti budaya nodejs atau npm yang membuat kode dua baris pun jadi paket
      Padahal sebenarnya hanya

      dir, err := os.Getenv("CREDENTIALS_DIRECTORY")
      cred, err := os.ReadFile(filepath.Join(dir, "name"))
      

      bahkan tidak lebih rumit daripada left-pad
      Setahu saya, di komunitas Go dulu dianggap baik untuk mengurangi dependensi dan menghindari abstraksi yang tidak perlu (seperti pemanggilan fungsi)
      Untuk perilaku sederhana seperti ini, orang-orang biasanya langsung menulisnya sendiri saat itu juga

    • Saya penasaran bagaimana cara mekanisme pengiriman credential ini mencegah kredensial diwariskan sampai ke proses anak hasil fork

  • Tulisan yang sangat berguna
    Saya juga suka daftar tiap opsi systemd dan saran seperti "lihat man page dan semoga beruntung"
    systemd memang sangat bagus dan saya ingin menerapkannya secara aktif di server saya

  • Tip kecil saja, penulisan yang benar untuk systemd di judul adalah systemd
    Yang benar adalah systemd, bukan SystemD, system D, atau system d
    Alasannya karena itu singkatan dari system daemon, jadi namanya diakhiri huruf d kecil sesuai tradisi Unix/Linux

    • Fakta yang menarik
      Saya biasanya lebih sering melihat orang menyebutnya systemD, jadi saya penasaran kenapa bentuk itu menjadi begitu umum
  • Tip untuk debugging isu syscall di systemd benar-benar sangat berguna