Kynning á netstefnu Kubernetes fyrir öryggissérfræðinga
Athugið. þýð.: Höfundur greinarinnar, Reuven Harrison, hefur yfir 20 ára reynslu af hugbúnaðarþróun og er í dag tæknistjóri og annar stofnandi Tufin, fyrirtækis sem býr til lausnir fyrir stjórnun öryggisstefnu. Þó að hann líti á Kubernetes netstefnur sem nokkuð öflugt tæki til að skiptast á netkerfi í klasa, telur hann einnig að þær séu ekki svo auðvelt að framkvæma í reynd. Þessu efni (nokkuð umfangsmikið) er ætlað að auka vitund sérfræðinga um þetta mál og hjálpa þeim að búa til nauðsynlegar stillingar.
Í dag eru mörg fyrirtæki í auknum mæli að velja Kubernetes til að keyra forritin sín. Áhugi á þessum hugbúnaði er svo mikill að sumir kalla Kubernetes „nýja stýrikerfið fyrir gagnaverið. Smám saman er farið að líta á Kubernetes (eða k8s) sem mikilvægan hluta fyrirtækisins, sem krefst skipulags þroskaðra viðskiptaferla, þar með talið netöryggis.
Fyrir öryggissérfræðinga sem eru undrandi á því að vinna með Kubernetes gæti raunverulega opinberunin verið sjálfgefin stefna vettvangsins: leyfðu allt.
Þessi handbók mun hjálpa þér að skilja innri uppbyggingu netstefnu; skilja hvernig þeir eru frábrugðnir reglum um venjulega eldveggi. Það mun einnig fjalla um nokkrar gildrur og veita ráðleggingar til að tryggja öryggi forrita á Kubernetes.
Netkerfi Kubernetes
Kubernetes netkerfiskerfi gerir þér kleift að stjórna samskiptum forrita sem eru sett á vettvang á netlaginu (það þriðja í OSI líkaninu). Netstefnur skortir suma af háþróaðri eiginleikum nútíma eldvegga, eins og OSI Layer 7 framfylgd og ógnunarskynjun, en þær veita grunnstig netöryggis sem er góður upphafspunktur.
Netstefnur stjórna samskiptum milli belg
Vinnuálagi í Kubernetes er dreift yfir belg, sem samanstanda af einum eða fleiri gámum sem dreift er saman. Kubernetes úthlutar hverjum pod IP-tölu sem er aðgengileg frá öðrum pods. Netstefnur Kubernetes setja aðgangsrétt fyrir hópa af belgjum á sama hátt og öryggishópar í skýinu eru notaðir til að stjórna aðgangi að sýndarvélatilvikum.
Skilgreina netstefnur
Eins og önnur Kubernetes tilföng eru netstefnur tilgreindar í YAML. Í dæminu hér að neðan, forritið balance aðgangur að postgres:
(Athugið. þýð.: þetta skjáskot, eins og allar síðari svipaðar myndir, var ekki búið til með innfæddum Kubernetes verkfærum, heldur með Tufin Orca verkfærinu, sem var þróað af fyrirtæki höfundar upprunalegu greinarinnar og sem getið er um í lok efnisins.)
Til að skilgreina þína eigin netstefnu þarftu grunnþekkingu á YAML. Þetta tungumál er byggt á inndrætti (tilgreint með bilum frekar en flipa). Inndreginn þáttur tilheyrir næsta inndreginni einingu fyrir ofan það. Nýr listaþáttur byrjar á bandstrik, allir aðrir þættir hafa formið lykilgildi.
Eftir að hafa lýst stefnunni í YAML, notaðu kubectltil að búa það til í þyrpingunni:
kubectl create -f policy.yaml
Forskrift netstefnu
Forskrift Kubernetes netkerfis inniheldur fjóra þætti:
podSelector: skilgreinir belg sem hafa áhrif á þessa stefnu (markmið) - krafist;
policyTypes: gefur til kynna hvaða tegundir stefnur eru innifalin í þessu: inngangur og/eða útgangur - valfrjálst, en ég mæli með því að það sé tilgreint sérstaklega í öllum tilvikum;
ingress: skilgreinir leyfilegt komandi umferð til miðbelgs - valfrjálst;
egress: skilgreinir leyfilegt fráfarandi umferð frá markhópum er valfrjáls.
Dæmi tekið af Kubernetes vefsíðunni (ég skipti út role á app), sýnir hvernig allir fjórir þættirnir eru notaðir:
Athugið að allir fjórir þættirnir þurfa ekki að vera með. Það er aðeins skylda podSelector, aðrar breytur er hægt að nota að vild.
Ef þú sleppir policyTypes, verður stefnan túlkuð sem hér segir:
Sjálfgefið er gert ráð fyrir að það skilgreini inngönguhliðina. Ef það er ekki tekið skýrt fram í stefnunni mun kerfið gera ráð fyrir að öll umferð sé bönnuð.
Hegðun útgönguhliðarinnar verður ákvörðuð af tilvist eða fjarveru samsvarandi útgöngufæribreytu.
Til að forðast mistök mæli ég með gerðu það alltaf skýrt policyTypes.
Samkvæmt ofangreindri rökfræði, ef breytur ingress og / eða egress sleppt, mun stefnan hafna allri umferð (sjá "Afnámsreglu" hér að neðan).
Sjálfgefin regla er Leyfa
Ef engar reglur eru skilgreindar leyfir Kubernetes alla umferð sjálfgefið. Allir belg geta frjálslega skipt á upplýsingum sín á milli. Þetta kann að virðast ósanngjarnt frá öryggissjónarmiði, en mundu að Kubernetes var upphaflega hannað af hönnuðum til að gera samvirkni forrita kleift. Netreglum var bætt við síðar.
Nafnarými
Nafnarými eru Kubernetes samstarfskerfið. Þau eru hönnuð til að einangra rökrétt umhverfi frá hvort öðru, en samskipti milli rýma eru sjálfgefið leyfð.
Eins og flestir Kubernetes íhlutir búa netstefnur í ákveðnu nafnrými. Í blokkinni metadata þú getur tilgreint hvaða svæði stefnan tilheyrir:
Ef nafnrýmið er ekki sérstaklega tilgreint í lýsigögnunum mun kerfið nota nafnrýmið sem tilgreint er í kubectl (sjálfgefið namespace=default):
kubectl apply -n my-namespace -f namespace.yaml
ég mæli með tilgreinið nafnrými sérstaklega, nema þú sért að skrifa stefnu sem miðar á mörg nafnrými í einu.
Primary frumefni podSelector í reglunni mun velja belg úr nafnrýminu sem stefnan tilheyrir (það er meinaður aðgangur að belg frá öðru nafnrými).
Á sama hátt, podSelectors í inn- og útgöngublokkum getur aðeins valið belg úr eigin nafnrými, nema auðvitað þú sameinar þá með namespaceSelector (Fjallað verður um þetta í kaflanum „Sía eftir nafnasvæðum og belgjum“).
Nafnareglur stefnu
Stefnanöfn eru einstök innan sama nafnarýmis. Það geta ekki verið tvær stefnur með sama nafni í sama rými, en það geta verið stefnur með sama nafni í mismunandi rýmum. Þetta er gagnlegt þegar þú vilt nota sömu stefnu aftur á mörgum svæðum.
Mér líkar sérstaklega við eina af nafnaaðferðunum. Það samanstendur af því að sameina nafnrýmið með markhópnum. Til dæmis:
Þú getur fest sérsniðna merkimiða við Kubernetes hluti, svo sem belg og nafnrými. Merki (merki - tags) eru ígildi merkja í skýinu. Kubernetes netkerfi nota merki til að velja fræbelgursem þau eiga við um:
podSelector:
matchLabels:
role: db
… eða nafnarýmisem þau eiga við um. Þetta dæmi velur alla belg í nafnasvæðum með samsvarandi merki:
Ein varúð: við notkun namespaceSelectorvertu viss um að nafnrýmin sem þú velur innihaldi réttan merkimiða. Vertu meðvituð um að innbyggð nafnarými eins og default и kube-system, sjálfgefið innihalda ekki merki.
Þú getur bætt merkimiða við svæði eins og þetta:
kubectl label namespace default namespace=default
Á sama tíma, nafnrými í hlutanum metadata ætti að vísa til raunverulegs nafns svæðis, ekki merkimiðans:
Eldveggsreglur samanstanda af reglum með heimildum og áfangastöðum. Kubernetes netkerfisreglur eru skilgreindar fyrir markmið - safn af belgjum sem þær eiga við - og setja síðan reglur fyrir inn- og/eða útgönguumferð. Í dæminu okkar mun markmið stefnunnar vera öll belg í nafnarýminu default með merkimiða með lykli app og merkingu db:
Undirkafli ingress í þessari stefnu opnar komandi umferð að markhópnum. Með öðrum orðum, innrás er uppspretta og markmið er samsvarandi áfangastaður. Sömuleiðis er útgangur áfangastaðurinn og markmiðið er uppspretta þess.
Þetta jafngildir tveimur eldveggsreglum: Ingress → Target; Markmið → Útgangur.
Egress og DNS (mikilvægt!)
Með því að takmarka útleið, huga sérstaklega að DNS - Kubernetes notar þessa þjónustu til að kortleggja þjónustu á IP tölur. Til dæmis mun eftirfarandi regla ekki virka vegna þess að þú hefur ekki leyft forritið balance fá aðgang að DNS:
Síðasti þáttur to er tómt, og þess vegna velur það óbeint allir belg í öllum nafnasvæðum, leyfa balance sendu DNS fyrirspurnir til viðeigandi Kubernetes þjónustu (venjulega keyrandi í rýminu kube-system).
Þessi aðferð virkar, hvernig sem hún er of leyfilegt og óöruggt, vegna þess að það gerir kleift að beina DNS fyrirspurnum út fyrir klasann.
Þú getur bætt það í þremur skrefum í röð.
1. Leyfa aðeins DNS fyrirspurnir innan þyrping með því að bæta við namespaceSelector:
2. Leyfa aðeins DNS fyrirspurnir innan nafnarýmis kube-system.
Til að gera þetta þarftu að bæta merki við nafnrýmið kube-system: kubectl label namespace kube-system namespace=kube-system - og skrifaðu það niður í stefnu með því að nota namespaceSelector:
3. Paranoid fólk getur gengið enn lengra og takmarkað DNS fyrirspurnir við tiltekna DNS þjónustu í kube-system. Hlutinn „Sía eftir nafnasvæðum OG belgjum“ mun segja þér hvernig á að ná þessu.
Annar valkostur er að leysa DNS á nafnrýmisstigi. Í þessu tilviki þarf ekki að opna það fyrir hverja þjónustu:
Í hefðbundnum eldveggjum er aðgerðin (Leyfa eða neita) á pakka ákvörðuð af fyrstu reglunni sem hann uppfyllir. Í Kubernetes skiptir röð stefnunnar ekki máli.
Sjálfgefið er, þegar engar reglur eru stilltar, eru samskipti á milli hólf leyfð og þeir geta frjálslega skiptst á upplýsingum. Þegar þú byrjar að móta stefnur, verður hver belg sem hefur áhrif á að minnsta kosti einni þeirra einangruð í samræmi við sundurliðun (rökrétt OR) allra reglna sem völdu hann. Pods sem engin stefnu hefur áhrif á eru áfram opnir.
Þú getur breytt þessari hegðun með því að nota strikunarreglu.
Afnámsregla („Neita“)
Eldveggsreglur neita venjulega allri umferð sem er ekki beinlínis leyfð.
Það er ekki neitað aðgerðir í KubernetesHins vegar er hægt að ná fram svipuðum áhrifum með venjulegri (leyfandi) stefnu með því að velja tóman hóp af upptökum (inngangur):
Vinsamlegast athugaðu það Allar viðbótarreglur sem leyfa umferð um belg í nafnarýminu munu hafa forgang fram yfir þessa reglu (svipað og að bæta leyfisreglu á undan neitunarreglu í eldveggsstillingu).
Leyfa allt (Any-Any-Any-Allow)
Til að búa til Leyfa allt stefnu þarftu að bæta við neita stefnunni hér að ofan með tómum þætti ingress:
Það veitir aðgang frá allir pods í öllum nafnasvæðum (og öllum IP) í hvaða pod sem er í nafnarýminu default. Þessi hegðun er sjálfkrafa virkjuð, svo það þarf venjulega ekki að skilgreina hana frekar. Hins vegar gætirðu stundum þurft að slökkva tímabundið á sérstökum heimildum til að greina vandamálið.
Hægt er að þrengja regluna til að leyfa aðeins aðgang að ákveðið sett af belgjum (app:balance) í nafnarýminu default:
Stefna er sameinuð með því að nota rökrétt OR á þremur stigum; Heimildir hvers hólfs eru stilltar í samræmi við sundurliðun allra reglna sem hafa áhrif á hann:
1. Á ökrunum from и to Hægt er að skilgreina þrjár gerðir af þáttum (sem allir eru sameinaðir með OR):
namespaceSelector — velur allt nafnrýmið;
podSelector — velur belg;
ipBlock — velur undirnet.
Þar að auki, fjöldi þátta (jafnvel eins) í undirköflum from/to ekki takmarkað. Öll þau verða sameinuð með rökréttri OR.
2. Inni í stefnuhlutanum ingress getur haft marga þætti from (samsett með rökréttum OR). Á sama hátt, kafla egress geta innihaldið marga þætti to (einnig sameinað með sundrun):
3. Mismunandi stefnur eru líka sameinuð rökréttri OR
En þegar þeir sameina þá er ein takmörkun á því benti áChris Cooney: Kubernetes getur aðeins sameinað stefnur með mismunandi policyTypes (Ingress eða Egress). Stefna sem skilgreina inngöngu (eða útgöngu) munu skrifa yfir hver aðra.
Tengsl milli nafnrýma
Sjálfgefið er að upplýsingamiðlun milli nafnarúma er leyfð. Þessu er hægt að breyta með því að nota neitunarstefnu sem mun takmarka umferð sem fer út og/eða inn í nafnarýmið (sjá „Afnámsreglu“ hér að ofan).
Þegar þú hefur lokað fyrir aðgang að nafnrými (sjá „afnámsregluna“ hér að ofan), geturðu gert undantekningar frá neitunarreglunni með því að leyfa tengingar frá tilteknu nafnrými með því að nota namespaceSelector:
Þar af leiðandi eru allir belg í nafnarýminu default mun hafa aðgang að belgjum postgres í nafnrými database. En hvað ef þú vilt opna aðgang að postgres aðeins tilteknir belg í nafnrýminu default?
Sía eftir nafnasvæðum og belgjum
Kubernetes útgáfa 1.11 og nýrri gerir þér kleift að sameina rekstraraðila namespaceSelector и podSelector með því að nota rökrétt OG. Það lítur svona út:
Af hverju er þetta túlkað sem OG í stað venjulegs OR?
takið eftir því podSelector byrjar ekki á bandstrik. Í YAML þýðir þetta það podSelector og stóð fyrir framan hann namespaceSelector vísa til sama listaþáttar. Þess vegna eru þau sameinuð með rökréttum OG.
Að bæta við bandstrik áður podSelector mun leiða til þess að nýr listaþáttur verður til, sem verður sameinaður þeim fyrri namespaceSelector nota rökrétt OR.
Til að velja belg með ákveðnu merki í öllum nafnasvæðum, sláðu inn autt namespaceSelector:
Reglur fyrir eldvegg með mörgum hlutum (hýsingar, netkerfi, hópar) eru sameinuð með því að nota rökrétt OR. Eftirfarandi regla mun virka ef uppspretta pakka passar Host_1 Eða Host_2:
Þvert á móti, í Kubernetes eru hin ýmsu merki í podSelector eða namespaceSelector eru sameinuð rökréttum OG. Til dæmis mun eftirfarandi regla velja belg sem hafa bæði merki, role=db И version=v2:
podSelector:
matchLabels:
role: db
version: v2
Sama rökfræði á við um allar gerðir rekstraraðila: stefnumarkavalara, hólfveljara og nafnrýmisveljara.
Undirnet og IP tölur (IPBlocks)
Eldveggir nota VLAN, IP tölur og undirnet til að skipta upp neti.
Í Kubernetes er IP vistföngum sjálfkrafa úthlutað til belgjum og geta breyst oft, þannig að merki eru notuð til að velja belg og nafnrými í netstefnu.
Undirnet (ipBlocks) eru notaðar þegar stjórnað er innkomnum (inngangur) eða útleiðandi (útgangur) ytri (Norður-Suður) tengingar. Til dæmis opnast þessi regla fyrir alla belg úr nafnarýminu default aðgangur að Google DNS þjónustu:
Tómi belgvalsinn í þessu dæmi þýðir „velja alla belg í nafnrýminu“.
Þessi stefna leyfir aðeins aðgang að 8.8.8.8; aðgangur að öðrum IP er bannaður. Svo í rauninni hefurðu lokað fyrir aðgang að innri Kubernetes DNS þjónustunni. Ef þú vilt samt opna það skaltu tilgreina það sérstaklega.
Venjulega ipBlocks и podSelectors útiloka gagnkvæmt, þar sem innri IP tölur fræbelgs eru ekki notaðar í ipBlocks. Með því að gefa til kynna innri IP-belg, þú munt í raun leyfa tengingar til/frá belg með þessum netföngum. Í reynd muntu ekki vita hvaða IP tölu þú átt að nota, þess vegna ætti ekki að nota þær til að velja belg.
Sem gagndæmi inniheldur eftirfarandi stefna allar IP-tölur og leyfir því aðgang að öllum öðrum belgjum:
Venjulega hlusta fræbelgir á eina höfn. Þetta þýðir að þú getur einfaldlega ekki tilgreint gáttanúmer í stefnum og látið allt vera sjálfgefið. Hins vegar er mælt með því að gera reglur eins takmarkandi og mögulegt er, þannig að í sumum tilfellum geturðu samt tilgreint hafnir:
Athugið að valinn ports á við um alla þætti í reitnum to eða from, sem inniheldur. Til að tilgreina mismunandi tengi fyrir mismunandi sett af þáttum, skiptu ingress eða egress í nokkra undirkafla með to eða from og í hverri skráningu hafnanna þinna:
Ef þú sleppir gáttaskilgreiningunni alveg (ports), þetta þýðir allar samskiptareglur og allar hafnir;
Ef þú sleppir samskiptaskilgreiningunni (protocol), þetta þýðir TCP;
Ef þú sleppir portskilgreiningunni (port), þetta þýðir allar hafnir.
Bestu starfsvenjur: Ekki treysta á sjálfgefin gildi, tilgreindu það sem þú þarft sérstaklega.
Vinsamlegast athugaðu að þú verður að nota pod tengi, ekki þjónustutengi (meira um þetta í næstu málsgrein).
Eru reglur skilgreindar fyrir belg eða þjónustu?
Venjulega hafa belg í Kubernetes aðgang hver að öðrum í gegnum þjónustu - sýndarhleðslujafnari sem vísar umferð til belganna sem innleiða þjónustuna. Þú gætir haldið að netstefnur stjórni aðgangi að þjónustu, en svo er ekki. Kubernetes netstefnur virka á pod-höfnum, ekki þjónustuhöfnum.
Til dæmis, ef þjónusta hlustar á gátt 80, en vísar umferð á gátt 8080 af belgjum sínum, verður þú að tilgreina nákvæmlega 8080 í netstefnunni.
Slíkt fyrirkomulag ætti að teljast óákjósanlegt: ef innri uppbygging þjónustunnar (hafnirnar sem fræbelgir hlusta á) breytist, verður að uppfæra netstefnur.
Ný arkitektúrfræðileg nálgun með Service Mesh (sjá til dæmis um Istio hér að neðan - u.þ.b. þýðing) gerir þér kleift að takast á við þetta vandamál.
Er nauðsynlegt að skrá bæði Ingress og Egress?
Stutta svarið er já, til þess að belg A geti átt samskipti við belg B verður það að vera leyft að búa til sendan tengingu (til þess þarftu að stilla útgöngustefnu) og bekkur B verður að geta tekið við tengingu á leið ( til þess, í samræmi við það, þarftu inngöngustefnu).
Hins vegar, í reynd, getur þú treyst á sjálfgefna stefnu til að leyfa tengingar í aðra eða báðar áttir.
Ef einhver fræbelgur-uppspretta verður valinn af einum eða fleiri útgangur-stjórnmálamenn, þær takmarkanir sem á það eru settar ráðast af sundrun þeirra. Í þessu tilviki þarftu sérstaklega að leyfa tengingu við hólfið -til viðtakanda. Ef belg er ekki valið af neinni reglu er útleið (útgang) umferð hans leyfð sjálfgefið.
Á sama hátt eru örlög belgsinsviðtakanda, valinn af einum eða fleiri innrás-stjórnmálamenn, mun ráðast af sundrungu þeirra. Í þessu tilviki verður þú sérstaklega að leyfa því að taka á móti umferð frá upprunabelgnum. Ef belg er ekki valið af neinni stefnu er öll innkomin umferð fyrir hann sjálfgefið leyfð.
Sjá Stateful eða Stateless hér að neðan.
Logs
Kubernetes netkerfi geta ekki skráð umferð. Þetta gerir það að verkum að erfitt er að ákvarða hvort stefna virkar eins og til er ætlast og flækir öryggisgreiningu mjög.
Eftirlit með umferð til ytri þjónustu
Netstefnur Kubernetes leyfa þér ekki að tilgreina fullgilt lén (DNS) í útgönguhlutum. Þessi staðreynd leiðir til verulegs óþæginda þegar reynt er að takmarka umferð til ytri áfangastaða sem eru ekki með fasta IP tölu (eins og aws.com).
Stefnuskoðun
Eldveggir munu vara þig við eða jafnvel neita að samþykkja ranga stefnu. Kubernetes gerir einnig nokkra sannprófun. Þegar netstefna er sett í gegnum kubectl getur Kubernetes lýst því yfir að hún sé röng og neitað að samþykkja hana. Í öðrum tilvikum mun Kubernetes taka stefnuna og fylla hana út með þeim upplýsingum sem vantar. Þau má sjá með því að nota skipunina:
kubernetes get networkpolicy <policy-name> -o yaml
Hafðu í huga að Kubernetes staðfestingarkerfið er ekki óskeikult og gæti misst af einhverjum villum.
Framkvæmd
Kubernetes innleiðir ekki netstefnur sjálft, heldur er aðeins API-gátt sem framselur íþyngjandi framfylgdarvinnu til undirliggjandi kerfis sem kallast Container Networking Interface (CNI). Að setja stefnur á Kubernetes klasa án þess að úthluta viðeigandi CNI er það sama og að búa til stefnur á eldveggsstjórnunarþjóni án þess að setja þær síðan upp á eldveggi. Það er undir þér komið að tryggja að þú sért með viðeigandi CNI eða, ef um Kubernetes palla er að ræða, hýst í skýinu (þú getur séð lista yfir veitendur hér — ca. þýð.), virkjaðu netstefnur sem stilla CNI fyrir þig.
Athugaðu að Kubernetes mun ekki vara þig við ef þú stillir netstefnu án viðeigandi hjálpar CNI.
Ríkilegur eða ríkisfangslaus?
Allar Kubernetes CNIs sem ég hef kynnst eru staðhæfar (til dæmis, Calico notar Linux conntrack). Þetta gerir hólfinu kleift að fá svör við TCP-tengingunni sem það kom af stað án þess að þurfa að koma henni á aftur. Hins vegar er mér ekki kunnugt um Kubernetes staðal sem myndi tryggja yfirlýsingu.
Ítarlegri öryggisstefnustjórnun
Hér eru nokkrar leiðir til að bæta framfylgd öryggisstefnu í Kubernetes:
Byggingarmynstrið Service Mesh notar hliðarvagnagáma til að veita nákvæma fjarmælingu og umferðarstjórnun á þjónustustigi. Sem dæmi getum við tekið Sama.
Sumir CNI framleiðendur hafa útvíkkað verkfæri sín til að fara lengra en Kubernetes netstefnur.
Tufin Orca Veitir sýnileika og sjálfvirkni Kubernetes netstefnu.
Tufin Orca pakkinn stjórnar Kubernetes netstefnu (og er uppspretta skjámyndanna hér að ofan).
Kubernetes netstefnur bjóða upp á gott sett af verkfærum til að skipta klasa, en þau eru ekki leiðandi og hafa marga fínleika. Vegna þessa flókna tel ég að margar núverandi klasastefnur séu gallaðar. Mögulegar lausnir á þessu vandamáli eru meðal annars að gera stefnuskilgreiningar sjálfvirkar eða nota önnur skiptingartæki.
Ég vona að þessi handbók hjálpi til við að skýra nokkrar spurningar og leysa vandamál sem þú gætir lent í.