
Kubernetes Secret не шыфруецца па змаўчанні: як закрыць etcd

Інструкцыя Kubernetes па шыфраванні тлумачыць: па змаўчанні API-сервер захоўвае рэсурсы, у тым ліку Secret, у etcd без шыфравання. Каб змяніць гэта, задайце EncryptionConfiguration, падключыце яе да кожнага kube-apiserver і пастаўце шыфруючы правайдар першым у спісе.
Шыфраванне спрацоўвае пры стварэнні або абнаўленні запісу. Таму ўжо створаныя Secret трэба перазапісаць праз Kubernetes API, а затым прачытаць іх актуальныя значэнні непасрэдна праз etcdctl. Кадзіраванне поля data у base64 не абараняе змесціва: значэнне можна дэкадаваць без ключа.
Праверце бягучую канфігурацыю
На кожным вузле кіравання знайдзіце аргумент kube-apiserver --encryption-provider-config. Калі API-сервер працуе як статычны Pod, праверце яго маніфест, шлях да файла EncryptionConfiguration і падключэнне файла ў кантэйнер. Адсутнасць аргумента азначае, што шыфраванне рэсурсаў пры запісе праз API-сервер не ўключана.
Калі аргумент ёсць, паглядзіце канфігурацыю на ўсіх вузлах. У resources павінен быць тып secrets, а першым у providers — шыфруючы правайдар. identity на першым месцы запісвае даныя без шыфравання. Нават правільны парадак не паказвае, ці былі перазапісаныя старыя Secret. У кіраваным кластары без доступу да вузлоў кіравання статус гэтай налады трэба высветліць праз сродкі правайдара кластара.
Выберыце KMS або лакальны ключ
Калі даступная служба кіравання ключамі, разгледзьце KMS v2. Інструкцыя Kubernetes для KMS называе v2 стабільным пачынаючы з Kubernetes v1.29: ключ, які абараняе ключы даных, кіруецца знешнім KMS, а API-сервер звязваецца з лакальным плагінам праз UNIX-сокет. Перад разгортваннем праверце версію кластара, даступнасць плагіна для кожнага API-сервера і працэдуру аднаўлення доступу да раней зашыфраваных даных пасля ратацыі ключа ў KMS.
Без KMS можна выкарыстаць лакальны secretbox. Для яго стварыце выпадковы ключ камандай head -c 32 /dev/urandom | base64 і запішыце вынік у secret файла EncryptionConfiguration. Абмяжуйце чытанне файла карыстальнікам, ад імя якога працуе kube-apiserver, а абароненую копію ключа захоўвайце асобна. Такі варыянт закрывае даныя ад таго, хто атрымаў доступ толькі да etcd; доступ да вузла кіравання і файла з ключом патрабуе асобнай абароны.
Разгарніце наладу без страты чытання

У файле пазначце apiVersion apiserver.config.k8s.io/v1, kind EncryptionConfiguration і resources з тыпам secrets. Для secretbox у providers задайце keys з name і значэннем secret у base64; для KMS v2 патрэбныя apiVersion v2, name і endpoint плагіна. Пакуль у etcd ёсць незашыфраваныя Secret, пакіньце identity апошнім: ён дазволіць API-серверу іх прачытаць.
Пры некалькіх API-серверах спачатку дайце ўсім аднолькавы лакальны ключ або доступ да KMS. Бяспечная паслядоўнасць для паэтапнага пераходу — спачатку разгарнуць на кожным серверы канфігурацыю з identity першым і шыфруючым правайдарам пасля яго. Серверы пакуль пішуць адкрытыя значэнні, затое ўсе ўжо могуць чытаць будучыя зашыфраваныя запісы. Калі кожны вузел абноўлены, перастаўце шыфруючы правайдар наперад і зноў абнаўляйце серверы па чарзе.
Для статычнага Pod падключыце файл як том толькі для чытання і задайце --encryption-provider-config з шляхам унутры кантэйнера. Пасля абнаўлення кожнага вузла праверце даступнасць яго API-сервера і чытанне Secret, перш чым пераходзіць да наступнага. Бесперапынная даступнасць API падчас перазапускаў залежыць ад працаздольных рэзервовых сервераў. Калі чытанне зламаецца, спыніце перазапіс і вярніце працаздольную канфігурацыю, абавязкова пакінуўшы ў ёй правайдар і ключы для ўжо зашыфраваных запісаў.
Перазапішыце раней створаныя Secret
Калі ўсе API-серверы пішуць праз новы правайдар, выканайце з правамі на чытанне і змяненне ўсіх Secret: kubectl get secrets --all-namespaces -o json | kubectl replace -f -. Каманда адпраўляе наяўныя аб’екты назад у API без змены іх змесціва; пры новым запісе сервер ужывае шыфраванне. Перад масавай аперацыяй зрабіце абароненую рэзервовую копію etcd і захавайце ключы або доступ да KMS, патрэбныя для аднаўлення.
Праверце вынік каманды: канфлікт з паралельным абнаўленнем азначае, што закрануты Secret трэба апрацаваць паўторна. У вялікім кластары зручней перазапісваць аб’екты па прасторах імёнаў і сачыць за памылкамі. Рэзервовая копія, зробленая да міграцыі, можа змяшчаць адкрытыя значэнні, таму доступ да яе абмяжоўвайце незалежна ад новай налады API-сервера.
Праверце запісы ў etcd

Стварыце пробны Secret з несакрэтным значэннем: kubectl create secret generic enc-check -n default --from-literal=probe=sample. З уліковымі данымі для свайго etcd прачытайце запіс: ETCDCTL_API=3 etcdctl get /registry/secrets/default/enc-check | hexdump -C. Калі кластар выкарыстоўвае іншы прэфікс захоўвання, падстаўце фактычны шлях.
У значэнні чакайце прэфікс k8s:enc: і пазначэнне ўжытага правайдара замест адкрытага змесціва. Каманда kubectl get secret enc-check -n default -o yaml павінна па-ранейшаму вяртаць аб’ект праз API. Такая праверка ахоплівае толькі новы запіс: пасля масавага перазапісу выбарачна прачытайце ў etcd таксама старыя Secret. Выдаляйце identity толькі калі пераканаліся, што ўсе актуальныя Secret зашыфраваныя, інакш прапушчаны адкрыты запіс стане нечытэльным праз API.
Актуальнае зашыфраванае значэнне не выдаляе ранейшы адкрыты тэкст з гісторыі. Апісанне мадэлі etcd паказвае, што папярэднія рэвізіі захоўваюцца пасля абнаўлення і адкідаюцца пры кампактаванні. Таму ўлічыце кампактаванне і тэрмін захавання старых рэзервовых копій, калі трэба прыбраць таксама гістарычныя значэнні.
Ратуйце ключ з магчымасцю вяртання
Для лакальнага правайдара дадайце новы ключ другім у keys на ўсіх вузлах і па чарзе перазапусціце API-серверы. Захавайце абароненую копію новага ключа, пасля чаго перастаўце яго на першае месца і зноў абнавіце серверы. Цяпер паўтарыце kubectl replace для ўсіх Secret: новыя версіі будуць зашыфраваныя новым ключом, а стары застанецца даступным для чытання.
Выдаляйце стары ключ толькі пасля паспяховага перазапісу і праверкі актуальных значэнняў, а таксама пасля вызначэння, якія ключы патрэбныя для захаваных копій. Калі пераход трэба спыніць раней, вярніце стары ключ на першае месца, пакінуўшы новы ў спісе для чытання ўжо створаных ім запісаў. Страта адзінага прыдатнага ключа не выпраўляецца перазапускам API-сервера. Для KMS ратуйце ключ паводле працэдуры плагіна і захоўвайце магчымасць расшыфроўваць старыя даныя да заканчэння міграцыі.
Чытайце таксама:
Падобныя артыкулы


GitHub Actions без ключоў AWS: адна ўмова не пусціць чужы рэпазіторый

Signal ці WhatsApp: аднолькавы пратакол не хавае аднолькавыя даныя

Сакрэт у Docker ENV застаецца ў вобразе: перанясіце яго ў secret mount

Amazon S3 ці Cloudflare R2: нулявы egress не кампенсуе кожную затрымку

Рэзервовая копія Signal не вернецца без 64-знакавага ключа
Падпішыцеся на нашу рассылку
Атрымлівайце свежыя навіны пра Web3, ШІ і крыптавалюты проста на пошту.