Docker

Rootless Docker: Jalankan Container Tanpa Akses Root untuk Keamanan Ekstra

Rootless Docker: Jalankan Container Tanpa Akses Root untuk Keamanan Ekstra

Bayangkan skenario ini: sebuah container di server production berhasil ditembus attacker karena image yang dipakai ternyata punya celah. Dengan setup Docker biasa, container itu berjalan dengan hak akses root — artinya attacker yang berhasil masuk langsung punya akses root ke host. Ini salah satu alasan kenapa rootless container semakin populer di kalangan developer dan sysadmin yang peduli keamanan.

Artikel ini membahas apa itu Rootless Docker, bagaimana cara kerjanya, kelebihan dan kekurangannya, serta panduan setup langkah demi langkah di Ubuntu. Artikel ini juga membandingkannya dengan Podman yang memang dirancang rootless sejak awal.

Apa Itu Rootless Docker

Rootless Docker adalah mode menjalankan Docker daemon dan container tanpa hak akses root (UID 0). Dalam mode ini, seluruh komponen Docker — dockerd, containerd, runc, dan container itu sendiri — berjalan sebagai user non-privileged di host.

Konsep kunci di baliknya adalah user namespace remapping. Docker memetakan UID di dalam container ke UID non-privileged di host. Jadi meskipun proses di dalam container mengaku sebagai root (UID 0), di level host proses itu sebenarnya berjalan sebagai user biasa dengan UID tertentu seperti 100000 atau 165536.

Kalau attacker berhasil escape dari container, yang dia dapatkan bukan root host, melainkan akses user biasa. Dampak serangan langsung berkurang drastis — ini alasan utama mode ini digadang-gadang sebagai lompatan besar keamanan container dibanding Docker klasik.

Perbedaan dengan Docker Klasik

Berikut perbandingan utama antara Docker klasik (rootful) dan Rootless Docker:

  • Privilege daemon. Docker klasik menjalankan daemon sebagai root; rootless menjalankan daemon sebagai user biasa. Ini menghilangkan banyak permukaan serangan pada daemon itu sendiri.
  • User namespace. Rootless memakai user namespace secara default, memetakan root di dalam container ke user non-root di host.
  • Socket ownership. Socket Docker di mode rootless dimiliki user, bukan root — tidak perlu grup docker yang praktis setara root.
  • Volume dan mount. Rootless tidak bisa mengakses volume atau bind mount dari path yang tidak bisa dibaca user tersebut.
  • Port binding. Port di bawah 1024 (seperti 80 dan 443) tidak bisa langsung di-bind tanpa bantuan eksternal.
  • Networking. Mode rootless memakai jaringan userland (slirp4netns) secara default, bukan bridge iptables langsung.

Perbedaan-perbedaan ini penting dipahami sebelum memutuskan migrasi, karena beberapa aplikasi yang bergantung pada kemampuan rootful akan butuh penyesuaian.

Panduan Setup di Ubuntu

Setup Rootless Docker di Ubuntu relatif mudah. Pertama, pastikan dependensi terinstall:

sudo apt update
sudo apt install -y uidmap dbus-user-session slirp4netns

Paket uidmap menyediakan newuidmap dan newgidmap yang dibutuhkan untuk user namespace. slirp4netns digunakan untuk jaringan userland. Setelah itu, install Docker Engine dengan cara biasa (paket docker-ce), lalu jalankan skrip rootless:

dockerd-rootless-setuptool.sh install

Skrip ini akan membuat service systemd user (docker.service di bawah systemctl --user) dan mengonfigurasi environment yang dibutuhkan. Aktifkan service agar jalan otomatis saat login:

systemctl --user enable docker
systemctl --user start docker

Supaya service systemd user tetap berjalan tanpa sesi login aktif, aktifkan lingering:

sudo loginctl enable-linger $(whoami)

Setelah itu, set variabel environment DOCKER_HOST agar perintah docker mengarah ke socket rootless:

export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock

Verifikasi bahwa daemon berjalan tanpa root:

docker info --format '{{.SecurityOptions}}'

Output harus mengandung name=rootless atau name=userns, menandakan mode rootless aktif.

Limitasi yang Perlu Diketahui

Rootless Docker bukan solusi tanpa kompromi. Beberapa limitasi yang umum ditemui:

  • Bind mount terbatas. Container hanya bisa mengakses direktori yang bisa dibaca user yang menjalankan daemon. Path di luar home sering kali bermasalah.
  • Port rendah. Binding port 80 atau 443 butuh redirect dari root, misalnya lewat authbind atau reverse proxy.
  • Jaringan. Mode userland networking punya overhead latency lebih tinggi dibanding bridge langsung, dan tidak mendukung semua fitur jaringan host.
  • Overlay fs. Beberapa distribusi butuh konfigurasi tambahan agar storage driver overlay2 berjalan di user namespace.
  • Fitur tertentu. Fitur seperti --privileged sebagian besar kehilangan maknanya, dan tidak semua plugin networking berfungsi.

Untuk workload yang butuh port 80/443 langsung dan volume di lokasi sistem, pendekatan yang umum dipakai adalah menjalankan reverse proxy (seperti Nginx atau Caddy) sebagai service root, lalu container rootless di belakangnya.

Rootless Docker vs Podman

Podman sering disebut sebagai alternatif yang dirancang rootless sejak awal. Perbandingannya:

  • Arsitektur. Podman tidak memakai daemon terpusat — tiap container dikelola langsung oleh proses podman, sehingga tidak ada daemon root yang bisa diserang.
  • Kompatibilitas CLI. Podman dirancang agar perintahnya mirip Docker, memudahkan migrasi tanpa mengubah workflow.
  • User namespace. Podman memakai user namespace secara default untuk mode rootless, mirip konsep Rootless Docker.
  • Kematangan. Rootless Docker sudah matang dan didukung penuh oleh Docker Inc; Podman lebih populer di ekosistem Red Hat dan Fedora.
  • Compose. Docker Compose v2 mendukung mode rootless; Podman punya podman-compose yang kompatibilitasnya tidak selalu sempurna.

Pilihan antara keduanya lebih banyak ditentukan oleh ekosistem yang sudah dipakai tim daripada perbedaan teknis yang drastis. Keduanya layak dipakai untuk mengurangi permukaan serangan di server.

Praktik Terbaik

Beberapa praktik yang baik diterapkan saat memakai Rootless Docker:

  • Gunakan image yang sudah discan. Rootless mengurangi dampak escape, tapi image yang kotor tetap bahaya. Kombinasikan dengan scanner seperti Trivy.
  • Jalankan reverse proxy di luar rootless. Untuk layanan publik, letakkan Nginx/Caddy sebagai entry point, container rootless di belakang.
  • Batasi resource. Tetap set --memory dan --cpus di tiap container agar satu container tidak menguras host.
  • Update rutin. User namespace dan slirp4netns punya celah yang pernah ditemukan; pastikan versi kernel dan paket selalu terbaru.
  • Backup state. Volume rootless tersimpan di path user; pastikan ikut ter-backup bersama konfigurasi.

Troubleshooting Umum

Beberapa masalah yang sering muncul saat pertama kali memakai Rootless Docker beserta solusinya:

  • Socket tidak ditemukan. Error Cannot connect to the Docker daemon biasanya berarti DOCKER_HOST belum di-set atau service belum jalan. Cek dengan systemctl --user status docker dan pastikan export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock ada di shell profile.
  • Permission denied pada bind mount. Rootless container berjalan sebagai user non-root di host, jadi path yang di-mount harus bisa diakses user tersebut. Solusinya: letakkan data di dalam home user atau samakan UID container dengan UID user.
  • Network lambat. Mode slirp4netns punya overhead. Untuk performa lebih baik, aktifkan --network=host kalau workload tidak butuh isolasi jaringan, atau pertimbangkan driver pasta (passt) yang lebih baru dan lebih cepat.
  • Image tidak bisa pull. Pastikan XDG_RUNTIME_DIR ter-set dengan benar dan proxy (kalau ada) dikonfigurasi di ~/.docker/config.json.
  • Port 80/443 tidak bisa bind. Gunakan reverse proxy root (Nginx/Caddy) yang meneruskan ke container rootless, atau set net.ipv4.ip_unprivileged_port_start=80 di sysctl kalau lingkungan mengizinkan.

Sebagian besar error Rootless Docker berakar dari satu hal: perbedaan privilege antara mode rootful dan rootless. Membaca pesan error dengan teliti — terutama bagian yang menyebut user namespace atau permission — biasanya langsung mengarahkan ke solusi yang tepat.

Kinerja dan Trade-off

Pertanyaan yang sering muncul: apakah Rootless Docker lebih lambat? Jawabannya tergantung workload. Untuk beban I/O disk dan jaringan yang tinggi, overhead user namespace dan slirp4netns memang terasa — benchmark menunjukkan penurunan throughput jaringan sekitar 10-30% pada mode userland dibanding bridge langsung. Untuk beban CPU-bound murni, perbedaannya hampir tidak terlihat karena user namespace tidak menambah biaya komputasi yang signifikan.

Penurunan performa ini perlu ditimbang dengan peningkatan keamanan yang didapat. Untuk aplikasi web biasa — yang trafiknya lewat reverse proxy dan datanya disimpan di volume — overhead tersebut biasanya tidak menjadi bottleneck. Ukur dulu dengan beban nyata: jalankan benchmark sederhana seperti ab atau hey terhadap layanan di mode rootful vs rootless, lalu putuskan berdasarkan angka, bukan asumsi.

Kalau performa jaringan menjadi masalah serius, kombinasi yang umum dipakai adalah: tetap memakai Docker rootful untuk workload yang butuh performa jaringan maksimal di jaringan internal yang terpercaya, dan Rootless Docker untuk layanan yang terekspos ke internet. Segmentasi ini memberi keseimbangan antara keamanan dan performa.

Kesimpulan

Rootless Docker adalah langkah keamanan yang signifikan untuk server yang menjalankan workload container, terutama yang terekspos ke internet. Dengan user namespace, dampak serangan yang berhasil menembus container bisa ditekan drastis.

Memang ada limitasi — port rendah, bind mount, dan overhead jaringan — tapi untuk sebagian besar workload aplikasi web, kompromi ini sepadan dengan peningkatan keamanan. Dimulai dari uji coba di staging, lalu migrasi bertahap, adalah jalur yang paling aman untuk mengadopsi mode rootless di production.

💬 Komentar (0)

Belum ada komentar. Jadilah yang pertama! 💬

Komentar akan muncul setelah moderasi.