Антон Рябов bio photo

Антон Рябов

Не люблю бриться и у меня умный взгляд.

Email Twitter Telegram Github PGP RSS

Зашифрованные секретные данные в Rails 5.1

От переводчика: Оригинал статьи

Обзор

В Rails давно уже есть функционал для работы с секретными данными (паролями, токенами и т.д.), но в релизе 5.1 его значительно улучшили добавив шифрование. Из данной статьи вы узнаете как использовать новые возможности и что нужно изменить в текущем Rails приложении.

Секретные данные без шифрования

Как создавать новое Rails приложение


В любом Rails приложении, рано или поздно нужно работать с секретными данными. Как минимум вам нужен ключ - secret key base, чаще всего в приложениях нужны токены для сторонних API. Хорошим тоном для работы с секретными данными в Rails будет - никогда не коммитить эти данные в репозиторий, навряд ли вы хотите чтобы их видели те у кого есть доступ в репозиторий или те кто получит к нему доступ в принципе.

Существует два способа:

Читать секретные данные из переменных окружения. Коммитить secrets.yml в репозиторий

По умолчанию cгенерированный файл secrets.yml читает secret_key_base из переменной окружения SECRET_KEY_BASE, вы можете использовать подобную тактику для добавления своих секретных данных.

production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
  my_secret_token: <%= ENV["MY_SECRET_TOKEN"] %>

Использование переменных окружения это удобный, но не самый безопасный способ работы с секретными данными. Процесс, запущенный на вашем сервере может получить доступ к переменным окружения. Библиотека для логирования используемая в Rails может передавать ваши секретные данные во внешние сервисы. Есть второй способ:

Сохранить все ваши секретные данные в secrets.yml и не коммитить его в репозиторий

В таком случае, те у кого есть доступ к вашей кодовой базе не смогут увидеть секретные данные, однако вам придется искать способ загрузить файл secrets.yml на сервера обходными путями, не через репозиторий.

Этот способ безопасный до тех пор, пока вы можете безопасно переносить secrets.yml на сервера. Например, можно использовать программы scp или sftp. Если вы достаточно продвинутый инженер, также можете использовать что-то вроде Chef Data Bags или Vault.

Шифрованные секретные данные

Итак, начиная с версии 5.1 вы можете использовать шифрование. Без ключа шифрования, вы не сможете прочитать секретные данные а увидите только беспорядочный набор символом. Такие данные уже можно спокойно коммитить в репозиторий, главное никогда не сохраняйте туда ключ шифрования. У шифрованных секретов есть плюсы по сравнению с вариантами перечисленными выше. Перед тем как расскаазть про них, давайте посмотрим как их использовать.

По умолчанию, данный функционал отключен. Чтобы начать пользоваться шифрованными секретами, нужно сгенерировать ключ. В корневой директории Rails приложения выполните команду:

bin/rails secrets:setup

Данная команда создает два файла: config/secrets.yml.key - содержит ключ, которым мы будем шифровать и дешифровать секретные данные, именно он НЕ должен быть закоммичен в репозиторий; config/secrets.yml.enc - содержит, собственно зашифрованные данные и этот файл, как раз таки можно сохранить в репозиторий. Если кто-то заполучит config/secrets.yml.enc, но у него не будет ключа, он не сможет расшифровать данные.

После создания ключа, даже если config/secrets.yml.enc не пустой, он не содержит ни одного секрета. Чтобы добавить ваши данные, запустите

bin/rails secrets:edit

Ваш текстовый редактор откроет незашифрованную версию секретных данных (которые по началу просто комментарии), похожую на то, что вы видите в secrets.yml. Если у вас не установлена переменная EDITOR, можете запустить команду таким образом:

EDITOR=vi bin/rails secrets:edit

подставив вместо vi, свой любимый редактор.

Вы можете перенести все ключи из secrets.yml и удалить сам файл в принципе. Как вариант, можете перенести только production данные и продолжить использовать secrets.yml для окружений development и test. Если секреты для production окружения у вас есть и в secrets.yml, и в secrets.yml.enc, то они будут совмещены (merged).

После сохранения файла, содержимое config/secrets.yml.enc будет зашифровано.

Чтение секретных данных

Rails приложение не будет читать секретные данные автоматически, даже если у вас есть ключ и зашифрованные данные на месте. Вам нужно добавить в config/environments/production.rb строку:

config.read_encrypted_secrets = true

После этого секреты будут доступны через Rails.application.secrets, но если вы захотите просмотреть их в консоли, нужно выполнить:

bin/rails runner "puts Rails::Secrets.read"

Преимущества использования шифрованных секретных данных

  1. Во-первых, и это очевидно - шифрование, никто не сможет прочитать ваши данные не имея ключа
  2. Секретные данные будут храниться в репозитории и можно будет проследить кем и что было изменено
  3. Новые секретные данные попадают на сервера вместе с кодом, например если вы добавили в код обращение к API, секретный токен также попадет на сервера и функционал сразу заработает, тогда как ранее, вам необходимо было убедиться что переменная окружения установлена, перед тем как заливать код.
  4. Все секретные данные в одном месте, вместо того чтобы поддерживать несколько переменных окружения у вас все в одном файле.

Управление ключом

В то время как шифрованные секреты имеют преимущество перед незашифрованными секретами, у нас все еще есть задача, найти способ положить ключ на свое место. Наши варианты похожи на работу с секретными данными до Rails 5.1, так как нельзя просто сохранить ключ в репозитории.

Загрузка secrets.yml.key безопасным способом

Вы можете использовать scp или sftp для загрузки файла. В Engine Yard, например, это нужно сделать только один раз, во время масштабирования, новые сервера будут автоматически получать копию secrets.yml.key.

Загрузите ключ в общую папку, “общую” здесь означает, то, что она доступна между релизами, а не всем пользователям. При каждом релизе, вы создаете символическую ссылку для config/secrets.yml.key указывающую на /path/to/shared/config/secrets.yml.key. Это можно сделать через deploy хуки в Engine Yard или в Capistrano.

Деплоим Rails + Webpack приложение на Heroku

Если вам нужно предоставить копию ключа разработчику, не стоит отправлять его по электронной почте, а воспользуйтесь менеджером паролей, они (более-менее) безопасные.

Сохраните ключ в переменной окружения - RAILS_MASTER_KEY

В тех случаях, когда вы не можете загрузить сам файл, это единственный оставшийся вариант. Даже если это удобно, помните о рисках безопасности, упомянутых выше, поэтому старайтесь найти способ загрузить файл.

Заметки про Secret Key Base

Ключ, используемый для шифрования секретов отличается от secret key base, он используется для шифрования и дешифрования всех секретных данных и не заменяет secret key base. secret key base - это, по умолчанию, единственный секретный ключ, необходимый для работы Rails приложения. Если вы захотите его перегенирировать, запустите:

bin/rails secret

Эта команда отличается от команды, которую мы использовали для шифрованных секретных данных, которые используют ключ secrets для своих команд.

Заключение

Шифрованные секретные данные имеют несколько преимуществ перед хранением доступов в открытом тексте или переменных окружения. Rails, как и в старые добрые времена, предлагает нам простой воркфлоу, попробуйте новый функционал и дайте нам знать в комментариях что вы о нем думаете. Спасибо всем контрибьютерам Rails, которые сделали это возможным.

От переводчика: Я не согласен с автором статьи в плане копирования файлов и “небезопасности” переменных окружения, но данная заметка знакомит нас с хорошим новым функционалом, который стоит использовать в разработке каждого вашего приложения на Rails, поэтому имеет место быть

#RubyOnRails #Security