Märge. tõlge: Artikli autoril Reuven Harrisonil on üle 20-aastane tarkvaraarenduse kogemus ning täna on ta turvapoliitika halduslahendusi loova ettevõtte Tufin CTO ja kaasasutaja. Kuigi ta peab Kubernetese võrgupoliitikaid üsna võimsaks vahendiks võrgu segmenteerimiseks klastris, usub ta ka, et neid pole praktikas nii lihtne rakendada. See materjal (üsna mahukas) on mõeldud selleks, et tõsta spetsialistide teadlikkust sellest probleemist ja aidata neil luua vajalikke konfiguratsioone.
Tänapäeval valivad paljud ettevõtted oma rakenduste käitamiseks üha enam Kubernetese. Huvi selle tarkvara vastu on nii suur, et mõned kutsuvad Kubernetest andmekeskuse uueks operatsioonisüsteemiks. Järk-järgult hakatakse Kubernetest (ehk k8-d) pidama ettevõtte kriitiliseks osaks, mis nõuab küpsete äriprotsesside, sealhulgas võrguturbe korraldamist.
Turvaspetsialistide jaoks, kes on Kubernetesega töötamisest hämmingus, võib tõeliseks ilmutuseks olla platvormi vaikepoliitika: lubage kõike.
See juhend aitab teil mõista võrgupoliitika sisemist struktuuri; mõista, kuidas need erinevad tavaliste tulemüüride reeglitest. See hõlmab ka mõningaid lõkse ja annab soovitusi Kubernetese rakenduste kaitsmiseks.
Kubernetese võrgupoliitikad
Kubernetese võrgupoliitika mehhanism võimaldab hallata platvormil juurutatud rakenduste suhtlust võrgukihis (kolmas OSI mudelis). Võrgupoliitikatel puuduvad mõned kaasaegsete tulemüüride täiustatud funktsioonid, nagu OSI Layer 7 jõustamine ja ohutuvastus, kuid need pakuvad võrguturbe põhitaset, mis on hea lähtepunkt.
Võrgupoliitikad kontrollivad kaustade vahelist suhtlust
Kubernetese töökoormused on jaotatud kaustade vahel, mis koosnevad ühest või mitmest koos juurutatud konteinerist. Kubernetes määrab igale kaustale IP-aadressi, millele pääseb juurde teistest kaustadest. Kubernetese võrgupoliitikad määravad kaubikute rühmadele juurdepääsuõigused samal viisil, nagu pilves olevaid turberühmi kasutatakse virtuaalse masina eksemplaridele juurdepääsu juhtimiseks.
Võrgupoliitika määratlemine
Sarnaselt teistele Kubernetese ressurssidele on võrgupoliitikad määratud YAML-is. Allolevas näites rakendus balance juurdepääsu postgres:
(Märge. tõlge: see ekraanipilt, nagu ka kõik järgnevad sarnased, ei loodud Kubernetese natiivsete tööriistade abil, vaid Tufin Orca tööriista abil, mille töötas välja algse artikli autori ettevõte ja mida mainitakse materjali lõpus.)
Enda võrgupoliitika määratlemiseks vajate YAMLi põhiteadmisi. See keel põhineb taandel (määratud pigem tühikute kui tabeldusmärkidega). Treppitud element kuulub lähima taandega elemendi juurde selle kohal. Uus loendielement algab sidekriipsuga, kõigil teistel elementidel on vorm võtmeväärtus.
Olles kirjeldanud poliitikat YAML-is, kasutage kubectlselle klastris loomiseks tehke järgmist.
kubectl create -f policy.yaml
Võrgupoliitika spetsifikatsioon
Kubernetese võrgupoliitika spetsifikatsioon sisaldab nelja elementi:
podSelector: määratleb kaustad, mida see poliitika mõjutab (sihtmärgid) – nõutav;
policyTypes: näitab, mis tüüpi poliitikad sellesse kuuluvad: ingress ja/või egress - valikuline, kuid soovitan see kõigil juhtudel selgesõnaliselt täpsustada;
ingress: määratleb lubatud sissetulevad liiklus sihtpunktidesse – valikuline;
egress: määratleb lubatud väljaminev liiklus sihtpunktidest on valikuline.
Näide võetud Kubernetese veebisaidilt (asendasin role edasi app), näitab, kuidas kasutatakse kõiki nelja elementi:
Pange tähele, et kõiki nelja elementi ei pea sisaldama. See on ainult kohustuslik podSelector, saab soovi korral kasutada muid parameetreid.
Kui jätame vahele policyTypes, tõlgendatakse poliitikat järgmiselt:
Vaikimisi eeldatakse, et see määrab sissepääsu poole. Kui poliitika seda selgesõnaliselt ei sätesta, eeldab süsteem, et kogu liiklus on keelatud.
Käitumise väljumispoolel määrab vastava väljumisparameetri olemasolu või puudumine.
Vigade vältimiseks soovitan tee see alati selgeks policyTypes.
Eeltoodud loogika kohaselt, kui parameetrid ingress ja / või egress välja jäetud, keelab poliitika kogu liikluse (vt allpool jaotist "Tühjendamise reegel").
Vaikepoliitika on Luba
Kui poliitikaid pole määratletud, lubab Kubernetes vaikimisi kogu liikluse. Kõik kaunad saavad omavahel vabalt teavet vahetada. See võib tunduda turvalisuse seisukohast vastuoluline, kuid pidage meeles, et Kubernetese kujundasid algselt arendajad, et võimaldada rakenduste koostalitlusvõimet. Võrgupoliitikad lisati hiljem.
Nimeruumid
Nimeruumid on Kubernetese koostöömehhanism. Need on loodud loogiliste keskkondade üksteisest eraldamiseks, samas kui ruumidevaheline suhtlus on vaikimisi lubatud.
Nagu enamik Kubernetese komponente, asuvad võrgupoliitikad kindlas nimeruumis. Plokis metadata saate määrata, millisesse ruumi poliitika kuulub:
Kui nimeruum pole metaandmetes selgesõnaliselt määratud, kasutab süsteem kubectlis määratud nimeruumi (vaikimisi namespace=default):
kubectl apply -n my-namespace -f namespace.yaml
Soovitan määrake nimeruum selgesõnaliselt, välja arvatud juhul, kui kirjutate poliitikat, mis sihib mitut nimeruumi korraga.
Peamine element podSelector valib poliitikas kaustad nimeruumist, kuhu poliitika kuulub (sellele on keelatud juurdepääs teisest nimeruumist pärit kaustadele).
Samamoodi podSelectors sisse- ja väljapääsuplokkides saab valida kaunasid ainult oma nimeruumist, välja arvatud juhul, kui te neid kombineerite namespaceSelector (seda käsitletakse jaotises “Filtreeri nimeruumide ja kaustade järgi”).
Poliitika nimetamise reeglid
Poliitikanimed on samas nimeruumis kordumatud. Samas ruumis ei saa olla kahte sama nimega poliitikat, kuid erinevates ruumides võib olla sama nimega eeskirju. See on kasulik, kui soovite sama reeglit mitmele väljale uuesti rakendada.
Eriti meeldib mulle üks nimetamisviis. See koosneb nimeruumi nime kombineerimisest sihtpunktidega. Näiteks:
Saate lisada kohandatud silte Kubernetese objektidele, nagu kaustad ja nimeruumid. Sildid (sildid - sildid) on samaväärsed märgenditega pilves. Kubernetese võrgupoliitikad kasutavad valimiseks silte kaunadmille kohta need kehtivad:
podSelector:
matchLabels:
role: db
… või nimeruumidmillele need kehtivad. See näide valib kõik nimeruumides olevad kaustad vastavate siltidega:
Üks ettevaatus: kasutamisel namespaceSelectorveenduge, et valitud nimeruumid sisaldavad õiget silti. Pidage meeles, et sisseehitatud nimeruumid nagu default и kube-system, ei sisalda vaikimisi silte.
Saate lisada sellisele ruumile sildi:
kubectl label namespace default namespace=default
Samal ajal nimeruum jaotises metadata peaks viitama ruumi tegelikule nimele, mitte sildile:
Tulemüüripoliitikad koosnevad reeglitest koos allikate ja sihtkohtadega. Kubernetese võrgupoliitikad määratletakse sihtmärgi jaoks – poodide komplekti jaoks, millele need kehtivad – ja seejärel kehtestatakse reeglid sisenemis- ja/või väljumisliikluse jaoks. Meie näites on poliitika sihtmärgiks kõik nimeruumis olevad kaustad default sildiga võtmega app ja tähendus db:
Alajaotis ingress selles poliitikas avab sissetuleva liikluse sihtpunktidesse. Teisisõnu, sissepääs on allikas ja sihtmärk on vastav sihtkoht. Samuti on väljapääs sihtkoht ja sihtmärk selle allikas.
See võrdub kahe tulemüürireegliga: Ingress → Target; Värav → Väljapääs.
Väljapääs ja DNS (tähtis!)
Väljuvat liiklust piirates pöörake erilist tähelepanu DNS-ile - Kubernetes kasutab seda teenust teenuste IP-aadressidega vastendamiseks. Näiteks järgmine reegel ei tööta, kuna te pole rakendust lubanud balance juurdepääs DNS-ile:
Viimane element to on tühi ja seetõttu valib see kaudselt kõik kaunad kõigis nimeruumides, lubades balance saatke DNS-päringud vastavasse Kubernetese teenusesse (tavaliselt töötab see ruumis kube-system).
See lähenemisviis töötab, hoolimata sellest liiga lubav ja ebakindel, sest see võimaldab DNS-päringuid suunata väljaspool klastrit.
Saate seda parandada kolme järjestikuse etapiga.
1. Lubage ainult DNS-päringud jooksul klastri lisamise teel namespaceSelector:
2. Lubage DNS-päringud ainult nimeruumis kube-system.
Selleks peate nimeruumile lisama sildi kube-system: kubectl label namespace kube-system namespace=kube-system - ja kirjutage see poliitikasse kasutades namespaceSelector:
3. Paranoilised inimesed võivad minna veelgi kaugemale ja piirata DNS-päringuid konkreetse DNS-teenusega kube-system. Jaotis "Filtreeri nimeruumide JA kaustade järgi" ütleb teile, kuidas seda saavutada.
Teine võimalus on lahendada DNS nimeruumi tasemel. Sel juhul ei pea seda iga teenuse jaoks avama:
Tühi podSelector valib kõik nimeruumis olevad kaustad.
Esimene matš ja reeglite järjekord
Tavalistes tulemüürides määrab paketi toimingu (Luba või Keela) esimene reegel, mida see rahuldab. Kubernetesis pole poliitikate järjekord oluline.
Vaikimisi, kui poliitikaid pole määratud, on kaustade vaheline suhtlus lubatud ja nad saavad teavet vabalt vahetada. Kui hakkate koostama poliitikaid, eraldatakse iga vähemalt ühe neist mõjutatav pod vastavalt kõigi selle valinud poliitikate disjunktsioonile (loogiline VÕI). Pod, mida ükski poliitika ei mõjuta, jäävad avatuks.
Saate seda käitumist muuta eemaldamisreegli abil.
Eemaldamise reegel ("Keela")
Tulemüüripoliitikad keelavad tavaliselt igasuguse liikluse, mis pole otseselt lubatud.
Kubernetesis ei saa tegevust eitadaSarnase efekti saab aga saavutada tavalise (lubava) poliitikaga, valides lähtekoodide tühja rühma (sisend):
Pange tähele, et mis tahes täiendavad eeskirjad, mis lubavad liiklust nimeruumis olevatesse kataloogidesse, on selle reegli suhtes ülimuslikud (sarnaselt tulemüüri konfiguratsioonis lubamisreegli lisamisega enne keelamisreeglit).
Luba kõike (kõik-kõik-kõik-lubatud)
Luba kõik poliitika loomiseks peate ülaltoodud keelamise poliitikat täiendama tühja elemendiga ingress:
See võimaldab juurdepääsu aadressilt kõik kaustad kõigis nimeruumides (ja kõik IP-d) nimeruumi mis tahes kaustadesse default. See käitumine on vaikimisi lubatud, seega ei pea seda tavaliselt rohkem määratlema. Kuid mõnikord peate probleemi diagnoosimiseks mõned konkreetsed load ajutiselt keelama.
Reegli saab kitsendada, et võimaldada ainult juurdepääsu konkreetne kaunade komplekt (app:balance) nimeruumis default:
2. Eeskirjade jaotises ingress võib sisaldada palju elemente from (kombineeritud loogilise VÕI-ga). Samamoodi jagu egress võib sisaldada palju elemente to (kombineeritud ka disjunktsiooniga):
3. Erinevad poliitikad on kombineeritud ka loogilise VÕI-ga
Kuid nende kombineerimisel on üks piirang osutasChris Cooney: Kubernetes saab kombineerida ainult erinevaid poliitikaid policyTypes (Ingress või Egress). Sissepääsu (või väljumist) määratlevad poliitikad kirjutavad üksteist üle.
Nimeruumide vaheline seos
Vaikimisi on nimeruumide vahel teabe jagamine lubatud. Seda saab muuta, kasutades keelamispoliitikat, mis piirab nimeruumi väljuvat ja/või sissetulevat liiklust (vt ülaltoodud jaotist "Tühjendamise reegel").
Kui olete blokeerinud juurdepääsu nimeruumile (vt ülaltoodud "Tühjendamise reeglit"), saate teha keelupoliitikas erandeid, lubades ühendusi konkreetsest nimeruumist, kasutades namespaceSelector:
Selle tulemusena kõik kaunad nimeruumis default saavad kaunadele juurdepääsu postgres nimeruumis database. Aga mis siis, kui soovite avada juurdepääsu postgres ainult konkreetsed kaustad nimeruumis default?
Filtreerige nimeruumide ja kaustade järgi
Kubernetese versioon 1.11 ja uuemad võimaldavad teil operaatoreid kombineerida namespaceSelector и podSelector kasutades loogilist JA. See näeb välja selline:
Miks tõlgendatakse seda kui JA, mitte tavalise VÕI?
Pange tähele, et podSelector ei alga sidekriipsuga. YAML-is tähendab see seda podSelector ja seisis tema ees namespaceSelector viitavad samale loendi elemendile. Seetõttu on need ühendatud loogilise JA-ga.
Enne sidekriipsu lisamine podSelector tulemuseks on uue loendielemendi tekkimine, mis ühendatakse eelmisega namespaceSelector kasutades loogilist VÕI.
Konkreetse sildiga kaunade valimiseks kõigis nimeruumides, sisestage tühjaks namespaceSelector:
Mitme objektiga (hostid, võrgud, rühmad) tulemüüri reeglid kombineeritakse loogilise VÕI abil. Järgmine reegel töötab, kui paketi allikas ühtib Host_1 VÕI Host_2:
Vastupidi, Kubernetesis on erinevad sildid sisse podSelector või namespaceSelector kombineeritakse loogilise JA-ga. Näiteks valib järgmine reegel kaunad, millel on mõlemad sildid, role=db И version=v2:
podSelector:
matchLabels:
role: db
version: v2
Sama loogika kehtib igat tüüpi operaatorite kohta: poliitika sihtvalijad, kausta valijad ja nimeruumi valijad.
Alamvõrgud ja IP-aadressid (IPBlockid)
Tulemüürid kasutavad võrgu segmentimiseks VLAN-e, IP-aadresse ja alamvõrke.
Kubernetesis määratakse IP-aadressid kaustadele automaatselt ja need võivad sageli muutuda, nii et võrgupoliitikates kasutatakse silte kaubade ja nimeruumide valimiseks.
Alamvõrgud (ipBlocks) kasutatakse sissetulevate (sisend) või väljaminevate (väljapääsu) väliste (põhja-lõuna) ühenduste haldamisel. Näiteks avaneb see reegel kõigile nimeruumi kaustadele default juurdepääs Google DNS-i teenusele:
Selles näites olev tühi kausta valija tähendab "vali kõik nimeruumis olevad kaustad".
See poliitika võimaldab juurdepääsu ainult versioonile 8.8.8.8; juurdepääs mis tahes muule IP-le on keelatud. Seega olete sisuliselt blokeerinud juurdepääsu sisemisele Kubernetes DNS-i teenusele. Kui soovite selle siiski avada, märkige see selgelt.
Tavaliselt ipBlocks и podSelectors on üksteist välistavad, kuna kaunade sisemisi IP-aadresse ei kasutata ipBlocks. Näidates sisemised IP-kambrid, siis tegelikult lubate ühendused nende aadressidega kaustadesse ja nendest. Praktikas ei tea te, millist IP-aadressi kasutada, mistõttu ei tohiks neid kaunade valimiseks kasutada.
Vastunäitena hõlmab järgmine poliitika kõiki IP-sid ja võimaldab seega juurdepääsu kõigile teistele kaustadele.
Saate avada juurdepääsu ainult välistele IP-aadressidele, välja arvatud kaustade sisemised IP-aadressid. Näiteks kui teie podi alamvõrk on 10.16.0.0/14:
Tavaliselt kuulavad kaustad ühte porti. See tähendab, et te ei saa poliitikates pordinumbreid lihtsalt määrata ja kõik vaikimisi jätta. Siiski on soovitatav muuta eeskirjad võimalikult piiravaks, nii et mõnel juhul saate siiski määrata pordid:
Pange tähele, et valija ports kehtib kõigi ploki elementide kohta to või from, mis sisaldab. Erinevate elementide komplektide jaoks erinevate portide määramiseks jagage ingress või egress mitmesse alajaotisse koos to või from ja igas registreerige oma pordid:
Kui jätate pordi määratluse täielikult välja (ports), tähendab see kõiki protokolle ja kõiki porte;
Kui jätate protokolli definitsiooni (protocol), tähendab see TCP-d;
Kui jätate pordi määratluse (port), tähendab see kõiki porte.
Parim tava: ärge toetuge vaikeväärtustele, täpsustage selgelt, mida vajate.
Pange tähele, et peate kasutama kambriporte, mitte teenindusporte (selle kohta leiate teavet järgmises lõigus).
Kas kaustade või teenuste jaoks on määratletud eeskirjad?
Tavaliselt pääsevad Kubernetese kaustad üksteisele teenuse kaudu – virtuaalse koormuse tasakaalustaja kaudu, mis suunab liikluse ümber teenust rakendavatele kaustadele. Võib arvata, et võrgupoliitikad kontrollivad juurdepääsu teenustele, kuid see pole nii. Kubernetese võrgupoliitikad töötavad pod-portides, mitte teenindusportides.
Näiteks kui teenus kuulab porti 80, kuid suunab liikluse ümber oma kabiinide pordile 8080, peate võrgupoliitikas määrama täpselt 8080.
Sellist mehhanismi tuleks pidada ebaoptimaalseks: kui teenuse sisemine struktuur (mille pordid kuulavad) muutub, tuleb võrgupoliitikat värskendada.
Uus arhitektuurne lähenemine Service Meshi abil (vt Istio kohta näiteks allpool – u tõlge) võimaldab teil selle probleemiga toime tulla.
Kas on vaja registreerida nii Ingress kui ka Egress?
Lühike vastus on jah, selleks, et pod A saaks suhelda podiga B, peab tal olema lubatud luua väljaminev ühendus (selleks tuleb konfigureerida väljumispoliitika) ja pod B peab suutma vastu võtta sissetulevat ühendust ( selleks vajate vastavalt sissepääsupoliitikat). poliitika).
Kuid praktikas võite tugineda vaikepoliitikale, et lubada ühendused ühes või mõlemas suunas.
Kui mõni pod-allikas valib üks või mitu väljumine-poliitikud, sellele seatavad piirangud määrab nende disjunktsioon. Sel juhul peate andma selgesõnalise loa pesaga ühenduse loomiseks -adressaat. Kui ühtki poliitikat ei valita, on selle väljuv (väljamineku) liiklus vaikimisi lubatud.
Samamoodi on kauna saatusadressaat, mille on valinud üks või mitu sissepääs-poliitikud, määrab nende erimeelsus. Sel juhul peate selgesõnaliselt lubama tal allikahoidlast liiklust vastu võtta. Kui ühtki poliitikat ei valita, on kogu selle sisendliiklus vaikimisi lubatud.
Vaadake allolevat jaotist Stateful või Stateless.
Palgid
Kubernetese võrgupoliitikad ei saa liiklust logida. See muudab raskeks kindlaks teha, kas poliitika töötab ettenähtud viisil, ja muudab turbeanalüüsi oluliselt keerulisemaks.
Väliste teenuste liikluse juhtimine
Kubernetese võrgupoliitikad ei luba teil väljapääsuosades määrata täielikult kvalifitseeritud domeeninime (DNS). See asjaolu toob kaasa märkimisväärseid ebamugavusi, kui üritate piirata liiklust välistesse sihtkohtadesse, millel pole fikseeritud IP-aadressi (nt aws.com).
Poliitika kontroll
Tulemüürid hoiatavad teid või isegi keelduvad aktsepteerimast vale poliitikat. Kubernetes teeb ka teatud kontrolli. Kubectli kaudu võrgupoliitika määramisel võib Kubernetes kuulutada, et see on vale, ja keelduda seda aktsepteerimast. Muudel juhtudel võtab Kubernetes poliitika ja täidab selle puuduvate üksikasjadega. Neid saab näha käsuga:
kubernetes get networkpolicy <policy-name> -o yaml
Pidage meeles, et Kubernetese valideerimissüsteem ei ole eksimatu ja võib teatud tüüpi vigu märkimata jätta.
Täitmine
Kubernetes ei rakenda ise võrgupoliitikaid, vaid on lihtsalt API lüüs, mis delegeerib juhtimiskoormuse aluseks olevale süsteemile, mida nimetatakse konteineri võrguliideseks (CNI). Kubernetese klastri poliitikate määramine ilma sobivat CNI-d määramata on sama, mis tulemüürihaldusserveris poliitikate loomine ilma neid tulemüüridesse installimata. Teie asi on tagada, et teil on korralik CNI või Kubernetese platvormide puhul pilves hostitud (näete pakkujate loendit siin — ca. trans.), lubage võrgupoliitikad, mis määravad teie eest CNI.
Pange tähele, et Kubernetes ei hoiata teid, kui määrate võrgupoliitika ilma sobiva abistaja CNI-ta.
Riiklik või kodakondsuseta?
Kõik Kubernetese CNI-d, millega olen kokku puutunud, on olekuga (näiteks Calico kasutab Linuxi conntracki). See võimaldab podil saada vastuseid algatatud TCP-ühenduse kohta, ilma et peaks seda uuesti looma. Kubernetese standardit, mis tagaks olekulikkuse, ma aga kursis ei ole.
Täiustatud turbepoliitika haldamine
Siin on mõned viisid Kubernetese turvapoliitika jõustamise parandamiseks.
Service Meshi arhitektuurne muster kasutab külgkorvi konteinereid, et pakkuda teenindustasemel üksikasjalikku telemeetria ja liikluse juhtimist. Näitena võime võtta Istio.
Mõned CNI müüjad on laiendanud oma tööriistu, et minna kaugemale Kubernetese võrgupoliitikast.
Tufin Orca Pakub Kubernetese võrgupoliitika nähtavust ja automatiseerimist.
Tufin Orca pakett haldab Kubernetese võrgupoliitikaid (ja on ülaltoodud ekraanipiltide allikas).
Kubernetese võrgupoliitikad pakuvad head tööriistakomplekti klastrite segmenteerimiseks, kuid need pole intuitiivsed ja neil on palju nüansse. Selle keerukuse tõttu usun, et paljud olemasolevad klastripoliitikad on lollakad. Selle probleemi võimalikud lahendused hõlmavad poliitika määratluste automatiseerimist või muude segmenteerimistööriistade kasutamist.
Loodan, et see juhend aitab selgitada mõningaid küsimusi ja lahendada probleeme, mis võivad tekkida.