Управление паролями локальных администраторов. Бесплатная замена Microsoft LAPS
10 июля 2024Одной из распространенных задач ИБ является управление паролями локального администратора. У компании Microsoft для управления паролями и регулярной их ротации существует продукт LAPS (Local Administrator Password Solution). Однако, он обеспечивает ротацию паролей локальных учетных записей только для доменных серверов. Для серверов не в домене, Linux-серверов LAPS не применим. С помощью существующих open source продуктов Hashicorp Vault, OpenBao, StarVault можно построить систему, которая позволяет автоматически ротировать пароли:
- для любых локальных учетных записей.
- вне зависимости от того входят ли сервера в домен или нет.
- вне зависимости от операционной системы.
Архитектура
Система состоит из 2х компонентов:
- Сервер, в роли которого выступает Hashicorp Vault, OpenBao, StarVault.
- Клиент:
- для Linux - приложение написаное на Go. Язык Go выбран, т.к. удобнее обрабатывать ошибки, по сравнению с bash, и не требуется устанавливать зависимости в отличие от Python.
- для Windows - скрипт powershell.
Vault и его альтернативы отвечают за :
- создание надежных паролей в соотвествии с заданными политиками.
- хранение паролей с разграничением доступа.
- хранение истории паролей с заданной глубиной хранения.
Клиентская часть:
- запрашивает новый пароль у Vault.
- сохраняет пароль в Vault.
- обновляет пароль на хосте для заданной учетной записи.
Для запуска клиентской части по расписанию используются:
- в Linux - таймер systemd.
- в Windows - Task Scheduler.
Права доступа к секретам (паролям) разграничены таким образом, что сервера могут только создавать и обновлять секреты в Vault. А системные администраторы - только читать эти секреты.
Исходный код клиентской части размещен на https://gitverse.ru/strongpass/manage-local-admin-password
Настройка Vault
Предполагается, что у вас уже есть развернутый сервер Vault и вы можете к нему подключиться с административной учетной записью. В статье не будет описываться выбор схемы развертывания и установка Vault, т.к. таких статей уже достаточно много в Интернeт. Так же в статье не рассматривается настройка прав доступа к чтению секретов для системных администраторов, т.к. она индивидуальна в каждой компании.
Аутентифицируемся в Vault с помощью токена (вместо <токен>
подставьте свой токен доступа):
> vault login token=<токен>
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.
Key Value
--- -----
token hvs.cNsG340tvlimz8ENAM4HtrMY
token_accessor Zw3IjEt8LqNiLqoA4hcTxvBh
token_duration ∞
token_renewable false
token_policies ["root"]
identity_policies []
policies ["root"]
Полученный токен сохраним в переменную среды VAULT_TOKEN
export VAULT_TOKEN="hvs.cNsG340tvlimz8ENAM4HtrMY"
Создадим файл password-policy.hcl
с настройками парольной политики:
length=20
rule "charset" {
charset = "abcdefghijklmnopqrstuvwxyz"
min-chars = 1
}
rule "charset" {
charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
min-chars = 1
}
rule "charset" {
charset = "0123456789"
min-chars = 1
}
rule "charset" {
charset = "!@#$%^&*-"
min-chars = 1
}
Создадим парольную политику с именем local-account-pwd-policy
:
vault write sys/policies/password/local-account-pwd-policy policy=@password-policy.hcl
Проверим, что можем получить сгенерированный пароль в соответствии с этой политикой:
curl --request GET \
--url http://vault.acme.corp/v1/sys/policies/password/local-account-pwd-policy/generate \
--header "X-Vault-Token: $VAULT_TOKEN"
В случае успеха, вы должны получить ответ вида:
{"request_id":"c6ea55d6-189a-df1f-4279-ab2947f0722f","lease_id":"","renewable":false,"lease_duration":0,"data":{"password":"UAVq1SVXVR8XWwRB7pxG"},"wrap_info":null,"warnings":null,"auth":null}
В поле data.password
будет находиться сгенерированный пароль.
Создадим KV-хранилище с именем local-account-creds
для хранения паролей:
vault secrets enable -version=2 -path=local-accounts-creds kv
Создадим политику доступа к паролям для клиентской части системы, выполняющийся на серверах. Приложения и скрипты для смены пароля могут создавать и обновлять секреты, но не могут их читать или удалять. Так же предоставим возможность генерировать пароли с помощью ранее созданной политики.
# Allows hosts to write new passwords
path "local-accounts-creds/*" {
capabilities = ["create", "update"]
}
path "sys/policies/password/local-account-pwd-policy/generate" {
capabilities=["read"]
}
Включаем метод атунтификации AppRole, который предназначен для аутентификации сервисов, приложений:
vault auth enable approle
Создаем роль для серверов
vault write auth/approle/role/pwd-rotate token_policies="password-rotate" token_ttl=1h token_max_ttl=2h
В данном варианте предполагается, что роль одна для всех серверов или группы серверов. Для усиления безопасности вы можете создавать отдельные роли для каждого сервера и устанавливать дополнительные ограничения для ролей. Проверяем правильность параметров:
❯ vault read auth/approle/role/pwd-rotate
Key Value
--- -----
bind_secret_id true
local_secret_ids false
secret_id_bound_cidrs <nil>
secret_id_num_uses 0
secret_id_ttl 0s
token_bound_cidrs []
token_explicit_max_ttl 0s
token_max_ttl 2h
token_no_default_policy false
token_num_uses 0
token_period 0s
token_policies [password-rotate]
token_ttl 1h
token_type default
Обратите внимание на token_policies
. Если вы сделали все правильно, то значение этого параметра будет содержать имя политики для генерации паролей.
Получаем role-id
и secret-id
. RoleID - это идентификатор AppRole, по которому оцениваются другие учетные данные. При аутентификации в систему RoleID всегда является обязательным аргументом (через role-id). В данном случае role-id
эквивалентен имени пользователя, а secret-id
- соответствующему паролю.
❯ vault read auth/approle/role/pwd-rotate/role-id
Key Value
--- -----
role_id c59c3a2f-1991-5a8f-d08f-d8f8415ff6aa
❯ vault write -force auth/approle/role/pwd-rotate/secret-id
Key Value
--- -----
secret_id 53e7b725-b93e-ffdd-5865-0ef3b48ccca7
secret_id_accessor 8dc2d921-5ce1-ba52-0110-97eecd1f5a1b
secret_id_num_uses 0
secret_id_ttl 0s
Значение параметра secret_id_ttl
равное 0s
означает, что secret_id
действует бессрочно.
Пробуем авторизоваться с указанными данными и получить токен доступа:
❯ vault write auth/approle/login role_id="c59c3a2f-1991-5a8f-d08f-d8f8415ff6aa" secret_id="53e7b725-b93e-ffdd-5865-0ef3b48ccca7"
Key Value
--- -----
token hvs.CAESIIMFzrS9j-6p5hQo5cofWpHZS__qoc0Kxqr95pc6nCyMGh4KHGh2cy5ZS0lNRE9ySGlrYVhVTnBtZTdZc3JQTmo
token_accessor RpP3Cwc3CeHOWbk1MonNaqDU
token_duration 1h
token_renewable true
token_policies ["default" "password-rotate"]
identity_policies []
policies ["default" "password-rotate"]
token_meta_role_name pwd-rotate
Для дальнейших проверок сохраняем токен доступа в переменную окружения VAULT_TOKEN
export VAULT_TOKEN="hvs.CAESIIMFzrS9j-6p5hQo5cofWpHZS__qoc0Kxqr95pc6nCyMGh4KHGh2cy5ZS0lNRE9ySGlrYVhVTnBtZTdZc3JQTmo"
Проверяем, что политики доступа настроены правильно и мы можем получить сгенерированный пароль:
❯ curl -k --request GET \
--url http://vault.acme.corp/v1/sys/policies/password/local-account-pwd-policy/generate \
--header "X-Vault-Token: $VAULT_TOKEN"
В случае успеха, в поле data.password
будет содержаться новый пароль:
{"request_id":"dd9250a2-655e-b8ea-f750-ca5291505e6d","lease_id":"","renewable":false,"lease_duration":0,"data":{"password":"zH2c54POGm4YKEwHzmxC"},"wrap_info":null,"warnings":null,"auth":null}
Проверяем запись пароля в Vault:
curl \
--header "X-Vault-Token: $VAULT_TOKEN" \
--json '{"data":{"root": "password-test"}}' \
http://vault.acme.corp/v1/local-accounts-creds/data/host_test
Успешный ответ будет выглядеть так:
{"request_id":"dca9f6c9-172d-0f42-c985-3715522f0d55","lease_id":"","renewable":false,"lease_duration":0,"data":{"created_time":"2024-07-07T14:53:25.263274272Z","custom_metadata":null,"deletion_time":"","destroyed":false,"version":2},"wrap_info":null,"warnings":null,"auth":null}
Со стороны Vault все готово для автоматизации смены паролей.
Настройка клиентской части для Linux
Переходим на сервер, на котором планируем автоматически менять пароль. Скачайте архив
с клиентской частью для Linux (файл password-auto-rotate.lnx.tar.gz
) со страницы
https://gitverse.ru/strongpass/manage-local-admin-password/releases
и распакуйте его.
Скопируйте файл password-auto-rotate
в /usr/local/bin
Скопируйте файл assets/password-auto-rotate.env
в /etc/defaut
и устанавите переменным значения, полученные при настройке Vault:
VAULT_ADDR="https://vault.acme.corp"
ROLE_ID=c59c3a2f-1991-5a8f-d08f-d8f8415ff6aa
SECRET_ID=53e7b725-b93e-ffdd-5865-0ef3b48ccca7
PASSWORD_POLICY_NAME="local-account-pwd-policy"
SECRETS_STORE_NAME="local-accounts-creds"
SECRETS_BASE_PATH="linux"
Скопируйте файлы из архива assets/password-auto-rotate.timer
и assets/password-auto-rotate.service
в /etc/systemd/system
. Эти файлы в дальнейшем будут использоваться как основа для сервисов, которые меняют пароли у конкретных пользователей. Вы можете настроить ротацию паролей для любой локальной учетной записи.
Создаем сервисы для смены пароля у пользователя root
:
cp /etc/systemd/system/password-auto-rotate.service /etc/systemd/system/password-auto-rotate@root.service
cp /etc/systemd/system/password-auto-rotate.timer /etc/systemd/system/password-auto-rotate@root.timer
Активируем таймер:
systemctl enable --now /etc/systemd/system/password-auto-rotate@root.timer
Повторите два последних действия для каждой учетной записи, пароль которой необходимо автоматически менять.
Посмотреть список таймеров и их статус можно командой systemctl list-timers --all
Запустим сервис для проверки правильности всех настроек.
systemctl start password-auto-rotate@root.service
Результат выполнения сервиса можно посмотреть в журнале.
journalctl -xeu password-auto-rotate@root.service
При необходимости вывод сообщений о ходе выполнения сервиса можно перенаправить в файл. Подробнее см. README
Система готова для автоматической ротации паролей на Linux-серверах.
Настройка клиентской части для Windows
Скачайте архив password-auto-rotate.win.zip
со страницы
https://gitverse.ru/strongpass/manage-local-admin-password/releases.
и распакуйте его.
Скопируйте файл в password-auto-rotate.ps1
в каталог C:\Program Files\password-auto-rotate\
Запустите скрипт из командной строки powershell
и убедитесь, что с указанными вами параметрами командной строки обновление пароля происходит успешно. Пример запуска скрипта:
.\password-auto-rotate.ps1 -VaultAddr "https://vault.acme.corp" -RoleID "c59c3a2f-1991-5a8f-d08f-d8f8415ff6aa" -SecretID "53e7b725-b93e-ffdd-5865-0ef3b48ccca7" -PasswordPolicyName "local-account-pwd-policy" -SecretsStoreName "local-accounts-creds" -SecretsBasePath "windows" -Username Administrator
Создайте задачу в Task Scheduler. Сначала указываем базовые параметры:
$principal = New-ScheduledTaskPrincipal -UserID "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount
$settings = New-ScheduledTaskSettingsSet
Зададим расписание запуска:
$trigger = New-ScheduledTaskTrigger -RandomDelay (New-TimeSpan -Minute 1) -Daily -At 1am
Создадим команду, которая будет выполняться задачей. Обратите внимание, что значение параметра Argument
находится в одинарных кавычках.
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument '-File "C:\Program Files\password-auto-rotate\password-auto-rotate.ps1" -VaultAddr "https://vault.acme.corp" -RoleID "c59c3a2f-1991-5a8f-d08f-d8f8415ff6aa" -SecretID "53e7b725-b93e-ffdd-5865-0ef3b48ccca7" -PasswordPolicyName "local-account-pwd-policy" -SecretsStoreName "local-accounts-creds" -SecretsBasePath "windows" -Username Administrator'
Теперь создаем непосредственно саму задачу и регистрируем ее в Task Scheduler:
$task = New-ScheduledTask -Action $action -Principal $principal -Trigger $trigger -Settings $settings
Register-ScheduledTask -TaskName "Password auto rotate" -InputObject $task
Результаты выполнение скрипта пишутся:
- кратко - в журнал
Application
Windows Event Log. Сообщения можно найти произведя поиск по источнику сообщенийPasswordAutoRotate
. - подробно - в файл
C:\windows\debug\password-auto-rotate.log
Система готова для автоматической ротации паролей на Windows-серверах.