- Informasi tentang semua proses, bahkan tentang yang berumur pendek, harus dicatat.
- Kami harus memiliki informasi tentang jalur lengkap ke file yang dapat dieksekusi untuk semua proses yang berjalan.
- Kami, dalam alasannya, tidak perlu memodifikasi atau mengkompilasi ulang kode kami untuk versi kernel yang berbeda.
- : - Kubernetes Docker, , / .
cgroup ID. , , «» « ». , « », « », « », API, Docker . ID , . Docker .
Mari kita bicara tentang API Linux umum yang dapat membantu tugas ini. Agar tidak memperumit cerita, kami akan memberi perhatian khusus pada proses yang dibuat menggunakan panggilan sistem
execve. Jika kita berbicara tentang solusi masalah yang lebih lengkap, maka selama penerapannya perlu, sebagai tambahan, untuk memantau proses yang dibuat menggunakan panggilan sistem fork/clonedan variannya, serta hasil panggilan execveat.
Solusi sederhana diimplementasikan dalam mode pengguna
- Menghubungi
/proc. Metode ini, karena masalah proses berumur pendek, tidak terlalu cocok untuk kami. - netlink. netlink ,
PID. ./proc, . - Linux. — , . API . . . — , , , . , API ,
auditdosquery. , ,auditdgo-audit, secara teori, dapat mengurangi masalah ini. Namun dalam kasus solusi kelas perusahaan, Anda tidak dapat mengetahui sebelumnya apakah pelanggan menggunakan alat tersebut, dan jika mereka menggunakan, yang mana. Juga tidak mungkin untuk mengetahui sebelumnya kontrol keamanan yang bekerja secara langsung dengan API Audit yang sedang digunakan oleh klien. Kelemahan kedua adalah audit API tidak tahu apa-apa tentang container. Dan ini terlepas dari fakta bahwa masalah ini telah dibahas selama bertahun-tahun.
Alat debugging mode kernel sederhana
Penerapan mekanisme ini melibatkan penggunaan "probe" dari berbagai jenis dalam satu salinan.
â–ŤTracepoints
Menggunakan tracepoints (
tracepoint). Tracepoints adalah sensor yang dipasang secara statis ke tempat tertentu di kernel selama kompilasi. Setiap sensor semacam itu dapat dihidupkan secara independen dari yang lain, sebagai akibatnya sensor tersebut akan mengeluarkan pemberitahuan jika tempat kode kernel tercapai di mana ia disematkan. Kernel berisi beberapa tracepoint yang cocok untuk kita, yang kodenya dijalankan di berbagai titik dalam pengoperasian system call execve. Ini - sched_process_exec, open_exec, sys_enter_execve, sys_exit_execve. Untuk mendapatkan daftar ini, saya menjalankan perintahcat /sys/kernel/tracing/available_events | grep execdan memfilter daftar yang dihasilkan menggunakan informasi yang diperoleh dari membaca kode kernel. Tracepoint ini lebih cocok untuk kita daripada mekanisme yang dijelaskan di atas, karena mereka memungkinkan kita untuk mengatur pengamatan proses yang berumur pendek. Tetapi tidak satupun dari mereka memberikan informasi tentang jalur lengkap ke file yang dapat dieksekusi dari proses tersebut, jika parameternya execadalah jalur relatif ke file semacam itu. Dengan kata lain, jika pengguna menjalankan perintah seperti itu cd /bin && ./ls, maka kita mendapatkan informasi jalur di formulir ./ls, bukan di formulir /bin/ls. Berikut contoh sederhananya:
# the sched_process_exec
sudo -s
cd /sys/kernel/debug/tracing
echo 1 > events/sched/sched_process_exec/enable
# ls
cd /bin && ./ls
# sched_process_exec
# ,
cd -
cat trace | grep ls
#
echo 0 > events/sched/sched_process_exec/enable
â–ŤSensor Kprobe / kretprobe
Sensor
kprobememungkinkan Anda mengekstrak informasi debug dari hampir semua tempat di kernel. Mereka seperti breakpoint khusus dalam kode kernel yang memberikan informasi tanpa menghentikan eksekusi kode. Sebuah sensor kprobe, tidak seperti trackpoint, dapat dihubungkan ke berbagai fungsi. Kode sensor semacam itu akan dipicu selama eksekusi panggilan sistem execve. Tetapi saya tidak menemukan dalam grafik panggilan dari execvefungsi apa pun, parameternya adalah PIDproses dan jalur lengkap ke file yang dapat dieksekusi. Akibatnya, kita dihadapkan pada "masalah jalur relatif" yang sama seperti saat menggunakan titik-jejak. Di sini Anda bisa, dengan mengandalkan kekhasan kernel tertentu, "mengubah" sesuatu. Bagaimanapun, sensorkprobedapat membaca data dari tumpukan panggilan kernel. Tetapi solusi seperti itu tidak akan bekerja secara stabil di versi kernel yang berbeda. Karena itu, saya tidak mempertimbangkannya.
â–ŤMenggunakan program eBPF dengan titik jejak, dengan probe kprobe dan kretprobe
Di sini kita berbicara tentang fakta bahwa ketika beberapa kode dijalankan, titik jejak atau sensor akan dipicu, tetapi kode program eBPF akan dieksekusi, dan bukan kode penangan kejadian biasa.
Menggunakan pendekatan ini membuka beberapa kemungkinan baru bagi kami. Sekarang kita dapat menjalankan kode arbitrer di kernel saat kita melakukan panggilan sistem
execve. Ini, secara teori, akan memberi kita kemampuan untuk mengekstrak informasi apa pun yang kita butuhkan dari kernel dan mengirimkannya ke ruang pengguna. Ada dua cara untuk mendapatkan jenis data ini, tetapi tidak satupun yang memenuhi persyaratan di atas.
- ,
task_structlinux_binprm. , , . ,sched_process_exec, eBPF- , dentrybprm->file->f_path.dentry, . eBPF- . . , eBPF- , , , . - eBPF . , . — API. — . (, eBPF,
cgroup ID, ).
«»
-
LD_PRELOADexeclibc. , . , , , , . -
execve,fork/clonechdir, . ,execveexecve. — eBPF- eBPF- , . - ,
ptrace. -. —ptraceseccompSECCOMP_RET_TRACE.seccompexecve,execveseccompexecve. - Menggunakan AppArmor. Anda dapat menulis profil AppArmor yang akan mencegah proses memanggil file yang dapat dijalankan. Jika Anda menggunakan profil ini dalam mode pelatihan (komplain), maka AppArmor tidak akan melarang eksekusi proses, tetapi hanya akan mengeluarkan pemberitahuan tentang pelanggaran aturan yang ditentukan dalam profil. Jika Anda menghubungkan profil ke setiap proses yang berjalan, maka kami mendapatkan solusi yang berfungsi, tetapi sangat tidak menarik dan terlalu "meretas". Mungkin tidak ada gunanya menggunakan pendekatan ini.
Solusi lainnya
Saya harus segera mengatakan bahwa tidak ada solusi ini yang memenuhi persyaratan kami, namun, saya akan mencantumkannya:
- Menggunakan utilitas
ps. Alat ini hanya membahas/procdan, akibatnya, mengalami masalah yang sama seperti mengarahkan ke/proc. - execsnoop, eBPF. , , ,
kprobe/kretprobe, , , . ,execsnoop, , , . -
execsnoop, eBPF. —kprobe, .
Di masa mendatang, dimungkinkan untuk menggunakan fungsi eBPF tambahan yang belum tersedia get_fd_path . Setelah ditambahkan ke kernel, ini akan berguna untuk menyelesaikan masalah kita. Benar, jalur lengkap ke file yang dapat dieksekusi dari proses tersebut harus diperoleh dengan menggunakan metode yang tidak menyediakan untuk membaca informasi dari struktur data kernel.
Hasil
Tidak ada satu pun API yang kami ulas yang sempurna. Di bawah ini saya ingin memberikan beberapa rekomendasi tentang pendekatan mana yang digunakan untuk mendapatkan informasi tentang proses dan kapan menggunakannya:
- —
auditdgo-audit. , . , , , . , , , - API , , . — , . - , , , , ,
execsnoop. — . - , , , , , . , . , , eBPF- eBPF-,
perf... Sebuah cerita tentang semua ini layak dijadikan artikel terpisah. Hal terpenting yang harus diingat saat memilih metode proses pemantauan ini adalah sebagai berikut. Jika Anda menggunakan program eBPF, periksa kemungkinan kompilasi statisnya, yang akan memungkinkan Anda untuk tidak bergantung pada header kernel. Tetapi justru ketergantungan inilah yang kami coba hindari menggunakan metode ini. Menggunakan metode ini juga berarti Anda tidak dapat bekerja dengan struktur data kernel dan Anda tidak dapat menggunakan kerangka kerja seperti BCC yang mengkompilasi program eBPF saat runtime. - Jika Anda tidak tertarik dengan proses yang berumur pendek dan rekomendasi sebelumnya tidak cocok untuk Anda, gunakan kemampuan netlink bersama dengan
/proc.
Bagaimana Anda mengatur pemantauan proses yang berjalan di Linux?
