Mengapa Proses Dalam Wadah Docker Tidak Harus Berjalan sebagai Root

Diterbitkan: 2022-08-19

Grafik yang menunjukkan logo Docker

Proses dalam wadah Docker tidak boleh dijalankan sebagai root. Lebih aman untuk menjalankan aplikasi Anda sebagai pengguna non-root yang Anda tentukan sebagai bagian dari Dockerfile Anda atau saat menggunakan docker run . Ini meminimalkan risiko dengan menghadirkan permukaan serangan yang berkurang terhadap ancaman apa pun di wadah Anda.

Dalam artikel ini, Anda akan belajar tentang bahaya menjalankan aplikasi kemas sebagai root. Anda juga akan melihat cara membuat pengguna non-root dan mengatur penspasian nama dalam situasi yang tidak memungkinkan.

Mengapa Menjalankan sebagai Root Berbahaya?

Wadah dijalankan sebagai root secara default. Daemon Docker dijalankan sebagai root pada host Anda dan container yang berjalan juga akan menjadi root.

Meskipun kelihatannya root di dalam container adalah pengguna independen, sebenarnya sama dengan akun root di host Anda. Pemisahan hanya disediakan oleh mekanisme isolasi kontainer Docker. Tidak ada batas fisik yang kuat; proses lain penampung Anda dijalankan oleh pengguna root pada kernel host Anda. Ini berarti kerentanan dalam aplikasi Anda, runtime Docker, atau kernel Linux dapat memungkinkan penyerang keluar dari wadah dan melakukan operasi root-privilege pada mesin Anda.

Ada beberapa perlindungan bawaan yang mengurangi risiko terjadinya hal ini. Root di dalam wadah tidak memiliki hak istimewa dan memiliki kemampuan terbatas. Ini mencegah container menggunakan perintah administrasi sistem kecuali Anda menambahkan kemampuan secara manual atau menggunakan mode istimewa saat memulai container.

Terlepas dari mitigasi ini, membiarkan aplikasi berjalan sebagai root tetap menjadi bahaya. Sama seperti Anda akan membatasi penggunaan root di lingkungan tradisional, tidak bijaksana untuk menggunakannya secara tidak perlu di dalam wadah Anda. Anda menyediakan lingkungan yang sangat diistimewakan yang memberi penyerang lebih banyak pijakan jika terjadi pelanggaran.

Menjalankan Aplikasi dalam Kontainer sebagai Pengguna Non-Root

Ini adalah praktik terbaik untuk menjalankan aplikasi kemas sebagai pengguna biasa. Sebagian besar perangkat lunak tidak memerlukan akses root sehingga mengubah pengguna memberikan lapisan pertahanan langsung terhadap penembusan kontainer.

Anda harus membuat akun pengguna baru sebagai salah satu tahap akhir di Dockerfile Anda. Anda dapat mencapai ini dengan instruksi USER :

 DARI gambar dasar: terbaru
RUN apt install demo-package
PENGGUNA demo-pengguna: demo-grup
ENTRYPOINT ["biner demo"]

Penampung yang dimulai dari gambar ini akan dijalankan sebagai demo-user . Pengguna akan menjadi anggota grup demo-group grup. Anda dapat menghilangkan nama grup jika Anda tidak ingin pengguna berada dalam grup:

 PENGGUNA demo-pengguna

Anda dapat menentukan ID pengguna (UID) dan ID grup (GID) alih-alih nama:

 PENGGUNA 950:950

Mengalokasikan UID dan GID yang diketahui biasanya merupakan cara paling aman untuk melanjutkan. Ini mencegah pengguna dalam wadah dipetakan ke akun host yang memiliki hak istimewa.

USER sering ditentukan sebagai tahap kedua dari belakang dalam Dockerfile. Artinya Anda masih bisa menjalankan operasi yang membutuhkan root tadi di build image. Instruksi apt install pada contoh di atas memiliki kebutuhan yang sah untuk root. Jika instruksi USER ditempatkan di atasnya, apt akan dijalankan sebagai demo-user yang tidak memiliki izin yang diperlukan. Karena instruksi Dockerfile hanya berlaku untuk pembuatan gambar, bukan penampung yang dijalankan, aman untuk membiarkan pengguna diubah hingga nanti di Dockerfile Anda.

Mengubah pengguna yang dijalankan penampung Anda mungkin mengharuskan Anda memperbarui izin pada file dan folder yang diaksesnya. Tetapkan kepemilikan pada jalur apa pun yang akan digunakan oleh aplikasi Anda:

 SALIN initial-config.yaml /data/config.yaml

PENGGUNA demo-pengguna: demo-grup
JALANKAN pengguna demo chown: grup demo / data

Dalam contoh ini direktori /data harus dimiliki oleh demo-user agar aplikasi dapat membuat perubahan pada file konfigurasinya. Pernyataan COPY sebelumnya akan menyalin file sebagai root. Singkatan tersedia dengan menggunakan flag --chown dengan copy :

 SALIN --chown=demo-user:demo-group initial-config.yaml /data/config.yaml

Mengubah Pengguna Saat Memulai Kontainer

Meskipun Anda dapat dengan mudah mengubah pengguna di Dockerfile Anda sendiri, banyak aplikasi pihak ketiga terus berjalan sebagai root. Anda dapat mengurangi risiko yang terkait dengan penggunaan ini dengan menyetel flag --user setiap kali Anda memanggil docker run . Ini menimpa set pengguna di Dockerfile gambar.

 $ docker run -d --user demo-user:demo-group demo-image:latest
$ docker run -d --user demo-user demo-image:latest
$ docker run -d --user 950:950 demo-image:latest

Bendera --user menjalankan proses penampung sebagai pengguna yang ditentukan. Ini kurang aman daripada instruksi Dockerfile USER karena Anda harus menerapkannya satu per satu ke setiap perintah docker run . Pilihan yang lebih baik untuk gambar yang biasa digunakan adalah membuat gambar turunan Anda sendiri yang dapat mengatur akun pengguna baru:

 DARI gambar-yang-berjalan-sebagai-root: terbaru
PENGGUNA demo-pengguna
 $ membangun buruh pelabuhan. -t gambar-yang-sekarang-berjalan-sebagai-non-root: terbaru

Mengubah pengguna gambar pihak ketiga dapat menyebabkan masalah: jika wadah diharapkan dijalankan sebagai root, atau perlu mengakses jalur sistem file yang dimiliki oleh root, Anda akan melihat kesalahan saat menggunakan aplikasi. Anda dapat mencoba mengubah izin secara manual di jalur yang menyebabkan masalah. Atau, periksa apakah vendor memiliki metode yang didukung untuk menjalankan aplikasi dengan akun pengguna yang tidak memiliki hak istimewa.

Menangani Aplikasi yang Harus Dijalankan sebagai Root

Penspasian nama pengguna adalah teknik untuk menangani aplikasi yang memerlukan beberapa hak akses root. Ini memungkinkan Anda memetakan root di dalam wadah ke pengguna non-root di host Anda. Root yang disimulasikan di dalam container memiliki hak istimewa yang dibutuhkan, tetapi breakout tidak akan memberikan akses root ke host.

Pemetaan ulang namespace diaktifkan dengan menambahkan bidang userns-remap ke file /etc/docker/daemon.json Anda:

 {
    "userns-remap": "default"
}

Menggunakan default sebagai nilai untuk userns-remap menginstruksikan Docker untuk secara otomatis membuat pengguna baru di host Anda yang disebut dockremap . Root di dalam container akan dipetakan kembali ke dockremap di host Anda. Anda dapat secara opsional menentukan pengguna dan grup yang ada, menggunakan kombinasi UID/GID atau nama pengguna/nama grup:

 {
    "userns-remap": "pengguna demo"
}

Mulai ulang daemon Docker setelah menerapkan perubahan Anda:

 $ sudo service docker restart

Jika Anda menggunakan nsuser-remap: default , pengguna dockremap sekarang harus ada di Host Anda:

 $id dockremap

uid=140(dockremap) gid=119(dockremap) grup=119(dockremap)

Pengguna juga harus muncul di file ID bawahan /etc/subuid dan /etc/subgid :

 $ dockremap:231500:65535

Pengguna telah dialokasikan rentang 65.535 ID bawahan mulai dari 231500. Di dalam ruang nama pengguna, ID 231500 dipetakan ke 0 , menjadikannya pengguna root di wadah Anda. Menjadi UID bernomor tinggi, 231500 tidak memiliki hak istimewa pada host sehingga serangan breakout kontainer tidak akan dapat menimbulkan begitu banyak kerusakan.

Semua wadah yang Anda mulai akan dijalankan menggunakan ruang nama pengguna yang dipetakan ulang kecuali Anda memilih keluar dengan docker run --userns=host . Mekanisme ini bekerja dengan membuat direktori dengan namespace di dalam /var/lib/docker yang dimiliki oleh UID dan GID bawahan dari pengguna dengan namespace:

 $ sudo ls -l /var/lib/docker/231500.231500

jumlah 14
drwx------ 5 231500 231500 13 Jul 22 19:00 aufs
drwx------ 3 231500 231500 13 Jul 22 19:00 kontainer
...

Penspasian nama pengguna adalah cara yang efektif untuk meningkatkan isolasi container, menghindari breakout, dan menjaga kompatibilitas dengan aplikasi yang membutuhkan hak akses root. Namun ada beberapa pengorbanan: fitur ini berfungsi paling baik pada instance Docker baru, volume yang dipasang dari Host harus memiliki izin yang disesuaikan, dan beberapa driver penyimpanan eksternal tidak mendukung pemetaan pengguna sama sekali. Anda harus meninjau dokumentasi sebelum mengadopsi opsi ini.

Ringkasan

Menjalankan aplikasi kemas sebagai root adalah risiko keamanan. Meskipun mudah diabaikan, isolasi yang disediakan oleh container tidak cukup kuat untuk memisahkan pengguna kernel sepenuhnya dari pengguna container. Root dalam wadah sama dengan root pada host Anda sehingga kompromi yang berhasil dapat memberikan kendali atas mesin Anda.

Sebagai pembuat gambar, Anda harus menyertakan instruksi USER di Dockerfile Anda sehingga aplikasi Anda berjalan tanpa root. Pengguna gambar dapat mengganti ini dengan docker run --user untuk menetapkan UID dan GID tertentu. Ini membantu mengurangi kasus di mana gambar biasanya menggunakan root.

Anda dapat lebih memperketat keamanan dengan menghapus semua kemampuan dari wadah menggunakan --cap-drop=ALL , lalu memasukkannya ke daftar putih yang diperlukan dengan --cap-add . Menggabungkan teknik-teknik ini akan menjalankan aplikasi Anda sebagai pengguna non-root dengan set hak minimum yang diperlukan, meningkatkan postur keamanan Anda.