Secrets

Когато трябва да използваме нещо което не е добра идея да се знае от всички (като например връзка към база или client secret и подобни), винаги, ама винаги-винаги-винаги стои въпроса къде да ги запазим. Различните платформи решават (или не) този проблем по различни начини. Валиден подход е и “не е мой проблем”. Kubernetes е пример за това – той решава проблема със secrets когато се управляват от него, но как стигат до там и къде се пазят преди това не е негов проблем.

Тук се намесва и ефекта на матрьошката – добър пример е LastPass или другите подобни password managers. Те обещават да пазатя всичките ни пароли, което е супер. Но те самите искат парола за да защитят останалите пароли. А къде да сложа тази парола? Обикновено Chrome Passwords е очевидното място. Той пък иска собсветна парола и encryption key. Аммм, а тях къде да ги запазя…

Едно сравнително просто решение за secrets е – ами в source control-a. Но пък парола в source control е лошо. Обаче пък дали не може някак все пак евентуално да го направим? Оказва се, че може със sealed secrets. Решението разчита на PKI, като private key-a се пази в Kubernetes cluster-a.

Инсталирането на sealed secrets е достатъчно просто – kubectl apply поредният yaml файл. Kubeseal се използва за криптиране на secrets и може да се дръпне от releases страницата.

За да криптираме нещо:

Трябва ни public key-a:

kubeseal --fetch-cert > pi-dev.pem

След това ни трябва нещо което да криптираме:

kubectl create secret generic my-secret --from-literal=pass=alabala --from-literal=user=kuku -o yaml --dry-run > my-secret.yaml

Криптираме (PowerShell не харесва <, трябва ви нормална конзола):

kubeseal --format=yaml --cert=pi-dev.pem < my-secret.yaml > my-secret-sealed.yaml

Връчваме го на нашият cluster:

kubectl apply -f my-secret.yaml

Проверяваме резултата:

kubectl get secrets

Ако всичко е проработило, може да запазим my-secret.yml в source control без угризения на съвестта. Същото важи и за pem файла, той не е тайна.

Secrets очаква base64 string, един начин да се генерира е с PowerShell:

$text = Read-Host -Prompt 'Text to base64 encode'
$bytes = [System.Text.Encoding]::ASCII.GetBytes($text)[Convert]::ToBase64String($bytes) | Set-Clipboard

ASCII.GetBytes изглежда старовремско, но е важно. Unicode.GetBytes чупи нещо по веригата base64 encodes string -> secret -> sealed secret -> secret (в k8s) -> dapr secret.