Kubernetesdagi Seccomp: Siz boshidanoq bilishingiz kerak bo'lgan 7 ta narsa

Eslatma. tarjima.: E'tiboringizga Britaniyaning ASOS.com kompaniyasining ilovalar xavfsizligi bo'yicha katta muhandisi maqolasining tarjimasini taqdim etamiz. Shu bilan u seccomp-dan foydalanish orqali Kubernetesda xavfsizlikni yaxshilashga bag'ishlangan bir qator nashrlarni boshlaydi. Agar kirish so'z o'quvchilarga yoqsa, biz muallifni kuzatib boramiz va uning ushbu mavzu bo'yicha keyingi materiallarini davom ettiramiz.

Kubernetesdagi Seccomp: Siz boshidanoq bilishingiz kerak bo'lgan 7 ta narsa

Ushbu maqola SecDevOps ruhida seccomp profillarini qanday qilib sehr va jodugarlikka murojaat qilmasdan yaratish bo'yicha bir qator postlarning birinchisidir. XNUMX-qismda men Kubernetes-da seccomp-ni amalga oshirishning asoslari va ichki tafsilotlarini yoritib beraman.

Kubernetes ekotizimi konteynerlarni himoya qilish va izolyatsiya qilishning turli usullarini taklif etadi. Maqola Xavfsiz hisoblash rejimi haqida, shuningdek, nomi bilan ham tanilgan ikkilamchi. Uning mohiyati konteynerlar tomonidan bajarilishi mumkin bo'lgan tizim qo'ng'iroqlarini filtrlashdan iborat.

Nima uchun bu muhim? Konteyner - bu ma'lum bir mashinada ishlaydigan jarayon. Va u xuddi boshqa ilovalar kabi yadrodan foydalanadi. Agar konteynerlar har qanday tizim qo'ng'iroqlarini amalga oshirishi mumkin bo'lsa, tez orada zararli dastur konteyner izolyatsiyasini chetlab o'tish va boshqa ilovalarga ta'sir qilish uchun bundan foydalanadi: ma'lumotni ushlab turish, tizim sozlamalarini o'zgartirish va hokazo.

seccomp profillari qaysi tizim qo'ng'iroqlariga ruxsat berish yoki o'chirish kerakligini belgilaydi. Yadro ularning bajarilishini kuzatishi uchun konteyner ish vaqti ishga tushganda ularni faollashtiradi. Bunday profillardan foydalanish, agar konteyner ichidagi biron bir dastur (ya'ni, sizning bog'liqliklaringiz yoki ularning bog'liqliklari) ruxsat etilmagan narsalarni qila boshlasa, hujum vektorini cheklash va zararni kamaytirish imkonini beradi.

Asoslarni tushunish

Asosiy seccomp profili uchta elementni o'z ichiga oladi: defaultAction, architectures (yoki archMap) va syscalls:

{
    "defaultAction": "SCMP_ACT_ERRNO",
    "architectures": [
        "SCMP_ARCH_X86_64",
        "SCMP_ARCH_X86",
        "SCMP_ARCH_X32"
    ],
    "syscalls": [
        {
            "names": [
                "arch_prctl",
                "sched_yield",
                "futex",
                "write",
                "mmap",
                "exit_group",
                "madvise",
                "rt_sigprocmask",
                "getpid",
                "gettid",
                "tgkill",
                "rt_sigaction",
                "read",
                "getpgrp"
            ],
            "action": "SCMP_ACT_ALLOW"
        }
    ]
}

(o'rta-basic-seccomp.json)

defaultAction bo'limda ko'rsatilmagan har qanday tizim chaqiruvining standart taqdirini belgilaydi syscalls. Ishni osonlashtirish uchun keling, ishlatiladigan ikkita asosiy qiymatga e'tibor qarataylik:

  • SCMP_ACT_ERRNO — tizim chaqiruvining bajarilishini bloklaydi;
  • SCMP_ACT_ALLOW - ruxsat beradi.

bo'lim architectures maqsadli arxitekturalar ro'yxatga olingan. Bu muhim, chunki yadro darajasida qo'llaniladigan filtrning o'zi profilda ko'rsatilgan nomlarga emas, balki tizim chaqiruvi identifikatorlariga bog'liq. Konteynerning ishlash vaqti foydalanishdan oldin ularni identifikatorlarga moslashtiradi. G'oya shundan iboratki, tizim qo'ng'iroqlari tizim arxitekturasiga qarab butunlay boshqacha identifikatorlarga ega bo'lishi mumkin. Masalan, tizim chaqiruvi recvfrom (rozetkadan ma'lumot olish uchun ishlatiladi) x64 tizimlarida ID = 64 va x517 da ID = 86 ga ega. u x86-x64 arxitekturalari uchun barcha tizim qo'ng'iroqlari ro'yxatini topishingiz mumkin.

Bo'limda syscalls barcha tizim qo'ng'iroqlarini sanab o'tadi va ular bilan nima qilish kerakligini belgilaydi. Misol uchun, sozlash orqali oq ro'yxat yaratishingiz mumkin defaultAction haqida SCMP_ACT_ERRNO, va bo'limda qo'ng'iroqlar syscalls tayinlash SCMP_ACT_ALLOW. Shunday qilib, siz faqat bo'limda ko'rsatilgan qo'ng'iroqlarga ruxsat berasiz syscalls, va boshqalarni taqiqlang. Qora ro'yxat uchun siz qiymatlarni o'zgartirishingiz kerak defaultAction va aksincha harakatlar.

Endi biz unchalik aniq bo'lmagan nuanslar haqida bir necha so'z aytishimiz kerak. Esda tutingki, quyida keltirilgan tavsiyalar siz Kubernetes-da biznes-ilovalar qatorini joylashtirmoqdasiz va ularning imkon qadar kamroq imtiyozlar bilan ishlashini xohlaysiz.

1. AllowPrivilegeEscalation=false

В securityContext konteyner parametrga ega AllowPrivilegeEscalation. Agar u o'rnatilgan bo'lsa false, konteynerlar ( bilan boshlanadi)on) bit no_new_priv. Ushbu parametrning ma'nosi nomidan ravshan: u konteynerni o'zidan ko'ra ko'proq imtiyozlarga ega bo'lgan yangi jarayonlarni ishga tushirishga to'sqinlik qiladi.

Ushbu parametrning yon ta'siri o'rnatilmoqda true (standart) konteynerning ishlash vaqti ishga tushirish jarayonining boshida seccomp profilini qo'llaydi. Shunday qilib, ichki ish vaqti jarayonlarini ishga tushirish uchun zarur bo'lgan barcha tizim qo'ng'iroqlari (masalan, foydalanuvchi/guruh identifikatorlarini o'rnatish, muayyan imkoniyatlarni o'chirish) profilda yoqilgan bo'lishi kerak.

Arzimas narsalarni qiladigan idishga echo hi, quyidagi ruxsatlar talab qilinadi:

{
    "defaultAction": "SCMP_ACT_ERRNO",
    "architectures": [
        "SCMP_ARCH_X86_64",
        "SCMP_ARCH_X86",
        "SCMP_ARCH_X32"
    ],
    "syscalls": [
        {
            "names": [
                "arch_prctl",
                "brk",
                "capget",
                "capset",
                "chdir",
                "close",
                "execve",
                "exit_group",
                "fstat",
                "fstatfs",
                "futex",
                "getdents64",
                "getppid",
                "lstat",
                "mprotect",
                "nanosleep",
                "newfstatat",
                "openat",
                "prctl",
                "read",
                "rt_sigaction",
                "statfs",
                "setgid",
                "setgroups",
                "setuid",
                "stat",
                "uname",
                "write"
            ],
            "action": "SCMP_ACT_ALLOW"
        }
    ]
}

(hi-pod-seccomp.json)

...bularning o‘rniga:

{
    "defaultAction": "SCMP_ACT_ERRNO",
    "architectures": [
        "SCMP_ARCH_X86_64",
        "SCMP_ARCH_X86",
        "SCMP_ARCH_X32"
    ],
    "syscalls": [
        {
            "names": [
                "arch_prctl",
                "brk",
                "close",
                "execve",
                "exit_group",
                "futex",
                "mprotect",
                "nanosleep",
                "stat",
                "write"
            ],
            "action": "SCMP_ACT_ALLOW"
        }
    ]
}

(hi-container-seccomp.json)

Ammo yana nima uchun bu muammo? Shaxsan men quyidagi tizim qoʻngʻiroqlarini oq roʻyxatga kiritishdan qochgan boʻlardim (agar ularga haqiqiy ehtiyoj boʻlmasa): capset, set_tid_address, setgid, setgroups и setuid. Biroq, haqiqiy qiyinchilik shundaki, siz mutlaqo nazorat qila olmaydigan jarayonlarga ruxsat berish orqali siz profillarni konteynerning ishlash vaqtini amalga oshirishga bog'laysiz. Boshqacha qilib aytganda, bir kun konteyner ish vaqti muhitini yangilaganingizdan so'ng (siz yoki, ehtimol, bulutli xizmat ko'rsatuvchi provayder tomonidan) konteynerlar to'satdan ishlashni to'xtatib qo'yishini bilib olishingiz mumkin.

Maslahat # 1: bilan konteynerlarni ishlating AllowPrivilegeEscaltion=false. Bu seccomp profillarining hajmini kamaytiradi va ularni konteyner ish vaqti muhitidagi o'zgarishlarga nisbatan kamroq sezgir qiladi.

2. Konteyner darajasida seccomp profillarini o'rnatish

Seccomp profili pod darajasida o'rnatilishi mumkin:

annotations:
  seccomp.security.alpha.kubernetes.io/pod: "localhost/profile.json"

... yoki konteyner darajasida:

annotations:
  container.security.alpha.kubernetes.io/<container-name>: "localhost/profile.json"

Kubernetes seccomp qachon yuqoridagi sintaksis o'zgarishini unutmang GA ga aylanadi (bu voqea Kubernetesning keyingi nashrida kutilmoqda - 1.18 - taxminan. transl.).

Kubernetes har doim shunday bo'lganini kam odam biladi xatoseccomp profillarini qo'llashga sabab bo'ldi konteynerni pauza qilish. Ish vaqti muhiti ushbu kamchilikni qisman qoplaydi, ammo bu konteyner podlardan yo'qolmaydi, chunki u ularning infratuzilmasini sozlash uchun ishlatiladi.

Muammo shundaki, bu konteyner har doim boshlanadi AllowPrivilegeEscalation=true, 1-bandda aytilgan muammolarga olib keladi va buni o'zgartirish mumkin emas.

Konteyner darajasida seccomp profillaridan foydalanib, siz ushbu tuzoqdan qochasiz va ma'lum bir konteynerga moslashtirilgan profil yaratishingiz mumkin. Bu ishlab chiquvchilar xatoni tuzatmaguncha va yangi versiya (ehtimol 1.18?) hamma uchun mavjud bo'lmaguncha bajarilishi kerak.

Maslahat # 2: Seccomp profillarini konteyner darajasida o'rnating.

Amaliy ma'noda, bu qoida odatda savolga universal javob bo'lib xizmat qiladi: "Nega mening seccomp profilim bilan ishlaydi? docker runlekin Kubernetes klasteriga joylashtirilgandan keyin ishlamayaptimi?

3. Ish vaqti/standartdan faqat oxirgi chora sifatida foydalaning

Kubernetes o'rnatilgan profillar uchun ikkita variantga ega: runtime/default и docker/default. Ikkalasi ham Kubernetes emas, balki konteynerning ish vaqti tomonidan amalga oshiriladi. Shuning uchun ular ishlatiladigan ish vaqti muhiti va uning versiyasiga qarab farq qilishi mumkin.

Boshqacha qilib aytganda, ish vaqtini o'zgartirish natijasida konteyner foydalanishi yoki foydalanmasligi mumkin bo'lgan boshqa tizim qo'ng'iroqlari to'plamiga kirish huquqiga ega bo'lishi mumkin. Ko'pchilik ish vaqtlari foydalanadi Dockerni amalga oshirish. Agar siz ushbu profildan foydalanmoqchi bo'lsangiz, uning sizga mos kelishiga ishonch hosil qiling.

profili docker/default Kubernetes 1.11 dan beri eskirgan, shuning uchun uni ishlatishdan saqlaning.

Menimcha, profil runtime/default yaratilgan maqsad uchun juda mos keladi: foydalanuvchilarni buyruqni bajarish bilan bog'liq xavflardan himoya qilish docker run ularning mashinalarida. Biroq, Kubernetes klasterlarida ishlaydigan biznes ilovalari haqida gap ketganda, men bunday profil juda ochiq va ishlab chiquvchilar o'z ilovalari (yoki ilovalar turlari) uchun profillar yaratishga e'tibor qaratishlari kerakligi haqida bahslashishga jur'at etaman.

Maslahat # 3: Muayyan ilovalar uchun seccomp profillarini yarating. Agar buning iloji bo'lmasa, dastur turlari uchun profil yarating, masalan, Golang ilovasining barcha veb-APIlarini o'z ichiga olgan kengaytirilgan profil yarating. Faqat oxirgi chora sifatida ish vaqti/standartdan foydalaning.

Kelgusi postlarda men SecDevOps-dan ilhomlangan seccomp profillarini qanday yaratish, ularni avtomatlashtirish va quvurlarda sinab ko'rishni ko'rib chiqaman. Boshqacha qilib aytganda, ilovaga oid profillarni yangilamaslik uchun hech qanday bahona bo'lmaydi.

4. Cheklanmagan variant EMAS.

dan birinchi Kubernetes xavfsizlik auditi sukut bo'yicha ekanligi ma'lum bo'ldi seccomp o'chirilgan. Bu shuni anglatadiki, agar siz o'rnatmasangiz PodSecurityPolicy, bu uni klasterda faollashtiradi, seccomp profili aniqlanmagan barcha podlar ishlaydi. seccomp=unconfined.

Ushbu rejimda ishlash klasterni himoya qiladigan butun izolyatsiya qatlami yo'qolishini anglatadi. Ushbu yondashuv xavfsizlik mutaxassislari tomonidan tavsiya etilmaydi.

Maslahat # 4: Klasterdagi hech bir konteyner ishlamasligi kerak seccomp=unconfined, ayniqsa ishlab chiqarish muhitida.

5. "Audit rejimi"

Bu nuqta Kubernetesga xos emas, lekin baribir "boshlashdan oldin bilish kerak bo'lgan narsalar" toifasiga kiradi.

Aytgancha, seccomp profillarini yaratish har doim qiyin bo'lgan va asosan sinov va xatolarga tayanadi. Gap shundaki, foydalanuvchilarda dasturni "tashlab qo'yish" xavfisiz ularni ishlab chiqarish muhitida sinab ko'rish imkoniyati yo'q.

Linux yadrosi 4.14 chiqarilgandan so'ng, barcha tizim qo'ng'iroqlari haqidagi ma'lumotlarni syslog-ga yozib olgan holda, lekin ularni bloklamasdan, audit rejimida profil qismlarini ishga tushirish mumkin bo'ldi. Ushbu rejimni parametr yordamida faollashtirishingiz mumkin SCMT_ACT_LOG:

SCMP_ACT_LOG: seccomp, agar u filtrdagi biron bir qoidaga mos kelmasa, tizim chaqiruvini amalga oshiruvchi ipga ta'sir qilmaydi, lekin tizim chaqiruvi haqidagi ma'lumotlar qayd qilinadi.

Bu xususiyatdan foydalanishning odatiy strategiyasi:

  1. Kerakli tizim qo'ng'iroqlariga ruxsat bering.
  2. Foydali bo'lmasligini bilgan tizimdan qo'ng'iroqlarni bloklang.
  3. Jurnaldagi boshqa barcha qo'ng'iroqlar haqidagi ma'lumotlarni yozib oling.

Soddalashtirilgan misol quyidagicha ko'rinadi:

{
    "defaultAction": "SCMP_ACT_LOG",
    "architectures": [
        "SCMP_ARCH_X86_64",
        "SCMP_ARCH_X86",
        "SCMP_ARCH_X32"
    ],
    "syscalls": [
        {
            "names": [
                "arch_prctl",
                "sched_yield",
                "futex",
                "write",
                "mmap",
                "exit_group",
                "madvise",
                "rt_sigprocmask",
                "getpid",
                "gettid",
                "tgkill",
                "rt_sigaction",
                "read",
                "getpgrp"
            ],
            "action": "SCMP_ACT_ALLOW"
        },
        {
            "names": [
                "add_key",
                "keyctl",
                "ptrace"
            ],
            "action": "SCMP_ACT_ERRNO"
        }
    ]
}

(o'rta-mixed-seccomp.json)

Ammo esda tutingki, siz foydalanilmasligini bilgan va klasterga zarar etkazishi mumkin bo'lgan barcha qo'ng'iroqlarni bloklashingiz kerak. Ro'yxatni tuzish uchun yaxshi asos rasmiy hisoblanadi Docker hujjatlari. Standart profilda qaysi tizim qo'ng'iroqlari bloklanganligi va nima uchun ekanligini batafsil tushuntiradi.

Biroq, bitta qo'lga olish bor. Garchi SCMT_ACT_LOG 2017 yil oxiridan beri Linux yadrosi tomonidan qo'llab-quvvatlanadi, u Kubernetes ekotizimiga nisbatan yaqinda kirdi. Shuning uchun, ushbu usuldan foydalanish uchun sizga Linux yadrosi 4.14 va runC versiyasidan past bo'lmagan versiya kerak bo'ladi v1.0.0-rc9.

Maslahat # 5: Qora va oq ro'yxatlarni birlashtirish orqali ishlab chiqarishda sinovdan o'tkazish uchun audit rejimi profilini yaratish mumkin va barcha istisnolar qayd etilishi mumkin.

6. Oq ro'yxatlardan foydalaning

Oq ro'yxatga olish qo'shimcha harakat talab qiladi, chunki siz ilovaga kerak bo'lishi mumkin bo'lgan har bir qo'ng'iroqni aniqlashingiz kerak, ammo bu yondashuv xavfsizlikni sezilarli darajada yaxshilaydi:

Oq ro'yxat usulidan foydalanish tavsiya etiladi, chunki u sodda va ishonchli. Qora ro'yxat har safar potentsial xavfli tizim chaqiruvi (yoki qora ro'yxatda bo'lsa, xavfli bayroq/variant) qo'shilganda yangilanishi kerak bo'ladi. Bundan tashqari, ko'pincha parametrni uning mohiyatini o'zgartirmasdan o'zgartirish va shu bilan qora ro'yxat cheklovlarini chetlab o'tish mumkin.

Go ilovalari uchun men ilovaga hamroh bo'lgan va ijro paytida qilingan barcha qo'ng'iroqlarni to'playdigan maxsus vositani ishlab chiqdim. Masalan, quyidagi dastur uchun:

package main

import "fmt"

func main() {
	fmt.Println("test")
}

... ishga tushamiz gosystract shuning uchun:

go install https://github.com/pjbgf/gosystract
gosystract --template='{{- range . }}{{printf ""%s",n" .Name}}{{- end}}' application-path

... va biz quyidagi natijaga erishamiz:

"sched_yield",
"futex",
"write",
"mmap",
"exit_group",
"madvise",
"rt_sigprocmask",
"getpid",
"gettid",
"tgkill",
"rt_sigaction",
"read",
"getpgrp",
"arch_prctl",

Hozircha, bu faqat bir misol - asboblar haqida batafsilroq ma'lumot beriladi.

Maslahat # 6: Faqat sizga kerak bo'lgan qo'ng'iroqlarga ruxsat bering va qolganlarini bloklang.

7. To'g'ri poydevor qo'ying (yoki kutilmagan xatti-harakatlarga tayyorlaning)

Yadro profilga nima yozganingizdan qat'i nazar, uni majbur qiladi. Garchi bu siz xohlagandek bo'lmasa ham. Misol uchun, agar siz kabi qo'ng'iroqlarga kirishni bloklasangiz exit yoki exit_group, konteynerni to'g'ri o'chirish va hatto oddiy buyruq kabi bo'lmaydi echo hi uni osib qo'yingo noma'lum muddatga. Natijada siz klasterda yuqori protsessordan foydalanasiz:

Kubernetesdagi Seccomp: Siz boshidanoq bilishingiz kerak bo'lgan 7 ta narsa

Bunday hollarda yordamchi xizmat yordamga kelishi mumkin strace - bu muammo nima bo'lishi mumkinligini ko'rsatadi:

Kubernetesdagi Seccomp: Siz boshidanoq bilishingiz kerak bo'lgan 7 ta narsa
sudo strace -c -p 9331

Profillar ish vaqtida dasturga kerak bo'lgan barcha tizim qo'ng'iroqlarini o'z ichiga olganligiga ishonch hosil qiling.

Maslahat # 7: Tafsilotlarga e'tibor bering va barcha kerakli tizim qo'ng'iroqlari oq ro'yxatga kiritilganligiga ishonch hosil qiling.

Bu SecDevOps ruhida Kubernetes-da seccomp-dan foydalanish bo'yicha bir qator maqolalarning birinchi qismini yakunlaydi. Keyingi qismlarda bu nima uchun muhimligi va jarayonni qanday avtomatlashtirish haqida gapiramiz.

Tarjimondan PS

Shuningdek, bizning blogimizda o'qing:

Manba: www.habr.com

a Izoh qo'shish