+1 098новых вакансий за сутки92 474вакансии открыты сейчасНовое:Talanto осенью: фильтры с числами, отклик по шагам и каталог компаний
Secrets хранятся в etcd в base64 (не зашифровано). Для шифрования нужно включить Encryption at Rest через EncryptionConfiguration с провайдером aescbc/aesgcm/kms. После включения надо перезаписать все существующие Secrets командой kubectl get/replace.
Все объекты Kubernetes, включая Secret, хранятся в etcd. По умолчанию данные пишутся в base64-кодировке, что является кодированием, а не шифрованием. Любой, кто имеет доступ к файлам etcd или бэкапам, может тривиально декодировать содержимое:
echo "c3VwZXJzZWNyZXQ=" | base64 -d
# supersecret
Причина исторически проста: изначально Secrets задумывались как механизм доступа (RBAC), а не хранения. Шифрование добавили позже как опциональную фичу.
Нужно создать файл EncryptionConfiguration и передать его API-серверу через флаг --encryption-provider-config.
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aesgcm:
keys:
- name: key1
secret: c2VjcmV0a2V5MTIzNDU2Nzg5MDEyMzQ1Ng==
- identity: {}
Провайдеры (первый в списке — для записи, остальные — для чтения при ротации):
identity — без шифрования (дефолт).aescbc — AES-CBC, устарел, уязвим к padding oracle в старых версиях.aesgcm — AES-GCM, рекомендован для локального шифрования.kms v2 — делегирует шифрование внешнему KMS (AWS KMS, GCP KMS, HashiCorp Vault).secretbox — XSalsa20+Poly1305, быстрее AES на CPU без AES-NI.providers:
- kms:
apiVersion: v2
name: aws-kms
endpoint: unix:///var/run/kmsplugin/socket.sock
timeout: 3s
- identity: {}
KMS v2 использует envelope encryption: данные шифруются локальным DEK, сам DEK шифруется мастер-ключом в KMS. Это изолирует ротацию ключей от объёма данных.
# На узле control-plane (kubeadm)
sudo mkdir -p /etc/kubernetes/enc
sudo cp encryption-config.yaml /etc/kubernetes/enc/
# Добавить в /etc/kubernetes/manifests/kube-apiserver.yaml:
# - --encryption-provider-config=/etc/kubernetes/enc/encryption-config.yaml
# + volumeMount и hostPath volume
Важно: после включения шифрования уже существующие Secrets в etcd остаются в открытом виде. Их нужно перезаписать принудительно:
kubectl get secrets --all-namespaces -o json | \
kubectl replace -f -
# Прочитать raw-данные из etcd (на control-plane узле)
ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
get /registry/secrets/default/my-secret | hexdump -C | head -5
# Если видите k8s:enc:aesgcm:v1 в начале — шифрование работает
/etc/kubernetes/enc/, а etcd — там же, атакующий с доступом к ФС получает и данные, и ключ. KMS решает эту проблему.get secrets, шифрование в etcd ему не помеха — он получит данные через API.EncryptionConfiguration позволяет зашифровать и configmaps — добавьте их в resources.