Використання постачальника KMS для шифрування даних
Ця сторінка показує, як налаштувати постачальника Служби керування ключами (KMS) та втулок для шифрування конфіденційних даних. У Kubernetes 1.32 існують дві версії шифрування даних за допомогою KMS у спокої. Якщо це можливо, вам слід використовувати KMS v2, оскільки KMS v1 застарів (починаючи з Kubernetes v1.28) та є типово вимкненим (починаючи з Kubernetes v1.29). KMS v2 пропонує значно кращі характеристики продуктивності, ніж KMS v1.
Увага:
Ця документація стосується загальновживаної реалізації KMS v2 (і застарілої реалізації версії 1). Якщо ви використовуєте будь-які компоненти панелі управління старші за Kubernetes v1.29, будь ласка, перевірте відповідну сторінку в документації для версії Kubernetes, яку використовує ваш кластер. Ранні версії Kubernetes мали різну поведінку, яка може бути важливою для інформаційної безпеки.Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Версія Kubernetes, яка вам потрібна, залежить від того, яку версію API KMS ви вибрали. Kubernetes рекомендує використовувати KMS v2.
- Якщо ви вибрали KMS API v1 для підтримки кластерів до версії v1.27 або якщо у вас є застарілий плагін KMS, який підтримує лише KMS v1, будь-яка підтримувана версія Kubernetes буде працювати. Цей API є застарілим починаючи з Kubernetes v1.28. Kubernetes не рекомендує використовувати цей API.
kubectl version
.KMS v1
Kubernetes v1.28 [deprecated]
Потрібна версія Kubernetes 1.10.0 або пізніше.
Починаючи з версії 1.29, реалізація v1 KMS типово вимкнена. Щоб увімкнути функцію, встановіть
--feature-gates=KMSv1=true
, щоб налаштувати постачальника KMS v1.Ваш кластер повинен використовувати etcd v3 або пізніше.
KMS v2
Kubernetes v1.29 [stable]
- Ваш кластер повинен використовувати etcd v3 або пізніше.
Шифрування KMS та ключі для кожного обʼєкта
Постачальник шифрування KMS використовує схему шифрування конвертів для шифрування даних в etcd. Дані шифруються за допомогою ключа шифрування даних (data encryption key — DEK). DEK шифруються за допомогою ключа шифрування ключа (key encryption key — KEK), який зберігається та обслуговується на віддаленому KMS.
Якщо ви використовуєте (застарілу) реалізацію v1 KMS, для кожного шифрування генерується новий DEK.
З KMS v2 для кожного шифрування генерується новий DEK: API-сервер використовує функцію похідного ключа для генерації ключів шифрування даних з одноразовим використанням секретного початкового елемента (seed — насіння) у поєднанні з випадковими даними. Ротація насіння відбувається при кожній зміні KEK (див. розділ Розуміння key_id та Ротація ключів нижче для докладніших відомостей).
Постачальник KMS використовує gRPC для звʼязку з певним втулком KMS через сокет UNIX-домену. Втулок KMS, який реалізований як сервер gRPC та розгорнутий на тих самих вузлах що і панель управління Kubernetes, відповідає за всі комунікації з віддаленим KMS.
Налаштування постачальника KMS
Для налаштування постачальника KMS на API-сервері включіть постачальника типу kms
у масиві providers
у файлі конфігурації шифрування і встановіть наступні властивості:
KMS v1
apiVersion
: Версія API для постачальника KMS. Залиште це значення порожнім або встановіть його наv1
.name
: Показує назву втулка KMS. Не може бути змінено після встановлення.endpoint
: Адреса прослуховування сервера gRPC (втулка KMS). Точка доступу — це сокет UNIX-домену.cachesize
: Кількість ключів шифрування даних (DEK), які будуть збережені в кеші у відкритому вигляді. Коли ключі DEK збережені в кеші, вони можуть бути використані без додаткового звертання до KMS; тоді як ключі DEK, які не збережені в кеші, потребують звертання до KMS для розшифрування.timeout
: Скільки часуkube-apiserver
має чекати на відповідь від втулка kms, перш ніж сповістити про помилку (типово — 3 секунди).
KMS v2
apiVersion
: Версія API для постачальника KMS. Встановіть це наv2
.name
:Показує назву втулка KMS. Не може бути змінено після встановлення.endpoint
: Адреса прослуховування сервера gRPC (втулка KMS). Точка доступу — це сокет UNIX-домену.timeout
: Скільки часуkube-apiserver
має чекати на відповідь від втулка kms, перш ніж сповістити про помилку (типово — 3 секунди).
KMS v2 не підтримує властивість cachesize
. Всі ключі шифрування даних (DEK) будуть збережені в кеші у відкритому вигляді, як тільки сервер розкриє їх за допомогою звертання до KMS. Після збереження в кеші, ключі DEK можуть бути використані для виконання розшифрування нескінченно довго без звертання до KMS.
Дивіться Розуміння налаштування шифрування в спокої.
Реалізація втулка KMS
Для реалізації втулка KMS ви можете розробити новий сервер gRPC втулка або увімкнути втулок KMS, який вже надається вашим постачальником хмарних послуг. Потім ви інтегруєте втулок з віддаленим KMS та розгортаєте його на панелі управління Kubernetes.
Увімкнення KMS, що підтримується вашим постачальником хмарних послуг
Зверніться до вашого постачальника хмарних послуг для отримання інструкцій щодо увімкнення втулка KMS, який він надає.
Розробка сервера gRPC втулка KMS
Ви можете розробити сервер gRPC втулка KMS, використовуючи файл шаблону, доступний для мови програмування Go. Для інших мов програмування ви можете використовувати файл proto для створення файлу шаблону, який ви можете використовувати для написання коду сервера gRPC.
KMS v1
Використовуючи Go: Використовуйте функції та структури даних у файлі шаблону: api.pb.go для написання коду сервера gRPC.
Використовуючи інших мов програмування: Використовуйте компілятор protoc з файлом proto: api.proto для генерації файлу шаблону для конкретної мови програмування.
KMS v2
Використовуючи Go: Надається високорівнева бібліотека для спрощення процесу. Низькорівневі реалізації можуть використовувати функції та структури даних у файлі шаблону: api.pb.go для написання коду сервера gRPC.
Використовуючи інших мов програмування: Використовуйте компілятор protoc з файлом proto: api.proto для генерації файлу шаблону для конкретної мови програмування.
Потім використовуйте функції та структури даних у файлі шаблону для написання коду сервера.
Примітки
KMS v1
Версія втулка kms:
v1beta1
У відповідь на виклик процедури Version сумісний втулок KMS повинен повернути
v1beta1
якVersionResponse.version
.Версія повідомлення:
v1beta1
Усі повідомлення від постачальника KMS мають поле версії встановлене на
v1beta1
.Протокол: UNIX доменний сокет (
unix
)Втулок реалізований як сервер gRPC, який слухає UNIX доменний сокет. Розгортання втулка повинно створити файл у файловій системі для запуску зʼєднання gRPC unix domain socket. API-сервер (клієнт gRPC) налаштований на постачальника KMS (сервер gRPC) за допомогою точки доступу UNIX доменного сокета для звʼязку з ним. Може використовуватися абстрактний Linux сокет, точка доступу якого починається з
/@
, наприклад,unix:///@foo
. Слід бути обережним при використанні цього типу сокета, оскільки вони не мають концепції ACL (на відміну від традиційних файлових сокетів). Однак вони підпадають під простір імен мережі Linux, тому будуть доступні лише контейнерам у тому ж самому Podʼі, якщо не використовується мережа хосту.
KMS v2
Версія втулка KMS:
v2
У відповідь на віддалений виклик процедури
Status
сумісний втулок KMS повинен повернути свою версію сумісності KMS якStatusResponse.version
. У цій відповіді на статус також повинен бути включений "ok" якStatusResponse.healthz
іkey_id
(ідентифікатор KEK віддаленого KMS) якStatusResponse.key_id
. Проєкт Kubernetes рекомендує зробити ваш втулок сумісним зі стабільнимv2
API KMS. Kubernetes 1.32 також підтримуєv2beta1
API для KMS; майбутні релізи Kubernetes, швидше за все, будуть продовжувати підтримувати цю бета-версію.API-сервер надсилає віддалений виклик процедури
Status
приблизно кожну хвилину, коли все в справному стані, і кожні 10 секунд, коли втулок не справний. Втулки повинні пильнувати за оптимізацією цього виклику, оскільки він буде під постійним навантаженням.Шифрування
Виклик процедури
EncryptRequest
надає текст для шифрування та UID для цілей логування. У відповіді повинен бути включений шифротекст,key_id
для використаного KEK та, опціонально, будь-які метадані, які потрібні втулку KMS для допомоги в майбутніх викликахDecryptRequest
(через полеannotations
). Втулок повинен гарантувати, що будь-який різний текст призводить до різної відповіді(шифротекст, key_id, annotations)
.Якщо втулок повертає непорожній масив
annotations
, всі ключі масиву повинні бути повністю кваліфікованими доменними іменами, такими якexample.com
. Приклад використанняannotations
—{"kms.example.io/remote-kms-auditid":"<audit ID використаний віддаленим KMS>"}
API-сервер не виконує виклик процедури
EncryptRequest
на високому рівні. Реалізації втулків повинні все ж старатися, щоб зберегти час очікування кожного запиту менше 100 мілісекунд.Розшифрування
Виклик процедури
DecryptRequest
надає(ciphertext, key_id, annotations)
зEncryptRequest
та UID для цілей логування. Як і очікується, це протилежне викликуEncryptRequest
. Втулки повинні перевірити, щоkey_id
є тим, що вони розуміють — вони не повинні намагатися розшифрувати дані, якщо вони не впевнені, що вони були зашифровані ними раніше.API-сервер може виконати тисячі викликів процедури
DecryptRequest
під час запуску для заповнення свого кешу перегляду. Таким чином, реалізації втулків повинні виконати ці виклики якнайшвидше, і повинні старатися зберегти час очікування кожного запиту менше 10 мілісекунд.Розуміння
key_id
та Ротації ключаkey_id
є публічним, незасекреченим імʼям віддаленого KEK KMS, який в цей момент використовується. Він може бути зареєстрований під час регулярної роботи API-сервера та, отже, не повинен містити ніяких приватних даних. Реалізації втулків повинні використовувати хеш, щоб уникнути витоку будь-яких даних. Метрики KMS v2 пильнують за хешуванням цього значення перед показом його через точку доступу/metrics
.API-сервер вважає, що
key_id
, отриманий з виклику процедуриStatus
, є авторитетним. Отже, зміна цього значення сигналізує API-серверу, що віддалений KEK змінився, і дані, зашифровані старим KEK, повинні бути позначені як застарілі при виконанні операція запису без операції (як описано нижче). Якщо виклик процедуриEncryptRequest
повертаєkey_id
, який відрізняється відStatus
, відповідь відкидається, і втулок вважається несправним. Таким чином, реалізації повинні гарантувати, щоkey_id
, що повертається зіStatus
, буде таким самим, як той, що повертається зEncryptRequest
. Крім того, втулки повинні забезпечити стабільністьkey_id
і не допускати перемикання між значеннями (тобто під час ротації віддаленого KEK).Втулки не повинні повторно використовувати
key_id
, навіть у ситуаціях, коли раніше використаний віддалений KEK був відновлений. Наприклад, якщо втулок використовувавkey_id=A
, перемикнувся наkey_id=B
, а потім повернувся доkey_id=A
— замість того, щоб повідомитиkey_id=A
, втулок повинен повідомити якесь похідне значення, таке якkey_id=A_001
або використовувати нове значення, наприкладkey_id=C
.Оскільки API-сервер опитує
Status
приблизно кожну хвилину, ротаціяkey_id
не є миттєвою. Крім того, API-сервер буде користуватися останнім дійсним станом протягом приблизно трьох хвилин. Таким чином, якщо користувач хоче здійснити пасивний підхід до міграції зберігання (тобто, чекаючи), він повинен запланувати міграцію на3 + N + M
хвилин після ротації віддаленого KEK (N
— це час, необхідний для того, щоб втулок помітив змінуkey_id
, іM
— бажаний буфер, щоб дозволити обробку змін конфігурації, рекомендується мінімальне значенняM
в пʼять хвилин). Зазначте, що для виконання ротації KEK перезапуск API-сервера не потрібен.Увага:
Оскільки ви не контролюєте кількість записів, виконаних з DEK, проєкт Kubernetes рекомендує робити ротацію KEK принаймні кожні 90 днів.Протокол: UNIX доменний сокет (
unix
)Втулок реалізований як сервер gRPC, який слухає UNIX доменний сокет. Розгортання втулка повинно створити файл у файловій системі для запуску зʼєднання gRPC unix domain socket. API-сервер (клієнт gRPC) налаштований на постачальника KMS (сервер gRPC) за допомогою точки доступу UNIX доменного сокета для звʼязку з ним. Може використовуватися абстрактний Linux сокет, точка доступу якого починається з
/@
, наприклад,unix:///@foo
. Слід бути обережним при використанні цього типу сокета, оскільки вони не мають концепції ACL (на відміну від традиційних файлових сокетів). Однак вони підпадають під простір імен мережі Linux, тому будуть доступні лише контейнерам у тому ж самому Podʼі, якщо не використовується мережа хосту.
Інтеграція втулка KMS з віддаленим KMS
Втулок KMS може спілкуватися з віддаленим KMS за допомогою будь-якого протоколу, який підтримується KMS. Усі дані конфігурації, включаючи облікові дані автентифікації, які використовує втулок KMS для спілкування з віддаленим KMS, зберігаються і керуються втулком KMS незалежно. Втулок KMS може кодувати шифротекст з додатковими метаданими, які можуть бути потрібні перед відправленням його в KMS для розшифрування (KMS v2 робить цей процес простішим, надаючи спеціальне поле annotations
).
Розгортання втулка KMS
Переконайтеся, що втулок KMS працює на тих самих хостах, що і сервер(и) API Kubernetes.
Шифрування даних за допомогою постачальника KMS
Для шифрування даних виконайте наступні кроки:
Створіть новий файл
EncryptionConfiguration
, використовуючи відповідні властивості для постачальникаkms
, щоб шифрувати ресурси, такі як Secrets та ConfigMaps. Якщо ви хочете зашифрувати розширення API, яке визначено у визначенні CustomResourceDefinition, ваш кластер повинен працювати на Kubernetes v1.26 або новіше.Встановіть прапорець
--encryption-provider-config
на kube-apiserver, щоб вказати місце розташування файлу конфігурації.Аргумент
--encryption-provider-config-automatic-reload
типу boolean визначає, чи слід автоматично перезавантажувати файл, встановлений за допомогою--encryption-provider-config
, у разі зміни вмісту на диску.Перезапустіть свій API-сервер.
KMS v1
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
- configmaps
- pandas.awesome.bears.example
providers:
- kms:
name: myKmsPluginFoo
endpoint: unix:///tmp/socketfile-foo.sock
cachesize: 100
timeout: 3s
- kms:
name: myKmsPluginBar
endpoint: unix:///tmp/socketfile-bar.sock
cachesize: 100
timeout: 3s
KMS v2
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
- configmaps
- pandas.awesome.bears.example
providers:
- kms:
apiVersion: v2
name: myKmsPluginFoo
endpoint: unix:///tmp/socketfile-foo.sock
timeout: 3s
- kms:
apiVersion: v2
name: myKmsPluginBar
endpoint: unix:///tmp/socketfile-bar.sock
timeout: 3s
Встановлення --encryption-provider-config-automatic-reload
в true
обʼєднує всі перевірки стану в одну точку доступу перевірки стану. Індивідуальні перевірки стану доступні тільки тоді, коли використовуються постачальники KMS v1 і конфігурація шифрування не перезавантажується автоматично.
Наступна таблиця містить підсумки точок доступу перевірки стану для кожної версії KMS:
Конфігурації KMS | Без автоматичного перезавантаження | З автоматичним перезавантаженням |
---|---|---|
Тільки KMS v1 | Індивідуальні перевірки | Одна перевірка |
Тільки KMS v2 | Одна перевірка | Одна перевірка |
KMS v1 та KMS v2 | Індивідуальні перевірки | Одна перевірка |
Без KMS | Немає | Одна перевірка |
Одна перевірка
означає, що єдиною точкою доступу перевірки стану є /healthz/kms-providers
.
Індивідуальні перевірки
означає, що для кожного втулка KMS є асоційована точка доступу перевірки стану на основі його місця в конфігурації шифрування: /healthz/kms-provider-0
, /healthz/kms-provider-1
тощо.
Ці шляхи точок доступу перевірки стану жорстко закодовані та генеруються/контролюються сервером. Індекси для індивідуальних перевірок відповідають порядку, у якому обробляється конфігурація шифрування KMS.
До виконання кроків, визначених у Забезпечення шифрування всіх секретів, список providers
повинен закінчуватися постачальником identity: {}
, щоб можна було читати незашифровані дані. Після шифрування всіх ресурсів постачальника identity
слід видалити, щоб запобігти обробці незашифрованих даних сервером API.
Для отримання деталей про формат EncryptionConfiguration
, будь ласка, перегляньте
довідник API шифрування API сервера.
Перевірка того, що дані зашифровані
Коли шифрування даних у стані спокою правильно налаштовано, ресурси шифруються під час запису. Після перезапуску вашого kube-apiserver
, будь-які новостворені або оновлені Secret чи інші типи ресурсів, налаштовані в EncryptionConfiguration
, мають бути зашифровані при зберіганні. Щоб перевірити, ви можете використовувати програму командного рядка etcdctl
для отримання вмісту ваших секретних даних.
Створіть новий Secret з назвою
secret1
в просторі іменdefault
:kubectl create secret generic secret1 -n default --from-literal=mykey=mydata
Використовуючи командний рядок
etcdctl
, прочитайте цей Secret з etcd:ETCDCTL_API=3 etcdctl get /kubernetes.io/secrets/default/secret1 [...] | hexdump -C
де
[...]
містить додаткові аргументи для підключення до сервера etcd.Переконайтеся, що збережений Secret починається з префікса
k8s:enc:kms:v1:
для KMS v1 або з префіксаk8s:enc:kms:v2:
для KMS v2, що вказує на те, що постачальникkms
зашифрував результати даних.Перевірте, що Secret правильно розшифровується при отриманні через API:
kubectl describe secret secret1 -n default
Secret повинен містити
mykey: mydata
.
Забезпечення шифрування всіх секретів
Коли шифрування даних у стані спокою правильно налаштовано, ресурси шифруються під час запису. Таким чином, ми можемо виконати оновлення без змін на місці, щоб переконатися, що дані зашифровані.
Наведена нижче команда читає всі Secret, а потім оновлює їх для застосування шифрування на сервері. У разі помилки через конфліктний запис, повторіть команду. Для більших кластерів вам може знадобитися поділити Secret за просторами імен або написати скрипт для оновлення.
kubectl get secrets --all-namespaces -o json | kubectl replace -f -
Перехід від локального постачальника шифрування до постачальника KMS
Щоб перейти від локального постачальника шифрування до постачальника kms
та перешифрувати всі секрети:
Додайте постачальника
kms
як перший запис у файлі конфігурації, як показано в наступному прикладі.apiVersion: apiserver.config.k8s.io/v1 kind: EncryptionConfiguration resources: - resources: - secrets providers: - kms: apiVersion: v2 name: myKmsPlugin endpoint: unix:///tmp/socketfile.sock - aescbc: keys: - name: key1 secret: <BASE 64 ENCODED SECRET>
Перезапустіть усі процеси
kube-apiserver
.Виконайте наступну команду, щоб змусити всі секрети перешифруватися за допомогою постачальника
kms
.kubectl get secrets --all-namespaces -o json | kubectl replace -f -
Що далі
Якщо ви більше не хочете використовувати шифрування для даних, збережених в API Kubernetes, прочитайте розшифровування даних, які вже зберігаються у спокої.