Menjalankan Service sebagai User Tanpa Hak Istimewa
Service yang berjalan sebagai root dapat mengubah seluruh server saat diretas. Gunakan akun sistem terpisah untuk tiap service, atau systemd dengan DynamicUser.
Mengapa tidak menjalankan semuanya sebagai root
root dapat melakukan apa saja pada mesin: membaca setiap file, mengubah pengaturan apa pun, dan menghapus seluruh sistem. Saat menjalankan service sebagai root, Anda memberikan seluruh kewenangan tersebut kepada service itu. Jika service memiliki bug yang dapat dieksploitasi penyerang, penyerang tidak hanya mendapatkan akses ke service, tetapi juga akses root, yang berarti seluruh server. Menjalankan service sebagai pengguna tanpa hak istimewa membatasi dampaknya. Bug pada service yang berjalan dengan akun terbatas hanya memberi penyerang akses ke hal-hal yang dapat disentuh akun tersebut, yang seharusnya hampir tidak ada.
Ini adalah prinsip hak akses minimum: berikan setiap bagian sistem akses yang benar-benar diperlukan untuk menjalankan tugasnya, dan tidak lebih. Prinsip ini merupakan kebiasaan paling efektif untuk membatasi dampak kompromi. Pada server modern, penerapannya hampir tidak menimbulkan biaya.
Akun khusus untuk setiap service
Pendekatan klasik adalah membuat user sistem terpisah untuk setiap service. User tersebut hanya memiliki file milik service itu dan tidak dapat login. Akun sistem untuk aplikasi web dapat dibuat seperti berikut:
sudo useradd --system --no-create-home --shell /usr/sbin/nologin appsvcSetiap flag memiliki fungsi. --system menjadikannya akun service, bukan akun untuk login manusia. --no-create-home melewati pembuatan direktori home yang tidak diperlukan. --shell /usr/sbin/nologin berarti, meskipun attacker berhasil mendapatkan akun tersebut, mereka tidak dapat membuka shell dengan akun itu. Akun ini hanya digunakan untuk memiliki suatu proses beserta file-nya.
Selanjutnya, berikan user tersebut hanya file yang diperlukan, tanpa akses tambahan:
sudo chown -R appsvc:appsvc /opt/myappKini service dapat membaca dan menulis pada direktorinya sendiri, tetapi tidak memiliki akses ke lokasi lain pada disk. Jika service tersebut berhasil dieksploitasi, file yang dapat diubah attacker terbatas pada /opt/myapp. Akun tersebut tetap dapat membaca file yang dapat dibaca semua user, tetapi tidak dapat mengubah bagian sistem lainnya.
Biarkan systemd menjalankannya sebagai pengguna tersebut
Setelah akun tersedia, konfigurasikan systemd agar menjalankan service dengan akun tersebut. Tambahkan satu baris berikut ke file unit:
[Service]
ExecStart=/opt/myapp/bin/server
User=appsvc
Group=appsvcUser=appsvc berarti proses dimulai dengan hak akses terbatas milik akun tersebut, bukan dengan hak akses root. Ini adalah cara standar untuk menjalankan aplikasi di bawah systemd, dan sebaiknya diterapkan pada setiap service yang unit-nya Anda tulis. Penurunan hak akses tidak akan membantu jika systemd memantau proses yang salah. Jika unit masih melaporkan status aktif setelah daemon berhenti tanpa pesan, periksa apakah Anda telah memilih Type= yang tepat sesuai cara proses Anda dimulai.
Atau lewati akun sepenuhnya dengan DynamicUser
systemd dapat melangkah lebih jauh dan membuat pengguna sementara untuk Anda, yang hanya ada selama service berjalan. Tetapkan DynamicUser=yes dan Anda tidak perlu mengelola akun sama sekali:
[Service]
ExecStart=/opt/myapp/bin/server
DynamicUser=yes
StateDirectory=myappSaat start, systemd mengalokasikan user ID yang belum digunakan. Saat stop, systemd melepaskannya. Service juga mendapatkan /tmp privat, tampilan filesystem yang sebagian besar bersifat read-only, serta direktori state yang dapat ditulisi di bawah /var/lib/myapp, yang disiapkan dan diserahkan kepadanya oleh StateDirectory=. Hal seperti ini tidak dapat dilakukan pada SysV init. Saat itu, penurunan hak akses diserahkan kepada apa pun yang dilakukan oleh start script milik setiap service. Kesenjangan tersebut menjadi salah satu alasan utama distribusi beralih ke systemd sejak awal. Untuk service mandiri yang hanya memerlukan direktori state miliknya sendiri, DynamicUser=yes adalah cara dengan upaya paling kecil untuk memperoleh isolasi yang kuat. Tidak ada akun jangka panjang yang dapat menjadi sasaran penyerang. Menulis unit secara manual cukup merepotkan, dan sebagian besar manfaatnya terletak pada penerapan direktif hardening yang benar. Generator dalam panduan service dan timer systemd dapat mengisi opsi tersebut untuk Anda, sehingga unit sudah benar sejak awal.
Kesesuaian dengan bagian lain
Least privilege adalah salah satu lapisan keamanan. Lapisan ini bekerja bersama lapisan lain, bukan menggantikannya. Firewall default-deny mengatur koneksi yang dapat mencapai service. Menjalankan service sebagai pengguna tanpa hak istimewa membatasi tindakan yang dapat dilakukan service jika server mengalami breach. SSH yang diperkuat mencegah penyerang masuk ke server sejak awal. Tidak satu pun dari langkah ini yang cukup jika diterapkan sendiri. Jika diterapkan bersama, bug pada satu service tidak langsung menyebabkan seluruh server mengalami kompromi. Hosting sesuatu yang melindungi secret menunjukkan batas lapisan ini: akun terbatas membatasi hal-hal yang dapat disentuh oleh proses yang mengalami breach, tetapi password manager yang di-host sendiri seperti Vaultwarden tetap bergantung pada cara Anda melindungi admin token dan file backup-nya. Isolasi pengguna tidak mencakup keduanya.
Sebelum melanjutkan, tinjau checklist hardening untuk seluruh server dan buat salinan yang dipersonalisasi sebagai dasar pekerjaan Anda:
FAQ
Mengapa saya tidak boleh menjalankan service sebagai root?
Karena root dapat melakukan apa pun pada mesin, service yang berjalan sebagai root dan berhasil dieksploitasi akan memberikan seluruh server kepada penyerang, bukan hanya service tersebut. Menjalankan service sebagai akun terbatas tanpa hak istimewa membatasi dampak pada hal-hal yang dapat diakses akun itu. Gunakan root hanya untuk administrasi, dan jalankan setiap service yang berjalan lama sebagai pengguna terbatas.
Bagaimana cara membuat pengguna yang tidak dapat login?
Jalankan sudo useradd --system --no-create-home --shell /usr/sbin/nologin NAME. Shell nologin berarti akun tersebut tidak dapat membuka sesi interaktif meskipun kredensialnya dicuri, --system menandainya sebagai akun service, dan --no-create-home melewati pembuatan direktori home yang tidak diperlukan. Berikan kepemilikan hanya atas file miliknya sendiri dengan chown.
Apa itu systemd DynamicUser?
DynamicUser=yes memberi tahu systemd untuk membuat pengguna sementara bagi service yang hanya ada selama service berjalan, sehingga Anda tidak perlu mengelola akun jangka panjang. Fitur ini juga memberikan /tmp privat, tampilan filesystem yang sebagian besar hanya-baca, dan direktori state yang dikelola. Ini adalah cara dengan upaya paling kecil untuk menjalankan service mandiri menggunakan identitas sementara dengan hak istimewa rendah.
Apakah menjalankan service sebagai pengguna non-root menggantikan firewall?
Tidak. Keduanya melindungi hal yang berbeda. Menjalankan service sebagai pengguna tanpa hak istimewa membatasi tindakan yang dapat dilakukan service jika berhasil dibobol, sedangkan firewall membatasi hal-hal yang dapat menjangkau service tersebut. Gunakan keduanya bersama SSH yang diperkuat agar setiap lapisan menutupi hal-hal yang tidak dapat ditangani lapisan lainnya.
File apa yang harus dimiliki pengguna service?
Hanya file yang benar-benar diperlukan service, dan tidak lebih. Berikan akun tersebut kepemilikan atas direktori kerja dan datanya sendiri, lalu biarkan semua yang lain dimiliki oleh root. Pola yang baik adalah sudo chown -R svc-app:svc-app /opt/svc-app untuk direktori aplikasi, sedangkan konfigurasi di bawah /etc tetap dimiliki oleh root dan hanya dapat dibaca oleh service. Tujuannya adalah memastikan bahwa jika proses tersebut dibobol, file yang dapat diubahnya terbatas pada datanya sendiri, bukan bagian lain dari sistem.