Seccomp yn Kubernetes: 7 peth y mae angen i chi eu gwybod o'r cychwyn cyntaf

Nodyn. traws.: Rydym yn cyflwyno i'ch sylw gyfieithiad o erthygl gan uwch beiriannydd diogelwch cymwysiadau yn y cwmni Prydeinig ASOS.com. Ag ef, mae'n dechrau cyfres o gyhoeddiadau sy'n ymroddedig i wella diogelwch yn Kubernetes trwy ddefnyddio seccomp. Os yw darllenwyr yn hoffi'r cyflwyniad, byddwn yn dilyn yr awdur ac yn parhau â'i ddeunyddiau yn y dyfodol ar y pwnc hwn.

Seccomp yn Kubernetes: 7 peth y mae angen i chi eu gwybod o'r cychwyn cyntaf

Yr erthygl hon yw'r gyntaf mewn cyfres o bostiadau ar sut i greu proffiliau seccomp yn ysbryd SecDevOps, heb droi at hud a dewiniaeth. Yn Rhan 1, byddaf yn ymdrin â'r pethau sylfaenol a manylion mewnol gweithredu seccomp yn Kubernetes.

Mae ecosystem Kubernetes yn cynnig amrywiaeth eang o ffyrdd o ddiogelu ac ynysu cynwysyddion. Mae'r erthygl yn ymwneud â Modd Cyfrifiadura Diogel, a elwir hefyd yn seccomp. Ei hanfod yw hidlo'r galwadau system sydd ar gael i'w gweithredu gan gynwysyddion.

Pam ei fod yn bwysig? Dim ond proses sy'n rhedeg ar beiriant penodol yw cynhwysydd. Ac mae'n defnyddio'r cnewyllyn yn union fel cymwysiadau eraill. Pe gallai cynwysyddion gyflawni unrhyw alwadau system, yn fuan iawn byddai malware yn manteisio ar hyn i osgoi ynysu cynhwysydd ac effeithio ar gymwysiadau eraill: gwybodaeth rhyng-gipio, newid gosodiadau system, ac ati.

mae proffiliau seccomp yn diffinio pa alwadau system y dylid eu caniatáu neu eu hanalluogi. Mae amser rhedeg y cynhwysydd yn eu actifadu pan fydd yn cychwyn fel y gall y cnewyllyn fonitro eu gweithrediad. Mae defnyddio proffiliau o'r fath yn caniatáu ichi gyfyngu ar y fector ymosodiad a lleihau difrod os bydd unrhyw raglen y tu mewn i'r cynhwysydd (hynny yw, eich dibyniaethau, neu eu dibyniaethau) yn dechrau gwneud rhywbeth na chaniateir iddo ei wneud.

Cyrraedd y pethau sylfaenol

Mae'r proffil seccomp sylfaenol yn cynnwys tair elfen: defaultAction, architectures (Neu archMap) A 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"
        }
    ]
}

(canolig-sylfaenol-seccomp.json)

defaultAction yn pennu tynged ddiofyn unrhyw alwad system nad yw wedi'i nodi yn yr adran syscalls. I wneud pethau'n haws, gadewch i ni ganolbwyntio ar y ddau brif werth a ddefnyddir:

  • SCMP_ACT_ERRNO - yn rhwystro gweithrediad galwad system,
  • SCMP_ACT_ALLOW - caniatáu.

Yn adran architectures rhestrir pensaernïaeth darged. Mae hyn yn bwysig oherwydd bod yr hidlydd ei hun, sy'n cael ei gymhwyso ar lefel y cnewyllyn, yn dibynnu ar ddynodwyr galwadau system, ac nid ar eu henwau a nodir yn y proffil. Bydd amser rhedeg y cynhwysydd yn cyfateb iddynt â dynodwyr cyn eu defnyddio. Y syniad yw y gall galwadau system gael IDau hollol wahanol yn dibynnu ar bensaernïaeth y system. Er enghraifft, galwad system recvfrom (a ddefnyddir i dderbyn gwybodaeth o'r soced) mae ID = 64 ar systemau x64 ac ID = 517 ar x86. Yma gallwch ddod o hyd i restr o'r holl alwadau system ar gyfer pensaernïaeth x86-x64.

Yn yr adran syscalls yn rhestru holl alwadau'r system ac yn nodi beth i'w wneud â nhw. Er enghraifft, gallwch greu rhestr wen trwy osod defaultAction ar SCMP_ACT_ERRNO, a galwadau yn yr adran syscalls aseinio SCMP_ACT_ALLOW. Felly, dim ond galwadau a nodir yn yr adran y byddwch yn eu caniatáu syscalls, a gwahardd pawb arall. Ar gyfer y rhestr ddu dylech newid y gwerthoedd defaultAction a gweithredoedd i'r gwrthwyneb.

Nawr dylem ddweud ychydig eiriau am arlliwiau nad ydynt mor amlwg. Sylwch fod yr argymhellion isod yn cymryd yn ganiataol eich bod yn defnyddio llinell o gymwysiadau busnes ar Kubernetes a'ch bod am iddynt redeg gyda'r nifer lleiaf o freintiau posibl.

1. CaniatáuPrivilegeEscalation=ffug

В securityContext mae gan y cynhwysydd baramedr AllowPrivilegeEscalation. Os caiff ei osod yn false, bydd cynwysyddion yn dechrau gyda (on) did no_new_priv. Mae ystyr y paramedr hwn yn amlwg o'r enw: mae'n atal y cynhwysydd rhag lansio prosesau newydd gyda mwy o freintiau nag sydd ganddo ei hun.

Sgîl-effaith yr opsiwn hwn yn cael ei osod i true (diofyn) yw bod yr amser rhedeg cynhwysydd yn cymhwyso'r proffil seccomp ar ddechrau'r broses gychwyn. Felly, rhaid galluogi pob galwad system sydd ei angen i redeg prosesau amser rhedeg mewnol (ee gosod ID defnyddiwr/grŵp, gollwng galluoedd penodol) yn y proffil.

I gynhwysydd sy'n gwneud pethau dibwys echo hi, bydd angen y caniatâd canlynol:

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

...yn lle'r rhain:

{
    "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-cynhwysydd-seccomp.json)

Ond eto, pam mae hyn yn broblem? Yn bersonol, byddwn yn osgoi rhestru'r galwadau system canlynol (oni bai bod gwir angen amdanynt): capset, set_tid_address, setgid, setgroups и setuid. Fodd bynnag, yr her wirioneddol yw eich bod, trwy ganiatáu prosesau nad oes gennych unrhyw reolaeth drostynt o gwbl, yn clymu proffiliau â gweithrediad amser rhedeg cynhwysydd. Mewn geiriau eraill, un diwrnod efallai y gwelwch, ar ôl diweddaru amgylchedd amser rhedeg y cynhwysydd (naill ai gennych chi neu, yn fwy tebygol, gan y darparwr gwasanaeth cwmwl), fod y cynwysyddion yn rhoi'r gorau i redeg yn sydyn.

Cyngor rhif 1: Rhedeg cynwysyddion gyda AllowPrivilegeEscaltion=false. Bydd hyn yn lleihau maint proffiliau seccomp ac yn eu gwneud yn llai sensitif i newidiadau yn amgylchedd amser rhedeg y cynhwysydd.

2. Gosod proffiliau seccomp ar lefel y cynhwysydd

Gellir gosod y proffil seccomp ar lefel y pod:

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

...neu ar lefel y cynhwysydd:

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

Sylwch y bydd y gystrawen uchod yn newid pan Kubernetes seccomp yn dod yn GA (disgwylir y digwyddiad hwn yn y datganiad nesaf o Kubernetes - 1.18 - tua. transl.).

Ychydig iawn o bobl sy'n gwybod bod Kubernetes wedi cael erioed byga achosodd i broffiliau seccomp gael eu cymhwyso i saib cynhwysydd. Mae'r amgylchedd amser rhedeg yn gwneud iawn yn rhannol am y diffyg hwn, ond nid yw'r cynhwysydd hwn yn diflannu o'r codennau, gan ei fod yn cael ei ddefnyddio i ffurfweddu eu seilwaith.

Y broblem yw bod y cynhwysydd hwn bob amser yn dechrau AllowPrivilegeEscalation=true, gan arwain at y problemau a leisiwyd ym mharagraff 1, ac ni ellir newid hyn.

Trwy ddefnyddio proffiliau seccomp ar lefel y cynhwysydd, rydych chi'n osgoi'r perygl hwn ac yn gallu creu proffil sydd wedi'i deilwra i gynhwysydd penodol. Bydd yn rhaid gwneud hyn nes bod y datblygwyr yn trwsio'r nam a'r fersiwn newydd (efallai 1.18?) ar gael i bawb.

Cyngor rhif 2: Gosodwch broffiliau seccomp ar lefel y cynhwysydd.

Mewn ystyr ymarferol, mae'r rheol hon fel arfer yn ateb cyffredinol i'r cwestiwn: “Pam mae fy mhroffil seccomp yn gweithio gyda docker runond ddim yn gweithio ar ôl anfon i glwstwr Kubernetes?

3. Defnyddiwch amser rhedeg/diofyn yn unig fel dewis olaf

Mae gan Kubernetes ddau opsiwn ar gyfer proffiliau adeiledig: runtime/default и docker/default. Mae'r ddau yn cael eu gweithredu gan yr amser rhedeg cynhwysydd, nid Kubernetes. Felly, gallant fod yn wahanol yn dibynnu ar yr amgylchedd amser rhedeg a ddefnyddir a'i fersiwn.

Mewn geiriau eraill, o ganlyniad i newid amser rhedeg, efallai y bydd gan y cynhwysydd fynediad at set wahanol o alwadau system, y gall eu defnyddio neu beidio. Mae'r rhan fwyaf o amseroedd rhedeg yn defnyddio Gweithredu docwr. Os dymunwch ddefnyddio'r proffil hwn, sicrhewch ei fod yn addas i chi.

Proffil docker/default wedi'i anghymeradwyo ers Kubernetes 1.11, felly ceisiwch osgoi ei ddefnyddio.

Yn fy marn i, proffil runtime/default yn berffaith addas ar gyfer y pwrpas y cafodd ei greu ar ei gyfer: amddiffyn defnyddwyr rhag y risgiau sy'n gysylltiedig â gweithredu gorchymyn docker run ar eu ceir. Fodd bynnag, o ran cymwysiadau busnes sy'n rhedeg ar glystyrau Kubernetes, byddwn yn meiddio dadlau bod proffil o'r fath yn rhy agored a dylai datblygwyr ganolbwyntio ar greu proffiliau ar gyfer eu cymwysiadau (neu fathau o gymwysiadau).

Cyngor rhif 3: Creu proffiliau seccomp ar gyfer ceisiadau penodol. Os nad yw hyn yn bosibl, crëwch broffiliau ar gyfer mathau o geisiadau, er enghraifft, crëwch broffil uwch sy'n cynnwys holl APIs gwe cymhwysiad Golang. Defnyddiwch amser rhedeg/diofyn fel y dewis olaf yn unig.

Mewn swyddi yn y dyfodol, byddaf yn ymdrin â sut i greu proffiliau seccomp wedi'u hysbrydoli gan SecDevOps, eu hawtomeiddio, a'u profi ar y gweill. Mewn geiriau eraill, ni fydd gennych unrhyw esgus i beidio ag uwchraddio i broffiliau cais-benodol.

4. NID yw Unconfined yn opsiwn.

O'r archwiliad diogelwch Kubernetes cyntaf mae'n troi allan bod yn ddiofyn seccomp anabl. Mae hyn yn golygu os nad ydych yn gosod PodSecurityPolicy, a fydd yn ei alluogi yn y clwstwr, bydd pob cod nad yw'r proffil seccom wedi'i ddiffinio ar ei gyfer yn gweithio ynddo seccomp=unconfined.

Mae gweithredu yn y modd hwn yn golygu bod haen gyfan o inswleiddio yn cael ei golli sy'n amddiffyn y clwstwr. Nid yw arbenigwyr diogelwch yn argymell y dull hwn.

Cyngor rhif 4: Ni ddylai unrhyw gynhwysydd yn y clwstwr fod yn rhedeg i mewn seccomp=unconfined, yn enwedig mewn amgylcheddau cynhyrchu.

5. "Modd archwilio"

Nid yw'r pwynt hwn yn unigryw i Kubernetes, ond mae'n dal i fod yn y categori “pethau i'w gwybod cyn i chi ddechrau”.

Fel mae'n digwydd, mae creu proffiliau seccomp bob amser wedi bod yn heriol ac yn dibynnu'n fawr ar brofi a methu. Y ffaith yw nad yw defnyddwyr yn cael y cyfle i'w profi mewn amgylcheddau cynhyrchu heb fentro “gollwng” y cymhwysiad.

Ar ôl rhyddhau cnewyllyn Linux 4.14, daeth yn bosibl rhedeg rhannau o broffil yn y modd archwilio, gan gofnodi gwybodaeth am yr holl alwadau system yn syslog, ond heb eu rhwystro. Gallwch chi actifadu'r modd hwn gan ddefnyddio'r paramedr SCMT_ACT_LOG:

SCMP_ACT_LOG: ni fydd seccomp yn effeithio ar yr edefyn sy'n gwneud y system yn galw os nad yw'n cyd-fynd ag unrhyw reol yn yr hidlydd, ond bydd gwybodaeth am alwad y system yn cael ei chofnodi.

Dyma strategaeth nodweddiadol ar gyfer defnyddio'r nodwedd hon:

  1. Caniatáu galwadau system sydd eu hangen.
  2. Bloc galwadau o'r system y gwyddoch na fydd yn ddefnyddiol.
  3. Cofnodi gwybodaeth am yr holl alwadau eraill yn y log.

Mae enghraifft symlach yn edrych fel hyn:

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

(canolig-cymysg-seccomp.json)

Ond cofiwch fod angen i chi rwystro pob galwad y gwyddoch na fydd yn cael ei defnyddio ac a allai niweidio'r clwstwr. Sail dda ar gyfer llunio rhestr yw'r swyddog Dogfennaeth docwr. Mae'n esbonio'n fanwl pa alwadau system sy'n cael eu rhwystro yn y proffil rhagosodedig a pham.

Fodd bynnag, mae un dal. Er SCMT_ACT_LOG wedi'i gefnogi gan y cnewyllyn Linux ers diwedd 2017, dim ond yn gymharol ddiweddar y daeth i mewn i ecosystem Kubernetes. Felly, i ddefnyddio'r dull hwn bydd angen fersiwn cnewyllyn Linux 4.14 a runC ddim yn is v1.0.0-rc9.

Cyngor rhif 5: Gellir creu proffil modd archwilio ar gyfer profi mewn cynhyrchiad trwy gyfuno rhestrau du a gwyn, a gellir cofnodi pob eithriad.

6. Defnyddiwch restrau gwyn

Mae angen ymdrech ychwanegol ar restr wen oherwydd mae'n rhaid i chi nodi pob galwad y gallai fod ei hangen ar y rhaglen, ond mae'r dull hwn yn gwella diogelwch yn fawr:

Argymhellir yn gryf defnyddio'r dull rhestr wen gan ei fod yn symlach ac yn fwy dibynadwy. Bydd angen diweddaru'r rhestr ddu pryd bynnag yr ychwanegir galwad system a allai fod yn beryglus (neu faner/opsiwn peryglus os yw ar y rhestr ddu). Yn ogystal, mae'n aml yn bosibl newid cynrychiolaeth paramedr heb newid ei hanfod a thrwy hynny osgoi cyfyngiadau'r rhestr ddu.

Ar gyfer cymwysiadau Go, datblygais offeryn arbennig sy'n cyd-fynd â'r cais ac sy'n casglu'r holl alwadau a wneir yn ystod y gweithredu. Er enghraifft, ar gyfer y cais canlynol:

package main

import "fmt"

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

... gadewch i ni lansio gosystract fel hyn:

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

... a chawn y canlyniad canlynol:

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

Am y tro, dim ond enghraifft yw hon - bydd mwy o fanylion am yr offer yn dilyn.

Cyngor rhif 6: Caniatewch y galwadau hynny sydd eu hangen arnoch chi mewn gwirionedd a rhwystrwch bob un arall.

7. Gosod y sylfeini cywir (neu baratoi ar gyfer ymddygiad annisgwyl)

Bydd y cnewyllyn yn gorfodi'r proffil waeth beth rydych chi'n ei ysgrifennu ynddo. Hyd yn oed os nad dyna'n union yr oeddech chi ei eisiau. Er enghraifft, os ydych yn rhwystro mynediad i alwadau fel exit neu exit_group, ni fydd y cynhwysydd yn gallu cau i lawr yn gywir a hyd yn oed gorchymyn syml fel echo hi hongian ef i fynyo am gyfnod amhenodol. O ganlyniad, byddwch yn cael defnydd CPU uchel yn y clwstwr:

Seccomp yn Kubernetes: 7 peth y mae angen i chi eu gwybod o'r cychwyn cyntaf

Mewn achosion o'r fath, gall cyfleustodau ddod i'r adwy strace - bydd yn dangos beth allai'r broblem fod:

Seccomp yn Kubernetes: 7 peth y mae angen i chi eu gwybod o'r cychwyn cyntaf
sudo strace -c -p 9331

Sicrhewch fod y proffiliau'n cynnwys yr holl alwadau system sydd eu hangen ar y rhaglen ar amser rhedeg.

Cyngor rhif 7: Rhowch sylw i fanylion a gwnewch yn siŵr bod yr holl alwadau system angenrheidiol ar y rhestr wen.

Mae hwn yn cloi rhan gyntaf cyfres o erthyglau ar ddefnyddio seccomp yn Kubernetes yn ysbryd SecDevOps. Yn y rhannau canlynol byddwn yn siarad am pam mae hyn yn bwysig a sut i awtomeiddio'r broses.

PS gan y cyfieithydd

Darllenwch hefyd ar ein blog:

Ffynhonnell: hab.com

Ychwanegu sylw