Seccomp li Kubernetes: 7 tiştên ku divê hûn ji destpêkê ve zanibin

Not. werger.: Em wergerandina gotarekê ji hêla endezyarek ewlekariya sepanê ya payebilind li pargîdaniya Brîtanî ASOS.com ve pêşkêşî we dikin. Bi wê re, ew dest bi rêze weşanan dike ku ji bo baştirkirina ewlehiyê li Kubernetes bi karanîna seccomp ve hatî veqetandin. Ger xwendevan ji pêşgotinê hez bikin, em ê nivîskar bişopînin û materyalên wî yên pêşerojê li ser vê mijarê bidomînin.

Seccomp li Kubernetes: 7 tiştên ku divê hûn ji destpêkê ve zanibin

Ev gotar yekem e di rêze nivîsan de li ser meriv çawa bi ruhê SecDevOps profîlên seccomp-ê biafirîne, bêyî ku serî li sêrbaz û sêrbaziyê bide. Di Beş 1 de, ez ê bingeh û hûrguliyên hundurîn ên pêkanîna seccomp-ê li Kubernetes vegirim.

Ekosîstema Kubernetes cûrbecûr awayan ji bo ewlekarî û veqetandina konteyneran pêşkêşî dike. Gotar li ser Moda Hesabkirina Ewle ye, ku jê re tê zanîn seccomp. Esasê wê fîlterkirina bangên pergalê yên ku ji bo darvekirinê ji hêla konteyneran ve têne peyda kirin e.

Çima girîng e? Konteynir tenê pêvajoyek e ku li ser makîneyek taybetî dimeşîne. Û ew mîna sepanên din kernel bikar tîne. Ger konteyneran karibe her bangên pergalê pêk bîne, pir zû malware dê ji vê yekê sûd werbigire da ku îzolekirina konteyneran derbas bike û bandorê li ser sepanên din bike: agahdarî bigire, mîhengên pergalê biguhezîne, hwd.

profîlên seccomp diyar dikin ka kîjan bangên pergalê divê werin destûr kirin an neçalak kirin. Dema xebitandina konteyneran gava ku dest pê dike wan çalak dike da ku kernel karibe pêkanîna wan bişopîne. Bikaranîna profîlên weha dihêle hûn vektora êrîşê sînordar bikin û zirarê kêm bikin ger ku bernameyek di hundurê konteynerê de (ango, girêdanên we, an girêdanên wan) dest bi kirina tiştê ku destûr nayê dayîn bike.

Gihîştina bingehên bingehîn

Profîla bingehîn ya seccomp sê hêman pêk tîne: defaultAction, architectures (an jî archMap) û 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"
        }
    ]
}

(navîn-bingehîn-seccomp.json)

defaultAction çarenûsa xwerû ya her bangek pergalê ku di beşê de nehatiye diyar kirin diyar dike syscalls. Ji bo ku tiştan hêsantir bikin, em li ser du nirxên sereke yên ku dê werin bikar anîn bisekinin:

  • SCMP_ACT_ERRNO - pêkanîna bangek pergalê asteng dike,
  • SCMP_ACT_ALLOW - destûrê dide.

beşa architectures mîmariyên armanc têne navnîş kirin. Ev girîng e ji ber ku fîlter bixwe, ku di asta kernelê de tê sepandin, bi nasnameyên banga pergalê ve girêdayî ye, û ne bi navên wan ên ku di profîlê de hatine destnîşan kirin. Dema xebitandina konteynerê dê wan berî bikar bîne bi nasnameyan re li hev bike. Fikir ev e ku bangên pergalê li gorî mîmariya pergalê dikarin nasnameyên bi tevahî cûda hebin. Mînakî, banga pergalê recvfrom (ji bo wergirtina agahdariya ji soketê tê bikar anîn) di pergalên x64 de ID = 64 û li ser x517 ID = 86 heye. Ev e hûn dikarin navnîşek hemî bangên pergalê ji bo mîmariya x86-x64 bibînin.

Di beşa syscalls hemî bangên pergalê navnîş dike û diyar dike ku bi wan re çi bikin. Mînakî, hûn dikarin bi mîhengê navnîşek spî biafirînin defaultAction li ser SCMP_ACT_ERRNO, û di beşê de bang dike syscalls cîrêdan SCMP_ACT_ALLOW. Bi vî rengî, hûn tenê destûrê didin bangên ku di beşê de hatine destnîşan kirin syscalls, û hemûyên din qedexe bike. Ji bo lîsteya reş divê hûn nirxan biguherînin defaultAction û çalakiyên berevajî.

Naha divê em çend peyvan li ser nuansên ku ew qas ne diyar in bibêjin. Ji kerema xwe not bikin ku pêşnîyarên jêrîn texmîn dikin ku hûn rêzek serîlêdanên karsaziyê li ser Kubernetes dişoxilînin û hûn dixwazin ku ew bi kêmtirîn îmtiyazên gengaz bimeşînin.

1. AllowPrivilegeEscalation=derew

В securityContext konteynir xwedî pîvanek e AllowPrivilegeEscalation. Ger ew tê de were saz kirin false, konteynir dê bi (on) bit no_new_priv. Wateya vê parametreyê ji navê xwe diyar e: ew nahêle ku konteynir pêvajoyên nû bi îmtiyazên ji xwe zêdetir dest pê bike.

Bandorek aliyî ya vê vebijarkê ku tê danîn true (xweserî) ev e ku dema xebitandina konteynerê di destpêka pêvajoya destpêkirinê de profîla seccomp bicîh tîne. Ji ber vê yekê, hemî bangên pergalê yên ku ji bo meşandina pêvajoyên dema xebitandina hundurîn hewce ne (mînak danîna nasnameyên bikarhêner/kom, avêtina hin kapasîteyan) divê di profîlê de werin çalak kirin.

Li konteynirek ku tiştên piçûk dike echo hi, destûrên jêrîn dê hewce bibin:

{
    "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)

... li şûna van:

{
    "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)

Lê dîsa, çima ev pirsgirêk e? Bi kesane, ez ê ji navnîşa spî ya bangên pergalê yên jêrîn dûr bixim (heta ku hewcedariya wan bi rastî hebe): capset, set_tid_address, setgid, setgroups и setuid. Lêbelê, kêşeya rastîn ev e ku bi destûrdana pêvajoyên ku we bi tevahî ti kontrola wan tune, hûn profîlan bi pêkanîna dema xebitandina konteynerê ve girêdidin. Bi gotinek din, rojek hûn dikarin bibînin ku piştî nûvekirina hawîrdora xebitandina konteyneran (ji hêla we ve an, bi îhtîmalek pirtir, ji hêla peydakarê karûbarê cloudê ve), konteynir ji nişkê ve disekine.

Serişte # 1: Run konteynir bi AllowPrivilegeEscaltion=false. Ev ê mezinahiya profîlên seccomp kêm bike û wan ji guheztinên di hawîrdora xebata konteynerê de kêmtir hesas bike.

2. Sazkirina profîlên seccomp di asta konteynerê de

Profîla seccomp dikare di asta pod de were saz kirin:

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

an jî di asta konteynerê de:

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

Ji kerema xwe gava ku Kubernetes seccomp hevoksa jorîn biguhere dê bibe GA (ev bûyer di serbestberdana paşîn a Kubernetes - 1.18 - nêzîkê werger tê çaverê kirin).

Kêm kes dizanin ku Kubernetes her dem hebû rûnaskku bû sedem ku profîlên seccomp werin sepandin konteynir sekinîn. Jîngeha xebitandinê bi qismî vê kêmasiyê telafî dike, lê ev konteynir ji potan winda nabe, ji ber ku ew ji bo mîhengkirina binesaziya wan tê bikar anîn.

Pirsgirêk ev e ku ev konteynir her gav bi dest pê dike AllowPrivilegeEscalation=true, dibe sedema pirsgirêkên ku di paragrafa 1 de hatine gotin, û ev nayê guhertin.

Bi karanîna profîlên seccomp di asta konteynerê de, hûn ji vê xefikê dûr dikevin û dikarin profîlek ku li gorî konteynirek taybetî hatî çêkirin biafirînin. Pêdivî ye ku ev were kirin heya ku pêşdebiran xeletiyê rast bikin û guhertoya nû (dibe ku 1.18?) ji her kesî re peyda bibe.

Serişte # 2: Profîlên seccomp di asta konteynerê de bicîh bikin.

Di wateya pratîkî de, ev qaîdeyek bi gelemperî wekî bersivek gerdûnî ya pirsê dike: "Çima profîla min a seccomp bi docker runlê piştî ku li komek Kubernetes hate bicîh kirin naxebite?

3. Dema xebitandinê/default tenê wekî çareya dawîn bikar bînin

Kubernetes ji bo profîlên çêkirî du vebijark hene: runtime/default и docker/default. Her du jî ji hêla dema xebitandina konteynerê ve têne bicîh kirin, ne Kubernetes. Ji ber vê yekê, ew dikarin li gorî hawîrdora xebitandinê û guhertoya wê ve girêdayî cûda bibin.

Bi gotinek din, di encama guhertina dema xebitandinê de, dibe ku konteynir bigihîje komek cûda bangên pergalê, ku ew dikare bikar bîne an jî nekare. Pir demên xebitandinê bikar tînin pêkanîna Docker. Heke hûn dixwazin vê profîlê bikar bînin, ji kerema xwe piştrast bikin ku ew ji we re guncan e.

Wêne docker/default ji Kubernetes 1.11-ê ve hatî qewirandin, ji ber vê yekê ji karanîna wê dûr bisekinin.

Bi dîtina min, profîla runtime/default ji bo armanca ku ew hatî afirandin bêkêmasî maqûl e: parastina bikarhêneran ji xetereyên ku bi pêkanîna fermanek ve girêdayî ne docker run li ser erebeyên wan. Lêbelê, gava ku dor tê ser sepanên karsaziyê ku li ser komên Kubernetes têne xebitandin, ez ê diwêrim ku profîlek weha pir vekirî ye û pêşdebiran divê balê bikişînin ser afirandina profîlên ji bo serîlêdanên xwe (an celebên serîlêdanan).

Serişte # 3: Ji bo serîlêdanên taybetî profîlên seccomp biafirînin. Ger ev ne mumkun be, ji bo celebên serîlêdanê profîlan biafirînin, mînakî, profîlek pêşkeftî biafirînin ku hemî API-yên webê yên serîlêdana Golang vedihewîne. Tenê dema xebitandinê/default wekî çareya paşîn bikar bînin.

Di postên pêşerojê de, ez ê vebêjim ka meriv çawa profîlên seccomp-ê yên îlhama SecDevOps biafirîne, wan bixweber bike, û wan di lûleyan de ceribandin. Bi gotinek din, hûn ê hincetek tune ku hûn profîlên serîlêdanê-taybet nûve nekin.

4. Bêsînor NE vebijarkek e.

Ji yekem kontrola ewlehiyê ya Kubernetes derket holê ku bi xweber seccomp neçalak. Ev tê wê wateyê ku heke hûn saz nekin PodSecurityPolicy, ku wê di komê de çalak bike, hemî podên ku profîla seccomp ne diyarkirî dê tê de bixebitin seccomp=unconfined.

Di vê modê de xebitandin tê vê wateyê ku tevahiya qatek insulasyonê ya ku komê diparêze winda dibe. Ev nêzîkatî ji hêla pisporên ewlehiyê ve nayê pêşniyar kirin.

Serişte # 4: Divê tu konteynir di komê de neyê xebitandin seccomp=unconfined, bi taybetî di hawîrdorên hilberînê de.

5. "Moda Kontrolkirinê"

Ev xal ne ji Kubernetes-ê re yekta ye, lê dîsa jî dikeve kategoriya "tiştên ku berî ku hûn dest pê bikin zanibin".

Wekî ku diqewime, afirandina profîlên seccomp her gav dijwar bûye û bi giranî xwe dispêre ceribandin û xeletiyê. Rastî ev e ku bikarhêner bi tenê fersendê nadin ku wan di hawîrdorên hilberînê de ceribandin bêyî ku xetera "avêtina" serîlêdanê bikin.

Piştî serbestberdana kernel Linux 4.14, gengaz bû ku beşên profîlek di moda kontrolê de bimeşîne, agahdariya li ser hemî bangên pergalê di syslog-ê de tomar bike, lê bêyî astengkirina wan. Hûn dikarin vê modê bi karanîna pîvanê çalak bikin SCMT_ACT_LOG:

SCMP_ACT_LOG: seccomp dê bandorê li ser mijara ku bangewaziya pergalê dike neke ger ew di parzûnê de bi rêgezek hevûdu nebe, lê agahdariya li ser banga pergalê dê were tomar kirin.

Li vir stratejiyek tîpîk ji bo karanîna vê taybetmendiyê heye:

  1. Destûrê bide bangên pergalê yên ku hewce ne.
  2. Bangên ji pergala ku hûn dizanin dê ne kêrhatî bin asteng bikin.
  3. Agahdariya li ser hemî bangên din di têketinê de tomar bikin.

Mînaka hêsankirî wiha xuya dike:

{
    "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"
        }
    ]
}

(navîn-mixed-seccomp.json)

Lê ji bîr mekin ku hûn hewce ne ku hemî bangên ku hûn dizanin nayên bikar anîn û ku dibe ku zirarê bide komê asteng bikin. Bingehek baş ji bo berhevkirina lîsteyek fermî ye Belgekirina Docker. Ew bi hûrgulî diyar dike ka kîjan bangên pergalê di profîla xwerû de têne asteng kirin û çima.

Lêbelê, yek girtinek heye. Herçi SCMT_ACT_LOG Ji dawiya sala 2017-an û vir ve ji hêla kernel Linux ve hatî piştgirî kirin, ew tenê di van demên dawî de ket ekosîstema Kubernetes. Ji ber vê yekê, ji bo ku hûn vê rêbazê bikar bînin, hûn ê hewceyê kernel Linux 4.14 û guhertoya runC ne kêmtir be v1.0.0-rc9.

Serişte # 5: Ji bo ceribandina di hilberînê de profîlek moda kontrolê dikare bi berhevkirina navnîşên reş û spî were afirandin, û hemî îstîsna dikarin bêne tomar kirin.

6. Lîsteyên spî bikar bînin

Lîsteya spî hewildanek zêde hewce dike ji ber ku hûn neçar in ku her bangek ku dibe ku serîlêdanê hewce bike nas bikin, lê ev nêzîkatî pir ewlehiyê çêtir dike:

Pir tê pêşniyar kirin ku meriv nêzîkatiya lîsteya spî bikar bîne ji ber ku ew hêsantir û pêbawertir e. Dema ku bangek pergalê ya potansiyel xeternak (an ala/vebijarkek xeternak heke ew di navnîşa reş de be) were zêdekirin pêdivî ye ku navnîşa reş were nûve kirin. Digel vê yekê, bi gelemperî gengaz e ku meriv nûnertiya pîvanek bêyî guheztina cewhera wê biguhezîne û bi vî rengî sînorkirinên navnîşa reş derbas bike.

Ji bo serîlêdanên Go, min amûrek taybetî çêkir ku digel serîlêdanê ye û hemî bangên ku di dema darvekirinê de hatine çêkirin berhev dike. Mînakî, ji bo serîlêdana jêrîn:

package main

import "fmt"

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

... em dest pê bikin gosystract wusa

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

... û em encama jêrîn bistînin:

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

Heya nuha, ev tenê mînakek e - hûrguliyên bêtir di derbarê amûran de dê li pey bibin.

Serişte # 6: Destûr bidin tenê wan bangên ku hûn bi rastî hewce ne û hemî yên din asteng bikin.

7. Bingehên rast deynin (an jî ji tevgerên nediyar re amade bibin)

Kernel bêyî ku hûn tê de binivîsin dê profîlê bicîh bike. Her çend ew ne tam ya ku we dixwest be jî. Mînakî, heke hûn gihîştina bangên mîna asteng bikin exit an exit_group, konteynir dê nikaribe rast biqede û tewra fermanek hêsan a mîna echo hi wî daleqînino ji bo demeke nediyar. Wekî encamek, hûn ê di komê de karanîna CPU-ya bilind bistînin:

Seccomp li Kubernetes: 7 tiştên ku divê hûn ji destpêkê ve zanibin

Di rewşên weha de, karûbarek dikare were rizgariyê strace - ew ê nîşan bide ka pirsgirêk çi dibe bila bibe:

Seccomp li Kubernetes: 7 tiştên ku divê hûn ji destpêkê ve zanibin
sudo strace -c -p 9331

Bawer bikin ku profîl hemî bangên pergalê yên ku serîlêdanê di dema xebitandinê de hewce dike dihewîne.

Serişte # 7: Bala xwe bidin hûrguliyê û pê ewle bin ku hemî bangên pergalê yên pêwîst di navnîşa spî de ne.

Ev beşa yekem a rêze gotarên li ser karanîna seccomp li Kubernetes di ruhê SecDevOps de bi dawî dike. Di beşên jêrîn de em ê li ser vê yekê bipeyivin ka çima ev girîng e û meriv çawa pêvajoyê bixweber dike.

PS ji wergêr

Li ser bloga me jî bixwînin:

Source: www.habr.com

Add a comment