Добавить файлы credentials и config на целевую машину
As announced in Rails 5.2.0 release candidate, Rails 5.2 will go out with a brand new credentials API that will eventually replace the current config/secrets.yml and config/secrets.yml.enc .
The intention behind this change is mainly to remove some of the confusion introduced by the combinations of config/secrets.yml , config/secrets.yml.enc and SECRET_BASE_KEY used in earlier versions of Rails, and attempt to unify everything using a more straightforward approach.
From now on, Rails 5.2 will only intend to use these two files instead:
- config/credentials.yml.enc
- config/master.key
When you upgrade Rails to v5.2, the file where you are going to store all your private credentials is config/credentials.yml.enc .
As it’s extension suggests, this file is going to be encrypted - so you won’t be able to read what’s inside of it - unless you have the proper master key to decrypt it. This is why it IS safe to version this file into your source control tool.
The second file, config/master.key , is the file where your RAILS_MASTER_KEY will be placed.
The RAILS_MASTER_KEY is the key that Rails will use to decrypt your config/credentials.yml.enc . It is NOT a good idea to version config/master.key file into your source control tool. You need to keep it as a secret, so make sure to list it in your .gitignore file if you’re using git.
Since it’s encrypted, Rails 5.2 comes with a way to edit the config/credentials.yml.enc file. You can do that by running the following command:
This will open up a vim editor with the decrypted version of the file (you can use others editors too, not necessarily vim). When you save it, it will encrypt it again using your master key.
You’ll see that the decrypted version of the file looks like any other normal .yml file.
By the time you run the credentials:edit command, If config/master.key and config/credentials.yml.enc don’t exist, Rails will take care of creating them on your behalf.
Let’s assume that the unencrypted version of your config/credentials.yml.enc file looks like this:
Then, you should be able to access the configuration programmatically like this:
The Rails team is proposing to remove the environment scopes inside config/credentials.yml.enc .
This new file is a flat format, not divided by environments, like secrets.yml has been. Most of the time, these credentials are only relevant in production, and if someone does need to have some keys duplicated for different environments, it can be done by hand. [DHH]
Nevertheless, you can always edit config/credentials.yml.enc and add namespaces for your secrets under development, test or production like the ones you would have in the old config/secrets.yml . You can structure your config/credentials.yml.enc like this:
Then, simply add the environment namespace when you access the configs:
When you move your code to a server, you need to make sure that your config/credentials.yml.enc file can be decrypted. That means that somehow you’ll need to provide Rails with your master key, given that it is not checked into version control.
There are two ways of doing that:
- Option 1: Place the config/master.key file in the server. You’ll normally want to symlink this file to a shared folder in the server filesystem. Again, do not version your config/master.key file.
- Option 2: create a RAILS_MASTER_KEY ENV variable. Rails will detect it and use it as your master key, e.g. in heroku: heroku config:set RAILS_MASTER_KEY= .
You should be able to use any of those indistinctly.
Keep in mind that the config/secrets.yml and config/secrets.yml.enc will continue to work and will still be compatible with Rails 5.2
Note: We will just keep Rails.secrets and friends around. The Rails.application.credentials setup will be a new, concurrent approach. All new apps would use it, but we wouldn’t need to screw existing apps. [DHH]
That won’t be forever though, so it’s not a bad idea to think about upgrading soon.
If you are upgrading your app, and not starting from a brand new Rails 5.2 app, make sure to add the following configuration to your config/environments/production.rb file:
This will tell Rails to ensure that a master key has been made available from either ENV['RAILS_MASTER_KEY'] or in config/master.key .
In general, I understand what the motivation behind this change is and I support it. If the old approach was confusing for a lot of people I believe it’s a good thing that the Rails team tries to improve it. Hopefully people will adopt it and it will become the standard for everyone.
If you want to read more about this, you can take a look at DHH’s Pull Request for the initial description and implementation of the change.
Сredentials в версии Ruby on Rails 5.2.0 — новый золотой стандарт. Старые добрые, но небезопасные файлы .env уступают дорогу. В этой статье вы узнаете:
- зачем и как перейти от secrets к credentials,
- как использовать API-ключи в Ruby, YML и js.erb,
- как раз и навсегда предоставить ключ каждому из команды.
Service-Now
Первый объект массива и есть нужный нам hostname.
Если машина готова, то можно изменить статус машины в Service-Now, для этого скрипт UpdateCI.ps1:
Для получения таблицы и записей используются REST API GET запросы, для изменения записи PUT/POST запросы, в теле которого поля которые необходимо изменить.
Мы создали удобный инструмент с графическим инструментом подобный Azure Portal, который позволяет управлять on-premises инфраструктурой максимально удобно нам и нашему заказчику.
P.S. 24.12.2018. Кажется это всё устарело? Пора использовать Azure DevOps. В следующей статье я расскажу как всё это сделать с помощью пайплайнов Azure DevOps
Начиная с версии 5.2 в Rails перешли с секретов ( secrets.yml ) на полномочия ( credentials.yml ).
Это менеджер ключей и паролей (да и вообще любых строк), хранящий всё в зашифрованном виде. Разберём как перевести имеющиеся секреты под новые требования на примере secret_key_base .
Установка SQL Server
В JSON- файле описаны требования по MS SQL Server, для установки и настройки SQL Server мы также используем DSC. Вот как выглядит конфигурация:
Где $MSSQL определен:
$MSSQL.InstanceName – всё это указано в нашем Json файле. Применение данной конфигурации выполнит установку MS SQL Server cо всеми обновлениями в папке Updates и перезагрузит сервер, если это необходимо.
Как это работает?
Запуск bin/rails credentials:edit в rails создает два файла, которые требуются в папке config:
- credentials.yml.enc хранит все ваши API-ключи. Если вам вдруг любопытно, расширение .enc означает шифрование.
- master.key — это ключ, который используется для расшифровки encrypted.file (1.) Убедитесь, что вы добавили master.key в файл .gitignore.yml .
2. Нужно задействовать.
1. В config/environments, как минимум в production.rb :
config.secret_key_base = Rails.application.credentials[Rails.env.to_sym][:secret_key_base]
Также включить требование ключа:
2. В иных местах, где использовался этот ключ, заменить на такую же конструкцию:
YourApp::Application.config.db_token = Rails.application.credentials[Rails.env.to_sym][:secret_key_base]
Но в этом примере правильнее всё-таки задействовать config:
YourApp::Application.config.db_token = Rails.application.config.secret_key_base
Переход на credentials
Откройте файл credentials, выполнив в терминале следующее:
EDITOR='code --wait' bin/rails credentials:edit
В зависимости от используемого вами редактора, замените code (VS Code). Например:
vim or vi = Vim
atom = Atom
subl or stt = Sublime
Файл credentials автоматически открывается в редакторе и ждет, когда вы его обновите и снова закроете. Перенесите ключи ENV, которые вы используете в файле .env, в файл credentials.yml.
Замените старый файл .ENV :
Примечание: Ключ Cloudinary API разделен на несколько частей, согласно документации.
Все готово! Для вывода на экран, credentials можно запустить в терминале.
Запустите bin/rails credentials:show .
Пришло время прощаться с нашим старым другом — файлом .ENV. Удалим его.
Как использовать Credentials в различных форматах, таких как Ruby, YML и JavaScript
для Cloudinary необходим дополнительный файл config/cloudinary.yml
1. Нужно создать
Можно и на локальном сервере, затем скопировать на релизный. Консольная команда, вызывающая редактирование credentials:
EDITOR=vim rails credentials:edit
Если через бандлы, то:
EDITOR=vim bundle exec rails credentials:edit
Редактор можно выбрать любой, даже с GUI. В него ввести практически то же самое, что было в secrets.yml , формат соответственно YAML.
development:
secret_key_base: 461989807a53d2de8dacd1c73585713c37fddfe.
staging:
secret_key_base: fd9065a781d4e3e96f17790c7d25ca45dcb1d8d.
production:
secret_key_base: 914edbe043002157751b338ef7d571b949654cc.
Если в secrets.yml использовался , то нужно его заменить на сам ключ.
После первого сохранения будут созданы master.key (в нём хранится ключ шифрования, при повторных сохранениях будет использоваться уже он) и credentials.yml.enc (это зашифрованные credentials).
Adding config/master.key to store the encryption key: 5ca595fdd3a6a774f0ae6b52c3fa29fc
Save this in a password manager your team can access.
If you lose the key, no one, including you, can access anything encrypted with it.
create config/master.key
File encrypted and saved.
Как поделиться ключами с командой
Поделитесь ключом в master.key с другими разработчиками, чтобы разрешить дешифрование.
Каждый член команды создает файл master.key локально в папке config и передает его в общий ключ.
Немного о хранении других ключей
Хранить можно любые значения, например:
development:
stripe:
secret_key: sk_test_asdfgh123
token: rk_test_Hkkjbh43
production:
stripe:
secret_key: sk_live_qwerty456
token: rk_live_dsIIjhh5
github:
app_id: 1111
app_secret: dfgdrghj6f
Обращение к ним:
Rails.application.credentials[Rails.env.to_sym][:stripe][:secret_key]
Often when working on a Rails app, you will have to handle vulnerable data.
Most often these are API keys to services that you integrate.
Most common examples:
- Github, Google, Twitter, Facebook oAuth
- AWS S3
- Stripe, Braintree etc
- Sendgrid, Mailchimp etc
Here you can see a client_id and client_secret provided by Github, so that you can add “Log in with Github” functionality:
To use these keys, you could directly place them in your devise.rb file like
However this approach creates a security threat.
For example, if your repository is ever open sourced or shared with third parties, anybody can misuse your API keys.
That can lead to your account:
- being banned (overuse quota with too many requests)
- charged (with your API keys anybody can upload too much data to your S3 account)
- you can experience a data leak (all your application attachements from S3 can be leaked)
That’s why should use credentials to encrypt sensitive data.
An encrypted line in devise.rb would look like:
So how do you make it work?
When you create a Rails 6 app, under app/config you have a file named credentials.yml.enc :
If you open the credentials.yml.enc file, it will usually look like this:
It is encrypted and safe to share in a public repository.
To decrypt the credentials.yml file, the master.key file is used:
NEVER SHARE THE MASTER KEY WITH THE PUBLIC.
IF YOU LOSE THE MASTER KEY, YOU WILL NOT BE ABLE TO DECRYPT YOUR CREDENTIALS
By default, master.key is not included into your git commits.
To decrypt and view or edit your credentials.yml , you can run rails credentials:edit or EDITOR=vim rails credentials:edit .
When decripted, the credentials.yml file would typically looks somewhat like this:
To retrieve any data from credentials.yml in your rails app or in the console, you can run something like
Editing the file in VIM inside a terminal can a feel tricky and unnatural.
To edit the file, press i . You will see INSERT appear on the bottom of the file, prompting that you are currently able to edit the file:
When you’re done, press ESC . next press :wq + ENTER to exit with saving.
Почему стоит использовать сredentials вместо secrets?
В цикле разработки, по мере развития в проект интегрируется всё больше различных сервисов. Для каждого внешнего сервиса существует собственный API-ключ. Обычно проходит совсем немного времени до момента, когда коллеги начнут охоту за за последним API-ключом. Это очень раздражает!
Или, просто представьте, API-ключ обновляется. Каждый разработчик в команде отдельно должен обновить ключ в локальных файлах dotenv. Кажется, всё это не соответствует концепции автоматизации и идеям программирования, верно?
Забудьте об обмене API-ключами в чатах в Slack или по электронной почте. Больше не придется нарушать политику безопасности.
Credentials в Rails решают эту проблему просто и эффективно: загрузка ключей на Github.
Загрузка на Github? Да, загрузка на Github! Небольшое примечание: API-ключи полностью зашифрованы.
Большое преимущество такого подхода в том, что существует один единственный ключ, которым можно поделиться с командой. И он никогда не меняется!
Новые API-ключи, добавленные вашими коллегами как credentials, подтягиваются из Github каждый раз, когда вы вытаскиваете последнюю версию ветки main (ранее носила название «ветка master»).
Ключ можно найти в папке config/master.key.
Создание виртуальной машины
Найдем соответствующий SLR-кластер:
И достаточно памяти:
Берем наш темплейт
И создаем новую виртуальную машину
Важно подключить сетевой интерфейс к подсети с включенным DHCP.
Запускаем виртуальную машину
И сохраняем описание машины, чтобы потом можно было определить машину на уровне VMWare.
Машина запустилась и теперь мы можем узнать полученный MAC-адрес:
Сохраним это значение в наш JSON-файл
Здесь самое время сделать commit в наш Git, что машина создана и имеет свой уникальный MAC.
Машина начинает инициализироваться (после sysprep), настраивать оборудование и начальную конфигурацию.
Давайте дождемся, когда будет доступна наша машина по WinRM c скриптом EstablishConnection.ps1.
Сначала узнаем какой IP машина получила от DHCP:
А теперь дождемся, когда машина будет доступна по WinRM:
Машина готова к управлению.
Почему стоит использовать сredentials вместо secrets?
В цикле разработки, по мере развития в проект интегрируется всё больше различных сервисов. Для каждого внешнего сервиса существует собственный API-ключ. Обычно проходит совсем немного времени до момента, когда коллеги начнут охоту за за последним API-ключом. Это очень раздражает!
Или, просто представьте, API-ключ обновляется. Каждый разработчик в команде отдельно должен обновить ключ в локальных файлах dotenv. Кажется, всё это не соответствует концепции автоматизации и идеям программирования, верно?
Забудьте об обмене API-ключами в чатах в Slack или по электронной почте. Больше не придется нарушать политику безопасности.
Credentials в Rails решают эту проблему просто и эффективно: загрузка ключей на Github.
Загрузка на Github? Да, загрузка на Github! Небольшое примечание: API-ключи полностью зашифрованы.
Большое преимущество такого подхода в том, что существует один единственный ключ, которым можно поделиться с командой. И он никогда не меняется!
Новые API-ключи, добавленные вашими коллегами как credentials, подтягиваются из Github каждый раз, когда вы вытаскиваете последнюю версию ветки main (ранее носила название «ветка master»).
Ключ можно найти в папке config/master.key.
Вывод
Программирование становится всё более увлекательным занятием без суеты и необходимости искать правильные API-ключи. Благодаря credentials, мы можем обновить приложение с учетом рекомендаций по информационной безопасности. Поделитесь master key один раз и избавьтесь от утомительного копирования.
Создание новой виртуальной машины — это рутина, отнимающая много времени. И чем больше инфраструктура и организация, тем больше процедур, связанных с этим процессом. Мы автоматизировали это процесс с помощью PowerShell.
Программисты не любят делать двойную работу, сисадмины тоже.
Ниже пример автоматизации одного из наших заказчиков.
Мы хотели сделать так, чтобы любой инженер или project-менеджер смог создать новую виртуальную машину с минимальными усилиями и за минимальный срок. У нашего заказчика есть ITSM-система, в данном примере это ServiceNow, мы создали соответствующую web-форму в сервисном каталоге. Для «заказа» новой машины менеджеру необходимо заполнить поля и подтвердить «заказ», после этого запускается цепочка процессов, и на выходе получаем готовую к использованию машину.
Итак, давайте рассмотрим, что нужно определить менеджеру, чтобы создать новую виртуальную машину:
VM Description: описание виртуальной машины
Тут нужны некоторые пояснения. В нашем решении активно используется PowerShell 5.1, поэтому пока Windows-only, в будущем мы постараемся добавить поддержку Unix-машин и перейдем на PowerShell Core.
OS, операционная система. Никаких особых препятствий использовать Windows 2008 (R2) нет, но мы используем 2012R2 или 2016.
VM Size, размер виртуальной машины. У каждого это может быть определено по-своему, в данном примере Small 1CPU-4Gb Ram, Medium 2CPU-8Gb, Large 4-16.
VM Storage, Disk 0 (C:\) имеет фиксированный размер, который вы не можете изменить, доступен только селектор Fast/Slow storage. «Fast» — это может быть Storage Tier с SSD, а «Slow» — это storage на «обычных» HDD (конечно — SAN). Disk1 (Disk2 и далее) также имеют селектор выбора типа Storage, а также поля для ввода желаемого размера в гигабайтах, Letter для раздела и размер кластера (что важно для SQL Server).
Trust, определяем, что машина должна быть Domain-joined или нет, с доступом из Public Network или нет.
Type, тип машины. Почти каждую машину можно определить, как front-end или back-end приложения или же other во всех оставшихся случаях. На основе выбранного типа мы сможем в дальнейшем определить наиболее подходящую подсеть для машины.
Environment, в инфраструктуре заказчика есть два дата центра: Primary (Production) и Secondary (Dev/test), DC связаны между собой быстром каналом связи и обеспечивают отказоустойчивость. По договоренности все виртуальные машины в Primary DC имеют IP-адрес, начинающийся на 10.230, а в Secondary DC — на 10.231.
(SLA) Service Level Agreement, этот параметр влияет на качество обслуживания данной машины.
Приложения. Мы добавили возможность установки и настройки SQL Server. Необходимо выбрать издание, instance name и collation. Также возможно настроить и Web Server роль и многое другое.
Теперь нам нужно определить, как хранить выбранные значения. Мы решили, что наиболее удобный формат — JSON-файл. Как я говорил ранее, в среде заказчика используется ITSM ServiceNow; менеджер, после того как выбрал все необходимы значения, нажимает кнопку «order» и после этого ServiceNow передает все параметры нашему PowerShell-скрипту (на back-end ServiceNow), который и создаст JSON-файл. Выглядит это примерно так:
В теле CreateConfiguration .ps1 скрипта:
В конце экспортируем наш объект в JSON-файл:
Примерный образец конфигурации:
Вы могли заметить, что в веб-форме отсутствовало имя виртуальной машины и IP-адрес. Мы получаем эти значения автоматически следующим образом:
Имя машины, в ITSM ServiceNow есть специальный раздел: CMDB (Configuration Management Data Base), в этой базе хранятся все записи о существующих виртуальных машинах, их статус, команда поддержки и прочее. Мы создали порядка 200 резервных записей со статусом Allocated. Чтобы получить имя для виртуальной машины мы делаем REST-запрос к CMDB и получаем первую «свободную» запись и меняем её статус с Allocated на Pending install.
IP адрес и VLAN, мы развернули IPAM в нашей сети — это встроенная feature в Windows Server 2016, которая позволяет управлять IP-адресами в вашей сети. Вовсе не обязательно использовать все возможности IPAM (DHCP, DNS, AD), а использовать её только как базу данных IP-адресов с потенциальным расширением функционала. Скрипт, который создает JSON файл, делает запрос к IPAM на предмет первого свободного IP адреса в подсети. А подсеть VLAN (х/24 подсеть) определяется на основе выбранных значений SLA, Environment, Trust и Type.
Файл-конфигурация готов, все поля на месте, можно создавать машину. Встает вопрос «как хранить учетные данные для всех наших скриптов?». Мы используем пакет CredentialManager. Этот пакет работает со встроенным Windows Credential Manager API для хранения паролей. Пример создания пароля:
Пароль будет доступен для чтения в пределах данной машины и учетной записи.
У нас есть сервер, на котором хранятся все конфигурации c GIT, теперь мы можем надежно отслеживать все изменения в конфигурациях: кто, что, где и когда.
На этом сервере настроен scheduled task: проверять папку c конфигурациями и писать в Windows Event Log обо всех изменениях.
Через 15 минут scheduled task напишет в Windows EventLog, что обнаружен новый файл-конфигурация.
Пришло время проверить эту конфигурацию. В первую очередь нам нужно убедиться, что файл имеет корректное форматирование:
Если все хорошо, пора приступать к созданию машины и запусить BuildVM.ps1 скрипт.
В BuildVM.ps1 мы проверяем, что файл-конфигурация имеет описание всех характеристик виртуальной машины: size, env, sla, type, storage, ram, network.
Проверяем, есть ли машина с таким же именем в инфраструктуре
Убедимся, что машина также не доступна по WinRM
Если в $VM и $ping пусто, то можно создавать новую машину. (Мы обрабатываем ситуации, когда машина уже создана в ESXi вручную или же эта машина в другом дата-центре.)
Пару слов о машине. Это подготовленный образ виртуальный машины, который был финализирован sysprep и сконвертирован в template в нашем vSphere. В образе сохранен локальный администратор с известным нам паролем, эта учетная запись «не слетает» после sysprep, что позволит нам получить доступ к каждой машине из этого темплейта, а позже мы сможем заменить этот пароль в целях безопасности.
3. Использовать на релизе.
Ключ можно хранить в двух местах: config/master.key и переменная окружения RAILS_MASTER_KEY . Отсюда вариативность использования:
3.1 RAILS_MASTER_KEY
Вариант простой, но не безопасный - любой процесс на сервере имеет к ним доступ. Также, если на одном сервере больше одного проекта, им придётся использовать одну переменную. Так что рекомендую второй способ.
3.2 master.key
На примере, когда на проекте используются репозиторий и деплои.
Файл master.key не рекомендуется хранить в открытых репозиториях. Если Ваш репозиторий закрыт от ненужных глаз, то данной частью можно пренебречь, иначе не забыть добавить его в .gitignore . Файл credentials.yml.enc зашифрован и его лучше хранить в репозитории.
Одним из вариантов использования master.key на сервере является хранение его во внешней папке с ограниченным доступом и при деплое делать ссылку на него в папке config. Допустим, есть папка shared, находящаяся вне проекта, доступная только необходимым пользователям, и на которую есть ссылка shared в папке проекта. Туда и можно скинуть данный файл.
Создание ссылки на файл на примере Capistrano. Сам таск:
Выполнение его нужно добавить после обновления кода, но перед выполнением любых подключений к БД, например миграций:
after "deploy:finalize_update", "custom:create_symlinks", "deploy:migrate"
С credentials.yml.enc всё проще - он добавится вместе с остальным кодом. После такого деплоя релизный проект сможет читать зашифрованные в файле ключи. Если что-то пошло не так, получите ошибку:
ArgumentError: Missing `secret_key_base` for 'production' environment, set this string with `rails credentials:edit`
Если это первое использование на релизе, то рельсы нужно пнуть с помощью rails credentials:edit :
EDITOR=vim rails credentials:edit
или через bundle :
EDITOR=vim bundle exec rails credentials:edit
"/tmp/47452.credentials.yml" 14L, 652C written
File encrypted and saved.
Desired State Configuration
Для настройки желаемой конфигурации мы используем часть PowerShell — DSC (Desired State Configuration). В сети есть настроенный DSC Pull Server: dscpull.testdomain.eu.
Ниже конфигурация нашего DSC Pull Server. Хорошая статья по настройке DSC Pull.
На всех клиентах pull сервера должен быть установлен PowerShell 5.1
Если установлен не PowerShell 5.1:
установить PowerShell 5.1:
В нашей сети также развернут PKI-сервер. Это условие для безопасного шифрование учетных данных сохранённых в DSC mof файлах (Mof файлы — это «язык» на котором общаются Pull Server и его клиенты). Когда клиент пытается зарегистрироваться на Pull Server, необходимо указать Thumbprint сертификата и в дальнейшем Pull Server будет использовать этот сертификат для шифрования паролей. Ниже мы рассмотрим, как это работает.
Импортируем Root CA нашей новой машине:
Для дальнейшей работы нам нужна пара RSA-ключей. Сгенерируем самоподписанный сертификат и временно будем работать с ним.
Теперь мы можем зарегистрироваться на Pull Server:
Отправим первую конфигурацию нашей машине
Сервер автоматически переименуется и перезагрузится. Теперь мы можем выполнить Join Domain.
Вот как выглядит наш mof-файл:
DSC зашифровал учетные данные от сервисной учетки с правами Domain Admin: testdomain.eu\\service_DomainJoin_001 самоподписанным сертификатом. DSC Client своим Private Key расшифровывает учетные данные и применяет все модули конфигурации c указанными доменным учетными данными. В данном случае выполняет Domain Join в указанную organization unit.
Этот модуль добавляет dscstaging в локальные администраторы для дальнейшей настройки.
После перезагрузки, мы сможем зайти на машину с доменными учетными данными.
Ждем, когда сервер получит сертификат от нашего PKI (у нас настроен auto enrollment) и в дальнейшем будем работать с сертификатом, выпущенным нашим PKI.
Теперь снова зарегистрируемся на Pull Server с обновленным thumbprint.
Всё, машина domain-joined, и мы можем использовать её так, как нам удобно.
Читайте также: