
Kontainer Docker adalah teknologi containerisasi paling populer. Awalnya, ini digunakan terutama untuk lingkungan dev dan pengujian, dan seiring waktu beralih ke produksi. Wadah Docker mulai berkembang biak di lingkungan produksi, seperti jamur setelah hujan, tetapi sedikit yang menggunakan teknologi ini telah memikirkan cara menerbitkan wadah Docker dengan aman.
Berdasarkan
OWASP , kami telah menyiapkan daftar aturan, yang implementasinya akan secara signifikan melindungi lingkungan Anda, dibangun di atas wadah Docker.
Aturan 0
Mesin host dan Docker harus berisi semua pembaruan saat ini.
Untuk melindungi dari kerentanan yang diketahui yang menyebabkan pelarian dari lingkungan kontainer ke sistem host, yang biasanya menghasilkan eskalasi hak istimewa pada sistem host, menginstal semua patch untuk OS host, Docker Engine, dan Docker Machine sangat penting.
Selain itu, kontainer (tidak seperti mesin virtual) membagikan kernel dengan host, sehingga exploit kernel yang berjalan di dalam container berjalan langsung di kernel host. Sebagai contoh, eksploitasi eskalasi hak istimewa kernel (seperti Dirty COW) yang berjalan di dalam wadah yang terisolasi akan menghasilkan akses root pada host.
Aturan 1
Jangan memberikan akses ke soket daemon Docker
Layanan Docker (daemon) menggunakan soket UNIX /var/run/docker.sock untuk koneksi API yang masuk.
Pemilik sumber ini harus menjadi pengguna root. Dan tidak ada cara lain. Mengubah hak akses ke soket ini pada dasarnya sama dengan memberikan akses root ke sistem host.
Selain itu, Anda tidak boleh meraba-raba soket /var/run/docker.sock dengan wadah, di mana Anda dapat melakukannya tanpa itu, karena dalam hal ini, mengkompromikan layanan dalam wadah akan menyebabkan kontrol penuh atas sistem host. Jika Anda memiliki wadah yang menggunakan sesuatu seperti ini:
-v /var/run/docker.sock://var/run/docker.sock
atau untuk komposisi buruh pelabuhan:
volumes: - "/var/run/docker.sock:/var/run/docker.sock"
kebutuhan mendesak untuk mengubah ini.
Dan yang terakhir - tidak pernah, dengar,
tidak pernah menggunakan soket TCP Docker tanpa kepastian mutlak bahwa Anda memerlukannya, terutama tanpa menggunakan metode perlindungan tambahan (setidaknya otorisasi). Secara default, soket Docker TCP membuka port pada antarmuka eksternal 0.0.0.0:23.275 (2376, dalam hal HTTP) dan memungkinkan kontrol penuh wadah, dan dengan itu sistem host potensial.
Aturan 2
Konfigurasikan pengguna yang tidak berhak di dalam wadah
Mengkonfigurasi wadah untuk menggunakan pengguna yang tidak memiliki hak adalah cara terbaik untuk menghindari serangan eskalasi hak istimewa. Ini dapat dilakukan dengan berbagai cara:
1. Menggunakan opsi "-u" dari perintah "docker run":
docker run -u 4000 alpine
2. Selama pembuatan gambar:
FROM alpine RUN groupadd -r myuser && useradd -r -g myuser myuser < root-, , > USER myuser
3. Aktifkan dukungan untuk "ruang nama pengguna" (lingkungan pengguna) di daemon Docker:
--userns-remap=default
Baca lebih lanjut tentang ini di
dokumentasi resmi .
Di Kubernetes, yang terakhir dikonfigurasi dalam
Konteks Keamanan melalui opsi runAsNonRoot:
kind: ... apiVersion: ... metadata: name: ... spec: ... containers: - name: ... image: .... securityContext: ... runAsNonRoot: true ...
Aturan 3
Batasi kemampuan kontainer
Di Linux, dimulai dengan kernel 2.2, ada cara untuk mengontrol kapabilitas proses istimewa yang disebut
Linux Kernel Capabilities (untuk detail, lihat tautan).
Docker menggunakan set fitur-fitur kernel yang sudah ditentukan sebelumnya secara default. Dan itu memungkinkan Anda untuk mengubah set ini menggunakan perintah:
--cap-drop — --cap-add —
Pengaturan keamanan terbaik adalah pertama-tama menonaktifkan semua fitur (--cap-drop semua), dan kemudian sambungkan hanya yang diperlukan. Misalnya, seperti ini:
docker run --cap-drop all --cap-add CHOWN alpine
Dan yang paling penting (!): Hindari menjalankan kontainer dengan flag –privileged !!!
Di Kubernetes, batasan Kemampuan Kernel Linux dikonfigurasikan dalam Konteks Keamanan melalui opsi kemampuan:
kind: ... apiVersion: ... metadata: name: ... spec: ... containers: - name: ... image: .... securityContext: ... capabilities: drop: - all add: - CHOWN ...
Aturan 4
Gunakan bendera no-new-privilege
Saat memulai sebuah wadah, berguna untuk menggunakan flag --security-opt = no-new-privilege yang mencegah peningkatan privilege di dalam wadah.
Di Kubernetes, batasan Kemampuan Kernel Linux dikonfigurasikan dalam Konteks Keamanan melalui opsi allowPrivilegeEscalation:
kind: ... apiVersion: ... metadata: name: ... spec: ... containers: - name: ... image: .... securityContext: ... allowPrivilegeEscalation: false ...
Aturan 5
Matikan komunikasi antar wadah
Secara default, komunikasi antar wadah diaktifkan di Docker, yang berarti bahwa semua kontainer dapat berkomunikasi satu sama lain (menggunakan jaringan docker0). Fitur ini dapat dinonaktifkan dengan menjalankan layanan Docker dengan –icc = false flag.
Aturan 6
Gunakan Modul Keamanan Linux (Modul Keamanan Linux - seccomp, AppArmor, SELinux)
Secara default, Docker sudah menggunakan profil untuk modul keamanan Linux. Karena itu,
jangan pernah menonaktifkan profil keamanan! Maksimal yang bisa dilakukan dengan mereka adalah memperketat aturan.
Profil default untuk seccomp tersedia di
sini .
Docker juga menggunakan AppArmor untuk perlindungan, dan Docker Engine sendiri menghasilkan profil default untuk AppArmor saat wadah mulai. Dengan kata lain, alih-alih:
$ docker run --rm -it hello-world
mulai:
$ docker run --rm -it --security-opt apparmor=docker-default hello-world
Dokumentasi juga memberikan contoh profil AppArmor untuk nginx, yang sangat mungkin (perlu!) Untuk menggunakan:
Aturan 7
Batasi sumber daya kontainer
Aturan ini cukup sederhana: untuk mencegah kontainer melahap semua sumber daya server selama serangan DoS / DDoS berikutnya, kita dapat menetapkan batas penggunaan memori untuk setiap kontainer secara individual. Anda dapat membatasi: jumlah memori, CPU, jumlah kontainer restart.
Jadi mari kita mulai.
MemoriOpsi -m atau --memoryJumlah maksimum memori yang bisa digunakan wadah. Nilai minimum adalah 4m (4 megabita).
Opsi - memori-swapOpsi untuk mengkonfigurasi swap (swap file). Dikonfigurasi secara licik:
- Jika --memory-swap> 0, maka flag -memory juga harus diatur. Dalam hal ini, pertukaran memori menunjukkan berapa banyak total memori yang tersedia untuk wadah bersama dengan pertukaran.
- Contoh yang lebih sederhana. Jika --memory = "300m", dan --memory-swap = "1g", maka kontainer dapat menggunakan 300MB memori dan 700MB swap (1g - 300m).
- Jika - memori-swap = 0, pengaturan diabaikan.
- Jika --memory-swap diatur ke nilai yang sama dengan --memory, maka kontainer tidak akan memiliki swap.
- Jika - memori-swap tidak ditentukan, tetapi - memori ditentukan, maka jumlah swap akan sama dengan dua kali jumlah memori yang ditentukan. Misalnya, jika --memory = "300m", dan --memory-swap tidak disetel, wadah akan menggunakan memori 300MB dan 600MB swap.
- Jika --memory-swap = -1, maka wadah akan menggunakan semua swap yang dimungkinkan pada sistem host.
Catatan untuk nyonya rumah: utilitas gratis yang diluncurkan di dalam wadah tidak menunjukkan nilai nyata dari pertukaran yang tersedia untuk wadah, tetapi jumlah pertukaran tuan rumah.
Opsi --oom-kill-disableMemungkinkan Anda untuk mengaktifkan atau menonaktifkan pembunuh OOM (Kehabisan memori).
Perhatian! Anda dapat mematikan OOM Killer hanya dengan opsi --memory yang diatur, jika tidak, dengan kehabisan memori di dalam wadah, kernel akan mulai mematikan proses sistem host.
Opsi konfigurasi manajemen memori lain, seperti - memori-swappiness, - memori-reservasi, dan - memori-kernel, lebih untuk menyesuaikan kinerja wadah.
CPUOpsi --cpusOpsi mengatur berapa banyak sumber daya prosesor yang tersedia yang dapat digunakan wadah. Sebagai contoh, jika kita memiliki host dengan dua CPU dan kita mengatur --cpus = "1,5", maka wadah dijamin menggunakan satu setengah prosesor.
Opsi --cpuset-cpusMengkonfigurasi penggunaan core atau CPU tertentu. Nilai dapat ditentukan dengan tanda hubung atau koma. Dalam kasus pertama, kisaran core yang diizinkan akan ditunjukkan, pada core spesifik kedua.
Jumlah kontainer restart --restart=on-failure:<number_of_restarts>
Pengaturan ini menetapkan berapa kali Docker akan mencoba memulai ulang wadah jika tiba-tiba macet. Penghitung diatur ulang jika kondisi wadah telah berubah menjadi berjalan.
Dianjurkan untuk menetapkan angka positif kecil, misalnya, 5, yang akan menghindari memulai kembali layanan yang tidak bekerja tanpa henti.
Aturan 8
Gunakan sistem file dan volume read-only
Jika wadah tidak boleh menulis apa pun di suatu tempat, maka Anda harus menggunakan sistem file read-only sebanyak mungkin. Ini akan sangat mempersulit kehidupan penyusup potensial.
Contoh memulai wadah dengan sistem file read-only:
docker run --read-only alpine
Contoh menghubungkan volume dalam mode hanya baca:
docker run -v volume-name:/path/in/container:ro alpine
Aturan 9
Gunakan alat analisis keamanan wadah
Alat harus digunakan untuk mendeteksi wadah dengan kerentanan yang diketahui. Belum banyak dari mereka, tetapi mereka adalah:
• Gratis:
• Komersial:
Dan untuk Kubernetes, ada alat untuk mendeteksi kesalahan konfigurasi: