Як зробити чутливу інформацію секретною
Дата оновлення перекладу 2024-05-09
Як зробити чутливу інформацію секретною
Змінні середовища - це найкращий спосіб зберігати конфігурацію, яка залежить від того, де виконується додаток - наприклад, деякий API-ключ, який може бути встановлений в одному значенні при локальній розробці, і в іншому значенні при виробництві.
Коли ці значення чутливі і мають зберігатися в таємниці, ви можете безпечно зберігати їх, використовуючи систему управління секретами Symfony, яку іноді називають "сейфом".
Note
Система Секретів вимагає PHP-розширення Sodium .
Генерування зашифрованих ключів
Для того, щоб зашифрувати та розшифрувати секрети, Symfony необхідні криптографічні ключі. Для того, щоб згенерувати пару ключів, виконайте:
1
$ php bin/console secrets:generate-keys
Це згенерує пару асиметричних криптографічних ключів. Кожне
середовище має власний набір ключів.
Припускаючи, що ви пишете код локально в середовищі dev
, це створить:
config/secrets/dev/dev.encrypt.public.php
- Використовується для шифрування/додавання секретів у сейф. Може бути відправлено безпечно.
config/secrets/dev/dev.decrypt.private.php
-
Використовується для дешифрування/читання ключів з сейфу. Ключ розшифровки
dev
може бути відправлений (припускаючи, що у сейфі dev не зберігаються надчустливі секрети), але ключ розшифровкиprod
не потрібно відправляти ніколи.
Ви можете згенерувати пару криптографічних ключів для середовища prod
,
виконавши наступне:
1
$ APP_RUNTIME_ENV=prod php bin/console secrets:generate-keys
Це згенерує config/secrets/prod/prod.encrypt.public.php
і
config/secrets/prod/prod.decrypt.private.php
.
Caution
Файл prod.decrypt.private.php
надчутливий. Ваша команда розробників і навіть сервіси
безперервної інтеграції не потребують цього ключа. Якщо ключ розшифрорвки було викрито
(наприклад, від вас пішов колишній співробітник), вам потрібно подумати про створення
нового, шляхом виконання secrets:generate-keys --rotate
.
Створення або оновлення секретів
Припустимо, що ви хочете зберігати свій пароль бази даних як секрет. Використовуючи
команду secrets:set
, ви повинні додати цей секрет у сейфи dev
і prod
:
1 2 3 4 5 6 7
# введеня приховане під час того, як ви друкуєте, з міркувань безпеки
# встановіть ваше значення розробки за замовчуванням (може бути перевизначене локально)
$ php bin/console secrets:set DATABASE_PASSWORD
# встановіть ваше значення виробництва
$ php bin/console secrets:set DATABASE_PASSWORD --env=prod
Це створить новий файл для секрету в config/secrets/dev
і ще один у
config/secrets/prod
. Ви також можете встановити секрет декількома іншими
способами:
1 2 3 4 5 6 7 8
# надайте файл для зчитування секрету
$ php bin/console secrets:set DATABASE_PASSWORD ~/Download/password.json
# або зміст, переданий STDIN
$ echo -n "$DB_PASS" | php bin/console secrets:set DATABASE_PASSWORD -
# або дозвольте Symfony згенерувати рандомне значення за вас
$ php bin/console secrets:set REMEMBER_ME --random
Note
Для переіменування секретів команди не існує, так що вам потрібно буде створити новий секрет та видалити старий.
Посилання на секрети у файлах конфігурації
На секретні значення можна посилатися так само, як і на змінні середовища . Будьте обережні, щоб випадково не визначити і секретне значення, і змінну середовища з однаковим іменемм: змінні середовища мають перевагу перед секретами.
Якщо ви зберегли секрет у DATABASE_PASSWORD
, ви можете послатися на нього так:
1 2 3 4 5 6
# config/packages/doctrine.yaml
doctrine:
dbal:
password: '%env(DATABASE_PASSWORD)%'
# ...
# ...
Реальне значення не буде виконано під час прогону: компіляція контейнера та розігрів кешу не потребують ключа розшифровки.
Список існуючих секретів
Всі мають право отримати список імен секретів за допомогою команди
secrets:list
. Якщо у вас є ключ розшифровки, ви також можете побачити
значення секретів, передавши опцію --reveal
:
1 2 3 4 5 6 7
$ php bin/console secrets:list --reveal
------------------- ------------ --------------------
Імʼя Значення Локальне значення
------------------- ------------ --------------------
DATABASE_PASSWORD "my secret"
------------------- ------------ --------------------
Розкриття існуючих секретів
Якщо у вас є ключ розшифровки, команда secrets:reveal
дозволяє
вам розкрити значення одного секрету.
1 2 3
$ php bin/console secrets:reveal DATABASE_PASSWORD
my secret
7.1
Команда secrets:reveal
була представлена в Symfony 7.1.
Видалення секретів
Symfony надає зручну команду для видалення секрету:
1
$ php bin/console secrets:remove DATABASE_PASSWORD
Локальні секрети: локальне перевизначення секретів
Секрети середовища dev
повинні містити гарні значення за замовчуванням для розробки.
Але іноді рорзробнику все одно потрібно перевизначити секретне значення локально під
час розробки.
Більшість команд secrets
- включно з secrets:set
- мають опцію --local
, яка
зберагіє "секрет" у файлі .env.{env}.local
в якості стандартної змінної середовища.
Щоб перевизначити секрет DATABASE_PASSWORD
локально, виконайте:
1
$ php bin/console secrets:set DATABASE_PASSWORD --local
Якщо ви введете root
, то тепер ви побачите у вашому файлі .env.dev.local
наступне:
1
DATABASE_PASSWORD=root
Це перевизначить секрет DATABASE_PASSWORD
, так як змінні середовища завжди головують
над секретами.
Список секретів тепер також міститиме локальну змінну:
1 2 3 4 5 6
$ php bin/console secrets:list --reveal
------------------- ------------ --------------------
Імʼя Значення Локальне значення
------------------- ------------ --------------------
DATABASE_PASSWORD "dev value" "root"
------------------- ------------ --------------------
Symfony також надає команду secrets:decrypt-to-local
, яка розшифровує всі секрети
і зберігає їх у локальному сейфі, та команду secrets:encrypt-from-local
для
шифрування всіх локальних секретів у сейф.
Секрети у середовищі тестування
Якщо ви додасте секрет у середовища dev
і prod
, його не буде у середовищі
test
. Ви можете створити "сейф" для середовища test
і визначити секрети
у ньому. Але легше буде встановити тестові значення через файл .env.test
:
1 2
# .env.test
DATABASE_PASSWORD="testing"
Запуск секретів у виробництво
У звʼязку з тим, що ключі розшифровки ніколи не повинні відправлятися, вам знадобиться вручну зберігати цей файл десь і запускати його. Є 2 способи зробити це:
- Завантаження файлу:
Перша опція - скопіювати ключ розшифровки виробництваconfig/secrets/prod/prod.decrypt.private.php
на ваш сервер.
- Використання змінної середовища
Другий спосіб - встановити змінну середовища SYMFONY_DECRYPTION_SECRET
у зашифроване
значення base64 ключа розшифровки виробництва. Модним способом отримання значення
ключа є:
1 2 3
# ця команда лише отримує значення ключа; ви повинні також встановити змінну середовища
# у вашій системі з цим значенням (наприклад, `export SYMFONY_DECRYPTION_SECRET=...`)
$ php -r 'echo base64_encode(require "config/secrets/prod/prod.decrypt.private.php");'
Щоб покращити продуктивність (тобто, уникнути розшифровки секретів під час прогону), ви можете розшифрувати ваші секрети під час запуску у "локальному" сейфі:
1
$ APP_RUNTIME_ENV=prod php bin/console secrets:decrypt-to-local --force
Це запише всі розшифровані секрети у файл .env.prod.local
. Післе того, як
це буде зроблено, ключ розшифровки не повинен залишатися на сервері(ах).
Ротація секретів
Команда secrets:generate-keys
надає опцію --rotate
для регенерування криптографічних
ключів Symfony розшифрує існуючі секрети за допомогою старого ключа, згенерує нові
криптографічні ключі та повторно зашифрує секрети з новим ключем. Для того, щоб розшифрувати
попередні секрети, розробнику буде потрібен ключ розшифровки.
Конфігурація
Система секретів включена за замовчуванням і деякі аспекти її поведінки можна сконфігурувати:
1 2 3 4 5 6
# config/packages/framework.yaml
framework:
secrets:
#vault_directory: '%kernel.project_dir%/config/secrets/%kernel.environment%'
#local_dotenv_file: '%kernel.project_dir%/.env.%kernel.environment%.local'
#decryption_env_var: 'base64:default::SYMFONY_DECRYPTION_SECRET'