Шифрування — це легка частина. Управління ключами — це те, що помічають лише коли його немає — зазвичай о 02:13 під час збою, коли старший менеджер питає, чи «дані ще там», ніби це філософське питання.
Вбудоване шифрування ZFS міцне, швидке й оманливо просте у включенні. Проблема в тому, що «encryption=on» — це не план. План — це: як ключі створюються, зберігаються, завантажуються, ротуються, аудитується, бекапляться та відновлюються, коли коробка померла, пул імпортувався тільки для читання, а ваш менеджер паролів теж лежить на тому пулі. Це посібник для людей, які реально керують продакшн-системами — і хочуть продовжувати це робити.
Що ви насправді керуєте (і чому це важче, ніж здається)
Шифрування ZFS — це не один вимикач. Це набір властивостей, прив’язаних до наборів даних, плюс набір поведінок, що проявляються в найневідповідніші моменти: завантаження, імпорт, відмово-перехід, відновлення, реплікація та аудити.
На високому рівні вбудоване шифрування ZFS працює так:
- Ви створюєте зашифрований набір даних з
encryption=on. - ZFS використовує обгортковий ключ, виведений з пароля або збереженого ключового матеріалу (
keyformat), щоб захистити ключ набору даних. - Блоки даних шифруються; метадані частково захищені залежно від налаштувань і реалій на диску.
- Щоб змонтувати зашифрований набір даних, зазвичай потрібно завантажити ключ (розблокувати), а потім змонтувати.
Управління ключами — це все навколо моменту розблокування: звідки приходить ключ, хто має доступ, як його ротувати та як довести, що ви можете відновитися без імпровізацій.
Жарт, бо він знадобиться: шифрування без процесу відновлення ключів — це як парашут, який ви купили онлайн, але ніколи не приміряли — технічно він є, емоційно непотрібний.
Три «площини реальності», які потрібно узгодити
Більшість катастроф з ключами ZFS відбуваються, коли ці три площини не узгоджені:
- Рівень набору даних: властивості як
encryption,keyformat,keylocation,keystatus, межі спадкування і чи успадковують ключ дочірні набори даних. - Рівень хоста: процес завантаження, initramfs, порядок сервісів, доступність файлів ключів, запити паролів, консолі, яких не існує (вітаємо, хмарні серійні консолі), і реальність того, що «введемо при завантаженні» перестає працювати, коли у вас 50 вузлів.
- Рівень людей: хто знає пароль, як він зберігається, як його ротувати без простоїв, як відкликати доступ і як довести, що це не «театр безпеки» зі спільним паролем у чаті.
Термінологія ZFS ключів, якою варто оперувати точно
В опс-розмовах слова «ключ» і «пароль» зливаються. Для шифрування ZFS будьте точні:
- Dataset encryption key (DEK): внутрішній ключ, який шифрує дані. Ви не вводите його вручну; ZFS ним керує.
- Wrapping key / key material: те, що захищає DEK. Це виводиться від паролю або походить з файлу ключа, залежно від
keyformat. - Loaded key: матеріал ключа в пам’яті і готовий до використання. Це те, що робить
zfs load-key. - Ротація ключа: зазвичай означає зміну обгорткового ключа (перепакування DEK), а не повторне шифрування всіх блоків даних.
Цікаві факти та контекст: як ми дійшли до цього
Помилки в управлінні ключами — це не особистий провал. Це галузева традиція. Кілька корисних контекстних пунктів:
- ZFS народився в Sun Microsystems у середині 2000-х з філософією «все з контрольними сумами», яка досі виглядає футуристично в порівнянні з багатьма застарілими стеками.
- Вбудоване шифрування ZFS з’явилося пізніше, ніж багато хто думає; роками люди використовували GELI (FreeBSD), LUKS/dm-crypt (Linux) або апаратне шифрування під ZFS.
- Ранні підходи «шифрувати весь диск» у деяких аспектах спрощували відновлення і процедури завантаження (одне розблокування), але ускладнювали реплікацію та тонкий контроль доступу.
- Операційно, шифрування стало від нішевого до звичного, коли вимоги відповідності (і заголовки про витоки) зробили «шифрування в стані спокою» стандартом навіть для внутрішніх систем.
- Модель наборів даних ZFS — це подвійний меч: вона дає тонке розмежування шифрування, але також дає вам 400 способів створити неконсистентне спадкування, яке ви не помітите до дня відновлення.
- Помилки в управлінні ключами часто бувають «помилками успіху»: команди успішно автоматизують розблокування для зручності і випадково позбавляють себе будь-якого змістовного контролю доступу.
- Резервні системи історично боролися з зашифрованими наборами, бо адміністратори плутали «шифровано на диску» з «безпечно в дорозі» або «безпечно в резервних копіях», що — різні задачі.
- Галузь навчалась (багато разів), що зберігання єдиної копії ключа на зашифрованому сховищі — це скоріше перформанс-арт, ніж інженерія.
Модель загроз: що шифрування ZFS захищає (і не захищає)
Якщо ви цього не задокументуєте, організація вигадає її пізніше під час розслідування витоку.
Що вбудоване шифрування ZFS захищає добре
- Вкрадені диски / списані накопичувачі: якщо хтось виніс диски або весь шасі, зашифровані набори даних захищають дані в стані спокою (за умови, що ключі не зберігаються разом із дисками).
- «Ой, ми відправили неправильне RMA» ситуації: шифрування знижує вплив, коли обладнання виходить з-під вашого контролю.
- Мультиорендальні межі на спільному сховищі: ключі наборів даних можуть розділяти доступ, в межах обмежень середовища хоста.
Чого воно не захищає
- Шкідливе ПЗ на хості: якщо набір даних змонтований і ключ завантажений, рансумвар читає/пише без проблем.
- Root на хості: root зазвичай може читати пам’ять, перехоплювати завантаження ключа або отримати доступ до файлів ключів залежно від налаштувань.
- Екфільтрація з додатків: шифрування ZFS нижче API файлової системи; додатки бачать відкритий текст.
Рішення в моделі загроз, які потрібно прийняти явно
- Чи потрібне безлюдне завантаження? Якщо так, ваш ключ або зберігається локально (менш безпечно), або отримується з мережевого сервісу (більше рухомих частин). Обидва варіанти валідні; уникати компромісу — погана ідея.
- Чи потрібні ключі на рівні набору даних? Чудово для принципу найменших привілеїв; болісно для опсів, якщо ви не стандартизуєте іменування та спадкування.
- Який у вас план «break glass»? Хто може розблокувати під час інциденту і як вони це роблять без археології в Slack.
Шаблони проєктування ключів, що виживають у реальному житті
Шаблон 1: Один зашифрований корінь із успадкованими ключами (нудно, ефективно)
Це шаблон «хочу спати». Ви шифруєте топовий набір даних (часто корінь пулу або призначений батько), встановлюєте успадкування дітей і зменшуєте кількість різних ключів.
Плюси: менше ключів, простіша процедура розблокування, легше відновлення після катастрофи. Мінуси: менше деталізованого розділення між наборами даних.
Шаблон 2: Декілька ключів за доменами (безпечніше, дорожче для опсів)
Ви групуєте набори даних за чутливістю: наприклад, pool/app, pool/db, pool/secrets, кожен з окремими обгортковими ключами. Ви погоджуєтесь, що розблокування і відновлення потребуватимуть ретельної хореографії.
Плюси: краща ізоляція. Мінуси: більше роботи по ротації ключів, більше залежностей під час завантаження, більше шансів забути один набір даних до помилки при відновленні.
Шаблон 3: Пароль проти файлу ключа (обирайте за реальністю завантаження)
Пароль: люди можуть ввести його, але люди — ненадійна інфраструктура. Добре для ноутбуків, менш добре для серверів без консолі, якщо у вас немає надійної віддаленої консолі і процедур.
Файл ключа: дружній до автоматизації, але файл треба захищати. Якщо файл ключа живе на тому ж сервері, ви здебільшого перемістили проблему. Якщо він витягується з безпечного джерела при завантаженні, ви побудували систему розподілу ключів — вітаємо з новою підсистемою.
Шаблон 4: keylocation — це інтерфейс, а не стратегія зберігання
ZFS дозволяє встановити keylocation як prompt або шлях до файлу. Це не рішення для управління ключами; це вказівник. Ваша фактична стратегія: звідки береться файл ключа, як він правиться правами доступу, як його ротувати і як відновлювати, якщо коробка мертва.
Шаблон 5: Правило «двох контролів» для продакшн-наборів даних
Практично: не дозволяйте одному адмінському ноутбуку з менеджером паролів бути єдиним шляхом до розблокування продакшн-даних. Використовуйте або загальний ескроу (з аудитом), або процес подвійного контролю. Аудитори це оцінять. Ваш інцидент-менеджер буде в захваті.
Практичні завдання з командами (і що означає вивід)
Команди нижче припускають OpenZFS на Linux, виконуються від root, якщо не вказано інше. Вивід репрезентативний; ваші поля можуть відрізнятися.
Завдання 1: Інвентаризація стану шифрування по пулу
cr0x@server:~$ zfs list -r -o name,encryption,keyformat,keylocation,keystatus,mounted pool
NAME ENCRYPTION KEYFORMAT KEYLOCATION KEYSTATUS MOUNTED
pool off - - - yes
pool/system aes-256-gcm passphrase prompt available yes
pool/system/var aes-256-gcm passphrase prompt available yes
pool/data aes-256-gcm raw file:///etc/zfs/keys/pool.data.key available yes
pool/data/backups aes-256-gcm raw file:///etc/zfs/keys/pool.data.key available yes
pool/archive aes-256-gcm passphrase prompt unavailable no
Інтерпретація: keystatus=unavailable означає, що набір даних заблокований (ключ не завантажений). Якщо mounted=no і keystatus=available, у вас проблема монтування, а не ключа.
Завдання 2: Підтвердити, які набори успадковують ключ, а які мають свій
cr0x@server:~$ zfs get -r -o name,property,value,source keylocation pool/system
NAME PROPERTY VALUE SOURCE
pool/system keylocation prompt local
pool/system/var keylocation prompt inherited from pool/system
Інтерпретація: Межі спадкування — це місце, де починається розростання ключів. Стовпець source показує, де ви випадково встановили «local» і відгалузили управління ключами.
Завдання 3: Створити зашифрований набір даних з запитом пароля
cr0x@server:~$ zfs create -o encryption=on -o keyformat=passphrase -o keylocation=prompt pool/secure
Enter passphrase:
Re-enter passphrase:
Інтерпретація: Це створює набір даних і встановлює його так, щоб вимагати пароль при завантаженні ключів. Добре для інтерактивних робочих процесів розблокування; ризиковано для безлюдного завантаження.
Завдання 4: Створити зашифрований набір даних з використанням файлу ключа
cr0x@server:~$ install -d -m 0700 /etc/zfs/keys
cr0x@server:~$ head -c 32 /dev/urandom > /etc/zfs/keys/pool.app.key
cr0x@server:~$ chmod 0400 /etc/zfs/keys/pool.app.key
cr0x@server:~$ zfs create -o encryption=on -o keyformat=raw -o keylocation=file:///etc/zfs/keys/pool.app.key pool/app
Інтерпретація: keyformat=raw очікує байти ключа. Права доступу мають значення; файл тепер — королівський артефакт. Якщо його можуть прочитати випадкові користувачі, ваше шифрування — здебільшого прикраса.
Завдання 5: Заблокувати і розблокувати набір даних (та перевірити)
cr0x@server:~$ zfs unmount pool/app
cr0x@server:~$ zfs unload-key pool/app
cr0x@server:~$ zfs get -o name,property,value keystatus pool/app
NAME PROPERTY VALUE
pool/app keystatus unavailable
cr0x@server:~$ zfs load-key pool/app
cr0x@server:~$ zfs mount pool/app
cr0x@server:~$ zfs get -o name,property,value keystatus pool/app
NAME PROPERTY VALUE
pool/app keystatus available
Інтерпретація: Спочатку відмонтуйте, потім завантажуйте ключ. Якщо ви намагаєтесь розвантажити ключ, коли набір змонтований, ZFS зазвичай відмовить, бо ключ використовується.
Завдання 6: Імпортувати пул без монтування, а потім навмисно розблокувати
cr0x@server:~$ zpool import -N pool
cr0x@server:~$ zfs load-key -a
cr0x@server:~$ zfs mount -a
Інтерпретація: -N імпортує без монтування, що корисно при контрольованому відновленні: спочатку імпорт, потім розблокування ключів, наприкінці — монтування. Це робить помилки очевидними і безпечнішими.
Завдання 7: Виявити, чому набір даних не монтується (ключ vs точка монтування vs зайнятість)
cr0x@server:~$ zfs mount pool/archive
cannot mount 'pool/archive': encryption key not loaded
cr0x@server:~$ zfs load-key pool/archive
Enter passphrase for 'pool/archive':
Інтерпретація: ZFS ввічливо підказує реальну причину. Коли воно говорить «key not loaded», не займайтеся налаштуванням ARC і написанням постмортемів про продуктивність.
Завдання 8: Ротувати обгортковий ключ (змінити пароль) без повторного шифрування даних
cr0x@server:~$ zfs change-key pool/secure
Enter new passphrase:
Re-enter new passphrase:
Інтерпретація: Це змінює обгортковий ключ для кореня шифрування цього набору. Це швидко, бо перепаковує матеріал ключа, а не перезаписує всі блоки.
Завдання 9: Ротувати матеріал ключа для набору з файлом ключа
cr0x@server:~$ head -c 32 /dev/urandom > /etc/zfs/keys/pool.app.key.new
cr0x@server:~$ chmod 0400 /etc/zfs/keys/pool.app.key.new
cr0x@server:~$ zfs set keylocation=file:///etc/zfs/keys/pool.app.key.new pool/app
cr0x@server:~$ zfs change-key pool/app
cr0x@server:~$ mv /etc/zfs/keys/pool.app.key.new /etc/zfs/keys/pool.app.key
Інтерпретація: Оновіть keylocation, потім change-key. Тримайте старий ключ поки не перевірите розблокування після перезавантаження/імпорту. Так, це пастка, якщо видалити занадто рано.
Завдання 10: Знайти корінь шифрування і підтвердити ієрархію
cr0x@server:~$ zfs get -o name,property,value -r encryptionroot pool/data
NAME PROPERTY VALUE
pool/data encryptionroot pool/data
pool/data/backups encryptionroot pool/data
Інтерпретація: Дочірні набори успадковують ключі від кореня шифрування. Якщо ви бачите дочірні з різними encryptionroot, ваша процедура розблокування має це враховувати.
Завдання 11: Підтвердити, що ключі випадково не збережені на зашифрованому пулі
cr0x@server:~$ zfs get -o name,property,value keylocation pool/data
NAME PROPERTY VALUE
pool/data keylocation file:///etc/zfs/keys/pool.data.key
cr0x@server:~$ findmnt /etc/zfs/keys
TARGET SOURCE FSTYPE OPTIONS
/etc/zfs/keys /dev/sda1 ext4 rw,relatime
Інтерпретація: Файл ключа живе на /dev/sda1 (ймовірно, диск ОС), а не на pool. Якщо /etc знаходиться на зашифрованому пулі, який ви намагаєтесь розблокувати, ви побудували замкнуті двері з ключем, приклеєним на іншій стороні.
Завдання 12: Перевірити помилки розблокування під час завантаження через журнал systemd
cr0x@server:~$ journalctl -b -u zfs-import-cache -u zfs-mount -u zfs-load-key --no-pager
-- Journal begins at ...
systemd[1]: Starting Load ZFS keys...
zfs-load-key[1023]: cannot open 'file:///etc/zfs/keys/pool.data.key': No such file or directory
systemd[1]: zfs-load-key.service: Main process exited, code=exited, status=1/FAILURE
systemd[1]: Failed to start Load ZFS keys.
systemd[1]: Dependency failed for ZFS mount.
Інтерпретація: Це не баг ZFS; це проблема порядку запуску або доступності файлової системи. Ваш шлях до ключа не існував в момент запуску сервісу.
Завдання 13: Швидко перелічити завантажені ключі (в масштабі)
cr0x@server:~$ zfs list -H -o name,keystatus -r pool | awk '$2=="unavailable"{print $1}'
pool/archive
pool/secrets/hr
Інтерпретація: Це вид «що ще заблоковано?». Корисно під час відновлення або коли перезавантаження залишило набори даних недоступними.
Завдання 14: Перевірити, що зашифрований набір даних справді зашифрований на диску
cr0x@server:~$ zfs get -o name,property,value encryption,keyformat pool/secure
NAME PROPERTY VALUE
pool/secure encryption aes-256-gcm
pool/secure keyformat passphrase
Інтерпретація: encryption показує режим шифрування. Якщо він off, у вас немає шифрування; у вас є оптимізм.
Завдання 15: Тест циклу export/import (найближче до вогневого тренування)
cr0x@server:~$ zfs unmount -a
cr0x@server:~$ zfs unload-key -a
cr0x@server:~$ zpool export pool
cr0x@server:~$ zpool import -N pool
cr0x@server:~$ zfs load-key -a
cr0x@server:~$ zfs mount -a
cr0x@server:~$ zfs list -o name,mounted,keystatus -r pool | head
NAME MOUNTED KEYSTATUS
pool yes -
pool/system yes available
pool/data yes available
Інтерпретація: Це операційний тест, який ви повинні запустити перед тим, як довіряти будь-якій стратегії ключів. Це контрольований біль, що запобігає неконтрольованому болю пізніше.
Реплікація зашифрованих наборів: send/receive без серцяболю
Реплікація — це місце, де добрі наміри вмирають. Люди шифрують набори даних, потім припускають, що реплікація «просто працює», як раніше. Вона може — але вам потрібно вибрати, що саме ви реплікуєте: відкритий текст, шифротекст або щось посередині.
Три режими реплікації, які варто зрозуміти
- Відправляти відкритий текст (отримувач повторно шифрує): дані розшифровуються на стороні відправника і передаються як потік відкритого тексту; отримувач може зашифрувати своїм ключем. Це прийнятно в межах довіреної мережі, але це інша історія безпеки.
- Відправляти raw (шифротекст): отримувач отримує зашифровані блоки і (часто) ту ж структуру ключів набору даних. Це зберігає шифрування «від кінця до кінця», але змінює поведінку ключів і властивостей.
- Гібридні робочі процеси: відправляйте raw для архівів, відкритий текст для оперативних наборів даних, залежно від вимог відповідності та потреб відновлення.
Завдання 16: Відправити зашифрований набір як raw-потік
cr0x@server:~$ zfs snapshot -r pool/data@replica-001
cr0x@server:~$ zfs send -w -R pool/data@replica-001 | zfs receive -uF backup/data
Інтерпретація: -w відправляє raw-потік (зберігає шифрування). -u приймає без монтажу. Це як уникнути автоматичного монтування на цільовому бекапі. Після receive вам все ще знадобляться ключі, щоб змонтувати і прочитати.
Завдання 17: Отримати і встановити інший ключ на місці призначення (коли не відправляєте raw)
cr0x@server:~$ zfs snapshot pool/app@replica-001
cr0x@server:~$ zfs send pool/app@replica-001 | zfs receive -o encryption=on -o keyformat=passphrase -o keylocation=prompt backup/app
Інтерпретація: Це повторно шифрує на приймачі з ключами, контрольованими приймачем. Корисно, коли середовище бекапу має інші вимоги доступу.
Підступ реплікації: «raw send» може відтворити ваші помилки
Якщо ви використали ту ж ієрархію ключів всюди, raw send охоче її зберігає. Це може бути саме те, що вам потрібно — або саме те, що робить ваше «середовище бекапу» не відмінним від продакшну.
Три міні-історії з корпоративного фронту
Міні-історія 1: Інцидент через неправильне припущення («Воно нам запитає при завантаженні»)
У них був акуратний флот: десяток нод баз даних і кілька додатків з великим сховищем. Хтось увімкнув шифрування ZFS заради «відповідності», обрав запит пароля і вважав справу зробленою. Це працювало в лабораторії, бо завжди була людина за консоллю.
Потім спрацював буденний тригер: оновлення ядра та координоване перезавантаження. Половина хостів була в колокації з віддаленими руками; інша половина — інстанси в хмарі з серійною консоллю, яка технічно доступна, але практично непридатна під тиском часу. Процес завантаження чекав вводу пароля, якого ніхто не міг надати в масштабі.
On-call робив те, що роблять on-call-ники: імпровізував. Вони пробували змонтувати набори вручну, потім зрозуміли, що набори навіть не розблоковані. Спробували завантажити ключі, але «правильні» паролі були розкидані по кількох людях і одному сховищу паролів — яке зберігалося на зашифрованому пулі, що, звісно, був заблокований на одному з недоступних хостів.
Аварія тривала досить довго, щоб стати міжкомандним інцидентом. Ніхто не робив тренування з перезавантаження з увімкненим шифруванням. Неправильне припущення було не технічним; воно було організаційним: вони вважали, що людський запит є прийнятною залежністю в продакшні.
Після цього вони перейшли на розділений підхід: паролі для найчутливіших наборів, що можуть терпіти ручне розблокування, і ключі, отримувані по мережі, для решти з жорстким контролем доступу. Урок був не в тому, щоб ніколи не використовувати запити. Він був у тому, щоб не будувати критичний шлях, що залежить від спокійної людини за консоллю.
Міні-історія 2: Оптимізація, яка обернулася проти них («Зробимо розблокування повністю автоматичним»)
Інший магазин пішов у протилежний бік. Вони ненавиділи запити при завантаженні, тож повністю автоматизували розблокування, зберігаючи файли ключів на кореневій файловій системі кожного сервера. Встановили тісні права, використовували конфігураційний менеджмент і навіть ротували ключі щоквартально. Здавалося зріло.
Потім компрометували обліковий запис підрядника. Атакуючому не потрібні були експлойти ядра або криптовоєчу майстерність. Достатньо було привілеїв, щоб прочитати файл ключа на підмножині хостів. Далі зашифровані набори ZFS були лише перешкодою, а не бар’єром.
Післяінцидентний розбір був неприємним, бо ніхто не «помилився» у звичному сенсі. Команда оптимізувала доступність і експлуатованість, і їй це вдалося. Провалом було те, що вони оптимізували поза межі моделі загроз: шифрування мало захищати від втрати дисків і витоку при списанні, але керівництво вважало, що воно також захищає від компрометації хоста.
Виправлення не полягало у відмові від автоматизації; виправлення було у впровадженні реального розділення обов’язків. Ключі перенесли поза хост, вимагали автентифікованого отримання при завантаженні і обмежили, хто може доступатися до механізму отримання. Також додали сигнал моніторингу «ключі завантажені»: якщо набори розблоковувалися поза нормальними вікнами, це тригерило розслідування.
Другий жарт, бо ми його заслужили: єдине гірше за ключ, який не можна знайти, — це ключ, який знайшов кожен.
Міні-історія 3: Нудна, але правильна практика, що врятувала день (репетиція відновлення, яку ніхто не хоче)
Фінансово близька компанія мала ритуал: раз на квартал вони робили репетицію відновлення зашифрованих даних. Це не було гламурно. Це займало час. Це дратувало людей. Але саме завдяки цьому у них не було катастрофи, що карає кар’єру.
Репетиція була проста: вибрати набір даних, експортувати і імпортувати на чистому хості, завантажити ключі за задокументованим методом, змонтувати в режимі read-only, перевірити цілісність даних і задокументувати кожне відхилення. Мета не «зможемо ми це зробити коли-небудь»; мета — «зможемо це зробити у втомленому стані, під тиском і під час замороження змін».
Одного кварталу репетиція провалилася. Не через сам ZFS, а тому що процес ескроу ключів змістився. Відбулася ротація, і оновлений матеріал ключа ніколи не потрапив в офлайн-ескроу. Вони спіймали це під час запланованого тесту, а не під час події з вимогою викупу.
Вони виправили процес і додали правило: ротація ключів не вважається завершеною, доки репетиція відновлення не пройде. Люди скаржилися. Потім поличка зі сховищем померла несподівано, і їм довелося відновлюватися з реплікації та бекапів. Розблокування і монтування були найлегшою частиною відновлення — і це власне головна ідея.
План швидкої діагностики: що перевірити першим, другим, третім
Це для моменту, коли зашифровані набори даних не монтуються і всі дивляться на вас, ніби ви особисто загубили закони математики.
Перше: визначте, чи це проблема ключа, чи проблема пула
cr0x@server:~$ zpool status -x
all pools are healthy
cr0x@server:~$ zpool import
pool: pool
id: 1234567890
state: ONLINE
action: The pool can be imported using its name or numeric identifier.
Інтерпретація: Якщо пул не можна імпортувати або він деградований, спочатку виправляйте це. Ключі не допоможуть, якщо пул не онлайн.
Друге: перевірте стан ключа і корінь шифрування
cr0x@server:~$ zfs list -r -o name,keystatus,encryptionroot,mounted pool | sed -n '1,25p'
NAME KEYSTATUS ENCRYPTIONROOT MOUNTED
pool - - yes
pool/system available pool/system yes
pool/archive unavailable pool/archive no
Інтерпретація: Якщо keystatus=unavailable, не витрачайте час на налаштування точок монтування. Ваш наступний крок — zfs load-key.
Третє: перевірте доступність keylocation і порядок сервісів
cr0x@server:~$ zfs get -o name,property,value keylocation pool/archive
NAME PROPERTY VALUE
pool/archive keylocation file:///etc/zfs/keys/pool.archive.key
cr0x@server:~$ ls -l /etc/zfs/keys/pool.archive.key
ls: cannot access '/etc/zfs/keys/pool.archive.key': No such file or directory
Інтерпретація: Відсутній файл ключа — найпоширеніша помилка під час завантаження. Якщо він існує, перевірте права. Якщо ні — перевірте, чи не знаходиться він на файловій системі, яка ще не змонтована.
Четверте: спробуйте контрольований імпорт і розблокування
cr0x@server:~$ zpool export pool
cr0x@server:~$ zpool import -N pool
cr0x@server:~$ zfs load-key -a
Інтерпретація: Контрольовані послідовності зменшують сюрпризи. Якщо load-key не вдається, повідомлення про помилку зазвичай дієве (неправильний пароль, відсутній файл, недійсний URI).
П’яте: якщо все ще застрягли, збирайте докази перед імпровізацією
cr0x@server:~$ zfs get -r -o name,property,value,source encryption,keyformat,keylocation,keystatus,encryptionroot pool > /root/zfs-encryption-audit.txt
cr0x@server:~$ journalctl -b --no-pager > /root/boot-journal.txt
Інтерпретація: Це зберігає стан для подальшого аналізу і зупиняє команду від «виправлення» проблеми в загадку.
Поширені помилки: симптоми та виправлення
Помилка 1: Файл ключа збережено на зашифрованому пулі
Симптом: після перезавантаження zfs load-key не вдається через те, що шлях до файлу ключа не існує; набори даних залишаються заблокованими; ситуація «курка-яйце».
Виправлення: зберігайте ключі на незашифрованій кореневій файловій системі, знімному носії або механізмі мережевого отримання, доступному до монтування ZFS. Повторно протестуйте з zpool import -N і zfs load-key.
Помилка 2: «Ми використали шифрування, отже бекапи в безпеці»
Симптом: бекапи — це raw зашифровані потоки, але ключі не ескроувані; відновлення зазнає фіаско, коли первинний хост зник.
Виправлення: ескроуйте ключі (або паролі), необхідні для розблокування реплік, і проводьте репетиції відновлення. Якщо використовуєте raw send, переконайтесь, що приймальна сторона може розблокувати незалежно від відправника.
Помилка 3: Ротація ключів зроблена без тесту перезавантаження/імпорту
Симптом: все працює до наступного перезавантаження; потім набори даних не розблоковуються, бо keylocation вказує на ротований ключ, який не був розгорнутий скрізь.
Виправлення: після ротації проведіть тест export/import (Завдання 15) у вікні обслуговування або на канарному хості. Трактуйте ротацію як незавершену, доки вона не пройде тест.
Помилка 4: Дрейф спадкування створює «загадкові ключі»
Симптом: деякі дочірні набори вимагають різних ключів; автоматизація завантаження підвантажує більшість ключів, але один набір залишається заблокованим і додаток падає дивною помилкою.
Виправлення: аудитуйте encryptionroot і джерела keylocation. Стандартизуйтесь на стратегії encryption-root і примусьте це через код-рев’ю або політики.
Помилка 5: Увімкнено безлюдне завантаження з локально збереженими ключами, після чого оголосили «безпечно»
Симптом: під час перевірки відповідності питають «хто може розблокувати дані?» і чесна відповідь — «будь-хто з root на хості», що не те, що вважало керівництво.
Виправлення: узгодьте модель загроз. Якщо потрібно захиститися від компрометації хоста, локальні ключі не допоможуть. Перенесіть отримання ключів поза хост і зменшіть коло осіб з доступом до шляхів отримання.
Помилка 6: Плутання помилок імпорту пулу з помилками ключів
Симптом: інженери кілька разів запускають zfs load-key, але пул не імпортується або імпортується тільки для читання через помилки.
Виправлення: почніть з zpool status і zpool import. Спочатку зробіть пул здоровим/імпортованим; потім розблоковуйте.
Помилка 7: Забувають про снапшоти і доступ реплікації
Симптом: система бекапу отримує зашифровані набори, але не може змонтувати їх для перевірки; або перевірка розкриває відкритий текст у середовищах, для яких ви не планували.
Виправлення: вирішіть, чи дозволено цільовому бекапу дешифрувати. Якщо так — керуйте ключами там. Якщо ні — перевіряйте через контрольні суми або метадані і тримайте їх заблокованими за замовчуванням.
Контрольні списки / покроковий план
Контрольний список 1: Архітектурні рішення (перед тим, як вводити команди)
- Запишіть модель загроз: вкрадені диски? недобросовісний адмін? компрометація хоста? вимога відповідності?
- Визначте політику безлюдного завантаження для кожного класу систем (ноди баз даних vs архіви vs ноутбуки).
- Виберіть гранулярність ключів: один корінь шифрування vs по-домену vs по-набору даних.
- Визначте ескроу/break-glass: хто може розблокувати, як і де секрети живуть, коли основна система недоступна.
- Визначте графік ротації і що означає «ротація завершена» (підказка: протестований імпорт/розблокування).
Контрольний список 2: Побудувати ієрархію зашифрованих наборів даних безпечно
- Створіть корінь шифрування для домену (наприклад,
pool/data). - Встановіть дочірні набори успадковувати ключі, якщо немає обґрунтованого розділення.
- Задокументуйте корені шифрування і keylocations в репозиторії інфраструктури (не в чиїсь голові).
- Запустіть drill export/import (Завдання 15) перед переведенням у продакшн.
Контрольний список 3: Операційний ранбук для перезавантаження і відновлення
- Імпортуйте пули без монтування:
zpool import -N. - Завантажте ключі:
zfs load-key -a. - Монтуйте:
zfs mount -a. - Перевірте, що критичні набори змонтовані і ключі доступні.
- Перевіряйте роботу додатків тільки після підтвердження стану сховища.
Контрольний список 4: Ротація ключів покроково (безпечна версія)
- Оголосіть вікно техобслуговування і визначте площу ураження (корені шифрування, що зачеплені).
- Згенеруйте новий ключовий матеріал (політика паролів або байти ключа).
- Розгорніть матеріал на всі релевантні вузли (або в систему отримання ключів), але не видаляйте старий матеріал одразу.
- Змініть ключ:
zfs change-keyна коренях шифрування. - Зробіть контрольований тест export/import на канарному хості.
- Лише після успішного перезавантаження/імпорту: видаліть старий матеріал з активних місць, збережіть ескроу згідно політики.
Поширені питання
1) Якщо я зашифрую батьківський набір даних, чи будуть діти автоматично зашифровані?
Якщо дочірні створені під зашифрованим набором даних, вони зазвичай успадковують шифрування. Але спадкування може з часом зійти з рельсів, якщо хтось встановлює локальні властивості або створює набори в несподіваних місцях. Підтвердіть за допомогою zfs get -r encryption,encryptionroot.
2) Чи zfs change-key перевшифровує всі мої дані?
Ні, зазвичай він перепаковує матеріал ключа (швидко). Це все одно операційно ризиковано, бо ви можете відрізати собі доступ, якщо неправильно вчините з keylocation або ескроу. Поводьтеся з цим як з зміною, що потребує тестування.
3) У чому різниця між keyformat=passphrase і keyformat=raw?
passphrase виводить матеріал ключа з секрету, введеного людиною. raw очікує фактичні байти ключа (часто збережені у файлі). Raw дружній до автоматизації і може мати високу ентропію, але підвищує важливість захисту файлу ключа.
4) Чи можна розблокувати набір даних без його монтування?
Так. zfs load-key розблоковує (завантажує ключ у пам’ять); монтування — окреме. Це корисно для контрольованого відновлення і щоб уникнути монтажу в неправильному середовищі.
5) Якщо набір даних зашифрований, чи весь пул зашифрований?
Шифрування ZFS на рівні набору даних. У пулі можуть бути як зашифровані, так і незашифровані набори. Ваш аудит має перевіряти ієрархію наборів, а не лише припускати «пул зашифрований».
6) Чи можу я реплікувати зашифровані набори на сайт бекапу і зберегти їх зашифрованими end-to-end?
Так, з raw send (наприклад, zfs send -w). Але тоді ви маєте забезпечити, щоб сайт бекапу мав незалежний, протестований спосіб розблокування — або навмисно тримати його заблокованим і прийняти інші методи перевірки.
7) Чому система завантажилась, але сервіси впали, хоч пул імпортувався нормально?
Поширено: пул імпортовано, але ключі не завантажені, тож зашифровані набори не змонтувались. Перевірте zfs list -o name,keystatus,mounted і системні логи на предмет збоїв zfs-load-key.
8) Чи безпечно зберігати файли ключів на диску ОС?
Залежить від вашої моделі загроз. Це зручно операційно і захищає від вкрадених дисків даних, але не захищає від нападника з root на хості. Якщо вам потрібні сильніші гарантії — використовуйте отримання ключів поза хостом і жорсткіший контроль доступу.
9) Як довести аудиторам (і собі), що відновлення працює?
Проводячи drill import/unlock/mount на чистій системі, використовуючи тільки задокументовані процедури і ескроувані секрети. Збережіть вивід zfs get і кроки, які ви виконали. Повторюйте на регулярній основі.
Висновок: нудне краще за героїчне
Шифрування ZFS — хороша інженерія. Але переможний хід — не просто ввімкнути його, а оперувати ним. Ваш майбутній я не хоче хитромудрої конфігурації; він хоче конфігурацію, яка переживе перезавантаження, відновлення, зміну персоналу і незручний момент, коли ваша «безпечна» система недоступна, бо ключ зберігався десь… «безпечному».
Якщо візьмете лише одну звичку з цього: проганяйте drill export/import + load-key до того, як він вам знадобиться. День катастрофи не переймається тим, що дизайн виглядав чисто на діаграмі. Йому важливо, чи може людина на виклику розблокувати дані без здогадок.