Hlavní navigace

Tajemství jako služba. V Seznamu se o ně stará Sasanka

4. 5. 2021
Doba čtení: 15 minut

Sdílet

 Autor: Seznam.cz
Jak v Seznam.cz řeší správu a sdílení hesel, klíčů či tokenů? Do technického zákulisí nechává nahlédnout technický ředitel Vlastimil Pečínka.

V roce 2021 jistě každý používá, zná nebo alespoň něco slyšel o správcích hesel (password manager). O užitečných nástrojích, které, pokud jsou správně používány, usnadňují pohyb a zvyšují bezpečnost v digitálním prostředí plném služeb vyžadujících naše přihlašování. Usnadňují nám například nepoužívat stejná hesla na různých službách a volit hesla dostatečně odolná proti prolomení. A to i díky tomu, že si je nemusíme pamatovat. Pokročilejší nástroje dokáží přenášet naše hesla mezi různými zařízeními, a tak je máme k dispozici přesně tam, kde je v danou chvíli třeba. A pokud je nutné heslo změnit, zásadně nám to usnadní.

Za oponou uživatelského rozhraní – v prostředí infrastruktury konkrétních služeb a aplikací – leží svět, který se potýká s podobnou problematikou. Možná i umocněnou tím, že kromě lidských uživatelů je zde řada uživatelů z kategorie „machine“. V rozsáhlých a komplexních infrastrukturách dokonce počet machine-to-machine interakcí výrazně převažuje. A ideálně všechny by měly mít nějakou míru autentizace (i autorizace).

Správné zabezpečení má především vyplývat z promyšleného designu a uplatňování správných vzorců chování. Například máte oddělená vývojová a provozní prostředí. Zároveň ale nechcete, aby se tato prostředí lišila a z jejich odlišnosti pak později vyvstaly problémy. Cloudový (platformní) přístup umožňuje sblížit tyto světy a infrastruktura se může stát součástí kódové báze aplikace. Ale jistě není součástí správného designu mít v kódové bázi uložena hesla, klíče nebo tokeny. Kam však s nimi?

Jiný z bezpečnostních principů je nemít nekonečně dlouho platná hesla, klíče nebo tokeny (obecně tajemství). Kromě jiných aspektů má pravděpodobnost prozrazení a zneužití tajemství určitou souvislost s tím, jak dlouho tajemství existuje. Proto je důležité platnost tajemství limitovat a pravidelně je obměňovat. To však naráží na lidskou povahu věci nedělat či zapomínat, a proto je neoddělitelnou součástí takové obměny tajemství automatizace. Možná to znáte z používání Let‘s Encrypt certifikační autority – tříměsíční expirace TLS certifikátů donutí každého dříve nebo později odevzdat rutinu obměňování nějakému nástroji.

Když si to nyní představíte vše dohromady, tak zde máme snahu sice sblížit, ale stále oddělovat vývojová a provozní prostředí. Zjednodušeně řečeno, stejný kus kódu, ale jiná data včetně tajemství. Dále chceme tajemství umět levně a často obměnit. A samo sebou mít je nějakým způsobem zabezpečena. To už si říká o infrastrukturní službu, která může být navíc vtělena do kódové báze dané aplikace a stát se její součástí. A na to máme v Seznam.cz již přes rok službu Sasanka.

Naše Sasanka

Sasanka je naše interní řešení napsané a rozvíjené s ohledem na specifika Seznamu. Dá se říct, že Sasanka je redundantní distribuovaný in-memory databázový cluster s REST API zaměřený na uchovávání a sdílení tajemství napříč infrastrukturou a zaměstnanci. Každý uživatel může vytvářet jmenné prostory (například john.doe:wiki-secrets) a sdílet je s dalšími uživateli. V rámci jmenných prostorů lze pak ukládat tajemství různých typů, případně vytvářet podepisovací či šifrovací klíče. K těmto tajemstvím je možné přistupovat „manuálně“, nicméně síla spočívá především v přístupu přes API. Toto API umožňuje automatizaci, namespace zase znamenají možnost oddělit různá prostředí a aplikace.


Autor: Vlastimil Pečínka, Seznam.cz

Sasanka může dobře posloužit v situaci, kdy existuje na jedné straně jeden producent tajemství (například naše interní služba TLS Management generující klíče a certifikáty pod různými certifikačními autoritami) a na druhé straně řada konzumentů, kteří tato tajemství potřebují pro svůj běh (například jednotlivé web servery). 

Stejně tak dobře poslouží, pokud máte oddělený vývojový a provozní tým, každý má svá tajemství (například přístupy do databáze) v odpovídajících namespace a aplikaci jen potřebujete konfiguračně říct, který namespace je ten správný pro prostředí, ve kterém danou aplikaci spouštíte. Sasanka také poslouží, pokud potřebujete jednorázově poslat nějaké tajemství kolegovi či kolegyni – na rozdíl od interního e-mailu nebo instant messengeru totiž netrousí dané tajemství po cestě.

Význačné rysy

V charakteristice služby Sasanka bylo uvedeno „distribuovaný in-memory databázový cluster“. Distribuovaný zde znamená, že nám běží ze všech tří lokalit, které k provozu Seznam.cz využíváme. V rámci lokality pak v několika instancích a každý node clusteru je v něm sám za sebe. In-memory znamená, že veškerá data se nacházejí pouze v paměti, cluster pro svůj běh nepotřebuje disk. Přesněji řečeno, disk je použit pouze na vybraných nodech při vytváření zašifrovaného snapshotu pro zálohovací účely. Možnost dešifrovat ho je značně omezená, viz dále. Cluster pak znamená, že jednotlivé uzly Sasanky si mezi sebou povídají a vyměňují změny v databází tajemství.

Cluster využívá „eventual consistency“ přístup. To znamená, že nastane-li někde v clusteru změna v datech, postupně se projeví na všech nodech, ale v určitém krátkém mezidobí mohou nodes vracet různé verze měněných dat. Obdobně, pokud ve zhruba stejný čas nastanou v různých částech clusteru dvě rozdílné změny nad stejným objektem, dojde cluster po čase do konzistentního stavu a všechny nodes začnou vracet stejná data – ta čerstvější, pokud to lze objektivně posoudit. Za běžných situací je tento přístup dostatečný, protože většinou producent a konzument jsou časově a místně odděleni a krátkou inkonzistenci nepostřehnou. Avšak tato architektura umožní asynchronní přenos dat a celkově robustní chování clusteru. I v případě, kdy na sebe nodes nebo lokality nevidí, všechny části clusteru mohou fungovat nadále a po obnově spojení dořeší změnové operace.

Služba, která uchovává takové množství tajemství, je pochopitelně velmi citlivé místo v infrastruktuře. Jedna z věcí, kam míříme Sasankou, je samotná ochrana této citlivé databáze. Neexistuje v Sasance žádná role „superuživatel“, která by mohla nahlížet do dat dalších uživatelů. Kód to neumožňuje. Data se drží pouze v paměti běžících instancí, případně v zašifrovaném snapshotu. System engineers provozující Sasanku nemají k dispozici dešifrovací klíč. Dešifrovací klíč ve své plné podobě nemá nikdo, je rozdělen s využitím Shamir's Secret Sharing na více částí a k jeho sestavení je potřeba jejich určitá podmnožina. Držitelé se musí sejít v případě disaster recovery nebo v případě, kdy je potřeba v clusteru rozjet nějaký node, který nedokáže cluster sám o sobě nainicializovat. Ve výchozí podobě se cluster snaží inicializovat své nodes sám za pomoci autodiscovery. A to i v případě aktualizace aplikace na novou verzi.


Autor: Vlastimil Pečínka, Seznam.cz

Budoucí rozvoj Sasanky v oblasti zabezpečení dat míří směrem k fyzické bezpečnosti serveru. V Seznamu mimo jiné vyvíjíme vlastní ARM mini server. Ten by mohl být zbaven disku a osazen vybraným „crypto processorem“, který by zajistil jeho nezfalšovatelnou identitu v rámci sítě. Pak už stačí, aby vyrobený kus prošel „trusted setup“ procesem, byl zapojen do sítě a stal se součástí clusteru. Bez disku, bez vzdáleného přístupu přes SSH a bez jediné osoby držící dešifrovací klíč je pak vektor útoku minimalizován.

Databáze Sasanky má sloužit jako zdroj pravdy pro tajemství používaná v infrastruktuře. Nicméně pro praktickou použitelnost je potřeba, aby tajemství byla blíže aplikacím a ideálně je poskytovala pro ně stravitelnou formou. Je těžké si představit, že každá u nás vyvíjená aplikace bude komunikovat se servery Sasanky, aby si vytáhla potřebné údaje pro přístup do databáze. Místo toho je lepší, aby tato tajemství byla přítomna například formou proměnných prostředí nebo hodnot v konfiguračním souboru, případně aby byla přímo obsahem nějakých souborů. 

V případech, kdy cílová aplikace běží v jednom z našich Kubernetes clusterů, může ten, kdo má přístup k tajemství v Sasance, nastavit automatickou synchronizaci do Kubernetes a Sasanka při každé změně tajemství aktualizuje odpovídající secret object v Kubernetes. Pokud aplikace běží v jiném prostředí (například ve VM v Openstacku), je k dispozici utilita, která může být spouštěna cronem, tahat tajemství ze Sasanky, ukládat je do souboru, vyplňovat šablony a spustit externí akce, pokud se tajemství změní. Existuje také utilita, která tajemství umístí do proměnné prostředí a spustí nějaký příkaz – to lze použít například v rámci CI/CD pipelines v našem Gitlabu a z něj odstranit ostatní tzv. „secret variables“.

Zastupitelnost a kontinuita

V komplexní infrastruktuře převládá komunikace machine-to-machine. Tomu by mohlo odpovídat mnoho servisních účtů. Ačkoliv Sasanka umožňuje vytvořit servisní účty nespojené s konkrétní osobou, není toto preferovaný způsob použití. Problém servisních účtů je, že po čase nevíte, komu patří a kdo do nich má přístup. Sasanka raději preferuje, aby v ní byl každý sám za sebe a bylo explicitně vyjádřeno vlastnictví tajemství. Ale zároveň má nástroj, jak podpořit zastupitelnost lidí, vyrovnat se s odchody zaměstnanců nebo umožnit strojům přistoupit ke konkrétním tajemstvím.

Každý uživatel má na startovní čáře svůj privátní prostor a je pouze na něm, jaké namespaces vytvoří a s kým je bude sdílet. Pokud se rozhodne, že daná tajemství jsou jen pro něj, prostě je nesdílí. Pokud ale pracuje v týmu na nějakém projektu, měl by další členy týmu zařadit do odpovídajících namespace jako členy v roli admin. To jednak umožní zastupitelnost při správě týmových tajemství, ale také zachová přístup k datům, pokud by dotyčný vlastník opustil zaměstnání. Sasanka v takovém případě účet pouze zablokuje, ale data jsou k dispozici těm, komu byla sdílena. Sdílející mohou v krajním případě data překopírovat a přenastavit své aplikace, aby odkazovaly na tajemství v novém umístění. 


Autor: Vlastimil Pečínka, Seznam.cz

Ale to není ten správný postup. Správné je mít vše od počátku nastavené tak, že s odchodem zaměstnance nemusíte nic řešit a infrastruktura se postará sama. Sasanka dokáže převlastnit sdílené namespace a tajemství na dalšího člena v roli admin. A pokud byl namespace přidělen globálně unikátní název (alias), nikdo a nic není tímto převlastněním dotčen a tajemství jsou nadále k dispozici již s novým vlastníkem pod stejným názvem.

Výše uvedené převlastnění se týká také aplikačních tokenů, které slouží k přístupu k tajemstvím přes API Sasanky. Tokeny mají možnost být omezeny (a vždy by měly být omezeny) na co nejužší scope odpovídající jejich účelu. V rámci operace převlastnění jsou tak odpovídajícím způsobem upraveny všechny dotčené tokeny. Aplikace a infrastruktura by to neměly postřehnout.

Aplikační tokeny

Zmíněné tokeny jsou důležité, protože s jejich využitím lze volat metody na API Sasanky, a tedy slouží primárně pro machine-to-machine komunikaci. Token je vždy vytvořen pro nějaký účel, a jak již bylo zmíněno, může být a měl by být omezen. Lze určit, že token nemůže provádět změnové operace. Protože předpokladem je, že existuje více konzumentů než producentů tajemství, většina tokenů by měla být read-only. 

Dále může mít token určen scope, ve kterém je platný. Scope je buď namespace, skupina, nebo tag, ať již explicitně uvedený svým názvem, nebo pomocí regulárního výrazu. Lze tak vytvořit například token, který umožní přístup do namespaces, kam má jeho vlastník přístup a které jsou pojmenovány s koncovkou -dev (pro zvídavé, v řeči Sasanky je scope takového tokenu ns:/^.*-dev$/).

Některé systémy využívají tokeny jako způsob sdílení prostředků. Typicky: někdo vlastní určitý prostředek, vytvoří token pro přístup k němu a ten token předá. Tento přístup má tu vadu, že v okamžiku, kdy vytvoříte token a někomu jej poskytnete, ztrácíte kontrolu a nevíte, kdo všechno daným tokenem disponuje. Případně nevíte, kde všude se začal používat a co rozbijete, když ho smažete. 


Autor: Vlastimil Pečínka, Seznam.cz

Sasanka preferuje, aby sdílení bylo realizováno sdílením, a bylo tedy explicitně vyjádřeno v nastavení namespace. S člověkem se už většinou domluvíte, když mu chcete sdílení odebrat. Token pak vytváří a používá ten, kdo typicky konfiguruje nějakou aplikaci a chce vyjádřit „nyní za mě přistupuj k těmto tajemstvím, ke kterým já mám přístup, protože je vlastním nebo mi je někdo sdílí“. Když jako osoba o přístup k tajemství přijdete, čímž o něj přijdou i vaše tokeny, je to izolovaný problém, který se dotýká pouze toho, co máte ve své správě.

Use case 1: TLS management

Samotný vznik Sasanky a inspirace filmem Terminátor nebo technologií kolem Bitcoinu či produktu Vault od HashiCorp by bylo na samotné téma. Podstatné je, že v Seznamu jsme před Sasankou měli službu pojmenovanou „szn-secrets“, která byla založena na secrets objektech v dedikované instanci Kubernetes clusteru. Služba měla podobné ambice jako pozdější Sasanka, ale nikdy nedosáhla dále než na omezené využití pro ukládání TLS certifikátů a klíčů v provozních aplikacích. Tento use case však byl startovací čárou pro Sasanku a dodnes zřejmě nejvíce tajemství v Sasance bude právě z kategorie webové a klientské certifikáty a klíče.


Autor: Vlastimil Pečínka, Seznam.cz

TLS management (TLSm) je naše samostatná interní služba, která využívá Sasanku jako storage pro vygenerované certifikáty a klíče. TLSm je vlastně „CA-aaS“ (certifikační autorita jako služba) s vlastním API pro podporu automatizace. Služba umožňuje svým uživatelům vytvářet vlastní certifikační autority a vydávat jejich prostřednictvím certifikáty pro uživatele, včetně auto-obnovy či revokace. Náš TLSm zprostředkovává i CA Let‘s Encrypt a z pohledu interních uživatelů je tak jedno, jestli řeší oficiální certifikát pro produkční nasazení na externím endpointu, certifikát vydaný naší interní seznamáckou CA čistě pro vývojové a testovací účely, nebo klientský certifikát vyžadovaný pro přístup na nějakou interní cloudovou službu.

Služba TLSm využívá Sasanku jako storage pro citlivá data dvojím způsobem. Pro každou CA (protože je to CA-aaS) si ve vlastním namespace drží podepisovací klíč odpovídající té které CA. Zároveň v situaci, kdy přes danou CA vytváří a podepisuje nějaký certifikát s klíčem, umístí obojí do namespace, který určil žadatel. Volitelně sama CA může mít své výchozí úložiště pro vygenerované klíče a certifikáty, pokud je potřebuje. Například vlastníkem CA pro webové certifikáty je náš aplikační load balancer, který potřebuje klíč i certifikát pro každou balancovanou službu. Samotný žadatel pak de facto svoji kopii certifikátu a klíče nepotřebuje, může na to celé „zapomenout“, nechat stroje povídat si a každé tři měsíce obnovit certifikát. Pokud by něco selhalo, dostane potřebné avízo do Mattermostu.

Jako žadatel o certifikát, pokud si ho chci nechat uložit v Sasance v mém namespace, mi tak stačí, abych do tohoto namespace vpustil určeného uživatele v roli write-only. Tím zajistím, aniž bych musel službě TLSm poskytovat nějaký token, že může do mého určeného namespace, že si z něj nic nepřečte, ale může mi tam zapisovat vygenerovaná či aktualizovaná tajemství.


Autor: Vlastimil Pečínka, Seznam.cz

Use case 2: Docker registry

V Seznamu hojně používáme kontejnery, a tedy i docker images. Pro jejich správu jsme se rozhodli pro produkt Harbor. V rámci něj je možné vytvářet různé projekty, které mohou být z interního pohledu firmy buď soukromé, či veřejné. Z pohledu projektů lze definovat, kdo může do daného projektu umístit docker image nebo si jej stáhnout. Pokud chcete do repozitáře umístit nějaký svůj docker image, musíte se autentizovat. Většinou je tvorba images záležitostí automatizace, odehrává se to v rámci CI/CD jobů (například v našem Gitlabu). A protože jako vývojář nechcete dávat do automatizovaných úloh své přihlašovací údaje, vytvoříte si v Harboru tzv. robot account, který pak za vás images nahrává. Pro tyto robot accounty platí to samé pravidlo jako pro tokeny. Jejich platnost by měla být co nejkratší. Sasanka má v sobě implementovanou podporu pro synchronizaci a obnovu takových robot accountů.

V rámci Sasanky stačí vytvořit ve vhodném namespace tajemství typu auth, což je JSON objekt s položkami username a password. V nich jsou uvedeny aktuální platné přihlašovací údaje daného robot accountu. V metadatech tajemství se uvede, že tento robot account má být synchronizován s Harborem pro určitý projekt. Sasanka si pak následně poprvé zjistí, kdy robot account expiruje, a tento termín si hlídá. Určitou dobu před expirací pak s Harborem domluví občerstvení hodnot a uloží je do odpovídajících položek username a password v tajemství. Vám jako uživateli pak stačí v rámci CI/CD jobu vytáhnout ze Sasanky aktuální hodnotu přihlašovacích údajů a použít je v okamžiku, kdy potřebujete nahrát nový sestavený image do repozitáře.

Robot accounts se dají používat i pro získání docker image ze soukromých projektů v Harboru, například do deploymentů v Kubernetes. Sasanka umí synchronizovat tajemství do Kubernetu, jak již bylo uvedeno. Umí je uložit jako typ opaque (obecné tajemství), tls (pár klíčů) nebo dockerconfigjson. Právě poslední uvedený umožní sdělit Kubernetes, že v tomto secretu (původně synchronizovaném ze Sasanky, který si jej zase čas od času občerství v Harboru) leží potřebné údaje pro nahrání images z jinak obecně nepřístupného projektu v repozitáři. Ačkoliv tento přístup není v současné využíván, nabízí do budoucna možnost některé projekty interně zabezpečit více, než je standardní.

Use case 3: Dropbox

Mechanismus namespaces a sdílení je cílen na dlouhodobější úschovu a práci s tajemstvími, které mají nějaký způsob automatické konzumace. Čas od času si ale jako lidé potřebujete vyměnit nějaké tajemství, které třeba jednorázově použijete. Problém pak nastává při volbě bezpečného kanálu, jakým taková tajemství předat. SMS, e-mail, instant messenger – vše zanechává nechtěnou stopu a nevíte, kdo další se k předanému tajemství může dostat. Samo sebou si v Sasance můžete vytvořit namespace, tajemství do něj uložit a sdílet ho s příjemcem. Sasanka má však i přímočařejší způsob, který nazývá Dropbox.

Jde o velmi jednoduchou feature. V kontextu této zabezpečené služby určené pro správu tajemství zašlete kolegovi či kolegyni (či skupině) instantní zprávu, která má automatickou expiraci. Sasanka příjemce takové zprávy upozorní i s odkazem v interním instant messengeru. Zprávu můžete zaslat přes webové rozhraní Sasanky, případně cmdline utilitou.

Use case 4: Šifrování záloh

Uvnitř namespaces můžeme mimo tajemství různých typů ukládat také privátní klíče. Na rozdíl od běžných tajemství však Sasanka neakceptuje hodnotu privátního klíče od vás, ale sama privátní klíč vygeneruje. Nikdy ho však nikomu neposkytne, poskytne pouze služby s daným privátním klíčem spojené. V případě, že jde o klíč určený k podepisování zpráv, tak vytvoří či ověří signaturu zadané zprávy. V případě, že jde o klíč určený k šifrování dat, tak z privátního klíče generuje jednorázový symetrický klíč použitý pro zašifrování dat a tzv. ciphertext, ze kterého je možné později zpětně sestavit odpovídající jednorázový symetrický klíč.

Tip do článku - EBF spíkři 1

Tento druhý zmíněný postup se používá například pro šifrování záloh dat uživatelů naší CDN. Každý uživatel (terminologicky lépe tenant) má přidělen svůj vlastní privátní master key v Sasance. Při každém požadavku na zálohu dat si zálohovací agent vyžádá pro daný master key jednorázovou dvojici symetrický klíč + ciphertext. Symetrický klíč použije pro zašifrování zálohy a zahodí ho. Zapomene ho. Naopak ciphertext vloží do zálohy, třeba jako první nebo poslední bajty výsledného binárního souboru. Tento ciphertext je tedy součástí zálohy a je potřeba v situaci, kdy je zálohu nutné dešifrovat. Zálohovací agent (či spíše jeho recovery protějšek) si z binárních dat ciphertext vytáhne a požádá Sasanku o vrácení odpovídajícího symetrického klíče, který mu umožní zálohu dešifrovat. Symetrický klíč se na straně Sasanky vždy vypočte z master key, není nikde uložen. Celý tento přístup je datově velmi nenáročný, znamená jen existenci tajného privátního klíče pro každého tenanta a několik desítek bajtů navíc v každé záloze. Ale v důsledku vede k tomu, že prozrazení nebo prolomení jedné konkrétní zálohy nevede k dešifrování žádné další zálohy a že hlavní dešifrovací klíče (master keys) leží v chráněném úložišti v Sasance.

Závěr

Existuje nespočetně dalších možných use case, které zde nezmiňuji s ohledem na délku celého článku nebo i omezenost mé fantazie. Mojí primární snahou bylo nechat trochu nahlédnout pod pokličku Seznamu v přístupu k problematice, o které se veřejně moc nemluví. Plus na nakládání s tajemstvími v infrastruktuře demonstrovat, že i zdánlivě běžné a možná nudné věci jako „hesla, tokeny a klíče“ jsou ve skutečnosti velmi pestré a dá se v nich realizovat mnoho nápadů a inovací.