Bitwarden в действии: Автоматизация смены ключей и паролей для AWS
В мире, где каждая учетная запись требует от нас еще одного пароля, и каждый облачный сервис, такой как AWS, зависит от надежности этих ключей, менеджеры паролей вроде Bitwarden выступают как спасители. Они не просто хранят наши ключи и пароли, но и делают их управление значительно удобнее. Однако, даже с таким мощным инструментом, как Bitwarden, мы сталкиваемся с ограничением: он не способен автоматически обновлять и менять используемые в облачных сервисах ключи и пароли. Итак, что делать, когда ручное обновление ключей и паролей становится скучной и малоэффективной задачей? В этой статье мы исследуем, как можно объединить удобство использования Bitwarden с эффективными методами автоматизации для управления учетными данными AWS. Представьте себе — больше нет монотонного ввода паролей и обновлений ключей вручную. Но для этого придется немного постараться. Что ж, начнем…
А почему, собственно, Bitwarden?
Выбирать инструмент для управления паролями и ключами AWS — это всегда непросто. Но после некоторых раздумий я остановился на Bitwarden, и вот почему он стал моим выбором:
Поддержка любых устройств: Bitwarden работает на всех платформах, которые я использую — это делает его идеальным решением для моих целей. У него есть нативные десктопные клиенты под Windows, Linux и MacOS. Есть родные мобильные приложения под iOS и Android. Есть отдельное приложение для Apple Watch. Есть command-line клиенты под любые платформы. Есть браузерные расширения для Chrome, Safari, Firefox и кучи других браузеров. И наконец есть просто веб-версия, доступная с любого устройства, где есть интернет и доступ к любому браузеру.
Простота и удобство использования: Несмотря на высокий уровень безопасности, Bitwarden остается интуитивно понятным и легким в использовании, что делает его доступным для всех. Особенно приятно наличие почти мгновенной безопасной синхронизации данных с централизованным облачным хранилищем. Так, что секрет, добавленный на одном клиенте, почти моментально становится доступен и на остальных. Для параноиков — можно не использовать родное облачное хранилище от самого сервиса Bitwarden, а использовать self-hosted установку, храня все секреты там, где хочется лично вам. Хоть на том же самом устройстве.
Двухфакторная авторизация и TOTP: Наличие поддержки двухфакторной авторизации и TOTP представляет собой важную функцию, позволяющую генерировать временные одноразовые пароли (TOTP) прямо внутри приложения. Это значительно упрощает процесс двухфакторной аутентификации, позволяя хранить и быстро использовать TOTP для различных веб-сайтов и приложений. В частности, Bitwarden можно использовать как Virtual MFA для авторизации в AWS.
Открытое API и открытый исходный код: Наличие открытого API и командного интерфейса в Bitwarden позволяет мне интегрировать данный сервис в различные сценарии и автоматизировать процессы управления паролями и ключами. Открытый исходный код облегчает аудит безопасности и позволяет легче расширять и улучшать сервис, реализуя новые возможности, в том числе альтернативные клиенты и даже сервер. Например, есть полностью переписанная на Rust серверная часть с полной поддержкой родного API и даже фич, которые в родном приложении доступны лишь для обладателей Premium-подписки.
Из недостатков, наверное, стоит отметить разве что отсутствие встроенной возможности обновлять пароли и ключи для заданных сервисов. Этот недостаток мы и попробуем исправить.
Добавляем данные IAM пользователя AWS в Bitwarden
Давайте для примера предположим, что вы используете облако AWS для ваших задач. При этом вы работаете с одним или несколькими разными аккаунтами AWS, в каждом из которых у вас есть личная учетная запись для которой нужно регулярно менять пароль. Для этого у вас должны быть настроены соответствующие права.
Для начала убедимся, что все необходимые данные для логина в AWS уже занесены в Bitwarden. При входе в консоль AWS обычно требуется ввести имя пользователя IAM и его пароль. Также важно сохранить в Bitwarden номер вашего AWS аккаунта или его псевдоним (alias), который необходим для доступа. Это обеспечит, что у вас всегда под рукой будут все данные для быстрого и безопасного доступа к вашему AWS аккаунту.
Форма логина в AWS Console
Давайте добавим соответствующие данные в Bitwarden, используя мобильный или десктопный клиент. При использовании браузерного расширения Bitwarden сам предлагает сохранить заполненные данные логина, создав новую запись, но мы не будем полагаться на это и попробуем для начала все настроить вручную.
Добавление логина в Bitwarden
Задаем имя пользователя в поле Username, а пароль — в поле Password. Поле Name служит просто названием карточки логина и может быть использовано для быстрого поиска среди других логинов. Если у вас в аккаунте AWS включена многофакторная аутентификация и Bitwarden добавлен в качестве соответствующего устройства Virtual MFA для вашей учетной записи, то в графе TOTP появится соответствующее значение вида otpauth://totp/Amazon%20Web%20Services:...
Добавить соответствующие данные в карточку логина можно с помощью мобильного приложения Bitwarden, отсканировав QR-код, который создает сам Amazon при добавлении соответствующего устройства MFA.
Также весьма полезно будет добавить дополнительное поле account
с идентификатором AWS аккаунта в графе CUSTOM FIELDS
, если мы не хотим каждый раз вводить или копировать его в форму логина вручную.
Поле account в разделе CUSTOM FIELDS
В поле Website можно добавить соответствующий адрес URL, тогда при использовании клиента или браузерного расширения Bitwarden сможет автоматически заполнять форму логина нужными данными:
Список адресов в разделе Website
Настраиваем CLI
Итак, у нас уже есть сохраненные данные IAM пользователя для логина в AWS Console. Но мы не хотим каждый раз вручную проделывать эту операцию, после чего также вручную обновлять сохраненные данные в Bitwarden. Для автоматизации данного процесса нам понадобятся следующие инструменты:
POSIX Shell (Bash, Zsh и т.п.) Для Windows тоже можно сделать вариант под cmd или powershell, но при наличии работающего WSL мне это представляется излишним.
AWS CLI
Bitwarden command-line interface (CLI)
jq
Не буду детально останавливаться на установке и настройке данных инструментов, обозначу лишь наиболее значимые моменты.
Для автоматизации действий с помощью Bitwarden CLI нам понадобится настроить авторизацию. Это можно делать различными способами. Наиболее удобный для обычного пользователя — использование персонального ключа API, который можно создать в профиле Bitwarden. После чего нужно в консоли выполнить команду
bw login --apikey
и ввести в ответ на запрос соответствующие данные client_id
и client_secret
. Либо можно задать соответствующие переменные окружения BW_CLIENTID
и BW_CLIENTSECRET
.
Для работы с данными нам нужен не только успешный логин, но и unlock хранилища секретов. Это можно сделать вручную с помощью команды
bw unlock
Для разблокировки потребуется также ввести мастер-пароль, дающий доступ к зашифрованным данным. Это стоит делать только непосредственно при работе с данными. По окончании работы следует выполнить команду bw lock
.
При успешном выполнении процедуры unlock будет создан временный сессионный ключ, который нам нужно будет использовать при выполнении любых операций с данными. Нам нужно задать его в виде переменной окружения для выполнения дальнейших команд:
export BW_SESSION="5PBYGU+5yt3RHcCjoeJKx/wByU34vokGRZjXpSH7Ylo8w=="
Если нам нужно выполнить полностью автоматическую процедуру логина и анлока, то это тоже можно сделать, задав соответствующие переменные окружения. Помимо упомянутых выше BW_CLIENTID
и BW_CLIENTSECRET
нам нужна будет еще и переменная BW_PASSWORD
, которой мы присвоим значение нашего мастер-пароля, который мы используем для разблокировки хранилища секретов.
Тогда выполнить автоматическую разблокировку можно простым выполнением команды
bw unlock --passwordenv BW_PASSWORD
После выполнения Bitwarden вернет нам в стандартном выводе значение переменной BW_SESSION
в виде готовой для исполнения команды. Если мы хотим полностью автоматизировать этот процесс, можно выполнить разблокировку следующим образом:
$(bw unlock --passwordenv BW_PASSWORD | awk '/export/ {print $2, $3}')
Так мы сразу разблокируем хранилище секретов и назначим правильное значение переменной BW_SESSION
без дополнительных ручных действий. После этого можно выполнить команду
bw sync
чтобы синхронизировать локальные данные хранилища с удаленным. При этом выполняется операция pull для получения всех последних изменений в хранилище секретов. Например, если вы создали какой-то секрет в Bitwarden с помощью другого приложения, клиента или вообще с другого устройства, то после выполнения этой команды вам станут доступны все последние изменения в хранилище ваших секретов.
Теперь можно заняться автоматизацией конкретных задач.
Меняем пароль IAM пользователя AWS
Возьмем для примера созданную нами чуть ранее запись с логином и паролем для пользователя john.doe и попробуем реализовать механизм изменения его пароля с автоматическим обновлением соответствующей записи в Bitwarden.
Для начала попробуем найти, как выглядит структура данных внутри записи при обращении к ней с помощью Bitwarden CLI. Чтобы вывести на экран данные записи для нашего логина с именем my_aws_account, используем следующую команду:
> bw get item my_aws_account --pretty
{
"passwordHistory": null,
"revisionDate": "2024-01-01T00:01:29.890Z",
"creationDate": "2024-01-01T00:01:29.890Z",
"deletedDate": null,
"object": "item",
"id": "32d1547c-5d14-37f2-7c2a-a0ef315dca6f",
"organizationId": null,
"folderId": "3f0a8c4a-9b5c-4f4d-9f9c-9c6a00a8f9e5",
"type": 1,
"reprompt": 0,
"name": "my_aws_account",
"notes": null,
"favorite": false,
"fields": [
{
"name": "account",
"value": "123412341234",
"type": 0,
"linkedId": null
}
],
"login": {
"fido2Credentials": [],
"uris": [
{
"match": null,
"uri": "https://eu-north-1.signin.aws.amazon.com/"
}
],
"username": "john.doe",
"password": "My_R@nd0m_$tr1ng",
"totp": null,
"passwordRevisionDate": null
},
"collectionIds": []
}
Мы видим, что у записи есть множество разных атрибутов. Но нас интересуют самые основные. Это id, login.username и login.password. Для поиска записей можно использовать значение поля name
, но этот параметр не обязательно будет уникальным, поэтому поиск может вернуть несколько разных записей. Чтобы обратиться к одной конкретной записи, лучше использовать ее уникальный идентификатор из поля id. Присвоим его значение конкретной переменной для удобства:
BW_ITEM_ID="32d1547c-5d14-37f2-7c2a-a0ef315dca6f"
Теперь получим старый пароль из записи Bitwarden, используя ее ID:
OLD_PASSWORD=$(bw get password "$BW_ITEM_ID")
Сгенерируем новый случайный с помощью команды bw generate:
NEW_PASSWORD=$(bw generate --length 16 --uppercase --lowercase --number --special)
Здесь в качестве параметров для генерации нового пароля мы указываем его длину (16 символов), обязательное наличие символов в верхнем регистре (uppercase), символов в нижнем регистре (lowercase), наличие цифр (number) и спецсимволов (special). В итоге в качестве значений переменной NEW_PASSWORD
мы получим случайную строку вида 9@8NfuGZ!&5pJoy%
.
Теперь, используя старый пароль, мы можем задать нашей учетной записи новый с помощью команды aws iam change-password
. Для выполнения данной команды нам потребуется также настроенный и работающий AWS CLI. Не будем здесь останавливаться подробно на деталях настройки данного инструмента. Нужно только отметить, что если вы используете различные аккаунты AWS, то скорее всего у вас настроены разные профили для доступа к командной строке с разными ключами для соответствующих аккаунтов. Поэтому при вызове команды нам также понадобится указать соответствующий профиль AWS в виде переменной AWS_PROFILE
. Если у вас нет разных профилей в настройках AWS CLI, либо вы используете другой источник ключей для доступа к AWS (например, переменные окружения), можете не указывать этот параметр. У нас получилось следующая команда:
aws iam change-password \
--old-password "$OLD_PASSWORD" \
--new-password "$NEW_PASSWORD" \
--profile "$AWS_PROFILE" && \
echo "Password changed successfully for profile '$AWS_PROFILE'." || {
echo "Failed to change password for profile '$AWS_PROFILE'."
return 1
}
Если доступ к AWS CLI настроен правильно, переменная OLD_PASSWORD
соответствует значению старого пароля, а значение переменной NEW_PASSWORD
соответствует требованиям к паролю для учетной записи AWS, то команда выполнится успешно и на экран выведется соответствующее сообщение. Если же по какой-то причине команда не завершится успешно, об этом тоже появится соответствующее сообщение.
Если все прошло успешно, то значит, новый пароль успешно задан и нам осталось лишь отредактировать нашу запись для учетной записи john.doe в Bitwarden, чтобы обновить значение пароля для данной записи. Чтобы сделать это из командной строки, нам придется воспользоваться также утилитой jq для работы с JSON. Итоговая команда по обновлению пароля в соответствующей записи Bitwarden будет выглядеть так:
bw get item "$BW_ITEM_ID" | jq --arg password "$NEW_PASSWORD" '.login.password = $password' | bw encode | bw edit item "$BW_ITEM_ID" >/dev/null
Если не перенаправить вывод итоговой команды в /dev/null, то на экран будет выведен итоговый JSON для нашей записи со всеми секретами, что не всегда полезно при работе в консоли. Поэтому для автоматизированных задач лучше отключить данный вывод.
В итоге мы с помощью Bitwarden CLI, AWS CLI и jq смогли сгенерировать новый пароль для выбранной нами учетной записи пользователя в AWS, а также смогли обновить соответствующую запись в нашем хранилище секретов Bitwarden.
Давайте теперь объединим данные команды в рамках одной общей функции, которую мы сможем вызывать одной командой из консоли. Получим примерно следующее:
rotate_aws_password() {
local AWS_PROFILE=my_profile
local BW_ITEM_ID=""
# Fetch the old AWS console password from Bitwarden
OLD_PASSWORD=$(bw get password "$BW_ITEM_ID")
# Generate new random password using Bitwarden CLI
NEW_PASSWORD=$(bw generate --length 16 --uppercase --lowercase --number --special)
# Use AWS CLI to change the password with the specified profile
aws iam change-password \
--old-password "$OLD_PASSWORD" \
--new-password "$NEW_PASSWORD" \
--profile "$AWS_PROFILE" && \
echo "Password changed successfully for profile '$AWS_PROFILE'." || {
echo "Failed to change password for profile '$AWS_PROFILE'."
return 1
}
# Update the password in Bitwarden
bw get item "$BW_ITEM_ID" | jq --arg password "$NEW_PASSWORD" '.login.password = $password' | bw encode | bw edit item "$BW_ITEM_ID" >/dev/null
# Clear the entered passwords from the shell environment for security
unset OLD_PASSWORD NEW_PASSWORD
}
Если добавить данный код в профиль вашего окружения для командного интерпретатора (.bashrc для Bash, .zshrc для Zsh и т.п.), то всю последовательность описанных выше действий можно запустить всего лишь одной командой:
> rotate_aws_password
Password changed successfully for profile 'my_profile'.
Можно проверить запись в соответствующей карточке Bitwarden и убедиться, что пароль для учетной записи john.doe действительно обновился.
Заключение
Мы рассмотрели пример автоматизации смены пароля для учетной записи AWS с использованием простых шелл-скриптов, а также с автоматическим обновлением сохраненных паролей в хранилище Bitwarden. Аналогичным образом можно автоматизировать ротацию ключей доступа к AWS CLI, получение временных токенов для доступа к AWS с использованием MFA и т.п. Если будет соответствующий запрос, попробую осветить данные моменты в следующих статьях.
Надеюсь, эта статья окажется полезной для упрощения вашей работы с AWS и Bitwarden. Я буду рад обсудить ваши идеи и предложения по дальнейшему улучшению автоматизации управления паролями. Буду рад любым отзывам в комментариях. Всего доброго.