https://github.com/yandex-cloud-examples/yc-secure-bypass-password-to-cloudinit
Безопасная передача паролей в скрипт инициализации cloudinit при развертывании Windows ВМ в Yandex Cloud.
https://github.com/yandex-cloud-examples/yc-secure-bypass-password-to-cloudinit
kms lockbox passwords-management terraform windows windows-vm yandex-cloud yandexcloud
Last synced: 4 months ago
JSON representation
Безопасная передача паролей в скрипт инициализации cloudinit при развертывании Windows ВМ в Yandex Cloud.
- Host: GitHub
- URL: https://github.com/yandex-cloud-examples/yc-secure-bypass-password-to-cloudinit
- Owner: yandex-cloud-examples
- License: apache-2.0
- Created: 2024-03-08T08:37:06.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-02-16T09:19:23.000Z (8 months ago)
- Last Synced: 2025-02-28T02:56:16.938Z (7 months ago)
- Topics: kms, lockbox, passwords-management, terraform, windows, windows-vm, yandex-cloud, yandexcloud
- Language: PowerShell
- Homepage:
- Size: 864 KB
- Stars: 0
- Watchers: 4
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# YC Windows VM Безопасная передача паролей в скрипт инициализации
## Проблема
По умолчанию все передаваемые в vm метаданные доступны для чтения, адмнистраторам. При этом, администраторы облачных контейнеров не обязательно должны иметь доступ к гостевой ОС. Пример:
для безопасной передачи и хранения секретов (паролей, приватных ключей) в гостевую ОС через сервис метаданных предлагается использовать скрипт инициализации с использованием сервиса Lockbox.
## Решение
Назначенный на виртуальную машину сервисный аккаунт может аутентифицироваться и авторизоваться в IAM изнутри гостевой ОС по упрощенной схеме. Т.е. достаточно просто получить IAM-токен через yc cli или REST API, не передавая никакой информации о субъекте. Это дает возможность при минимально необходимых правах безопасно передать в гостевую ОС пару ключ/значение (секретная часть) из Lockbox с помощью сервисного аккаунта.
### 1. Создать сервисный аккаунт
На уровне каталога на вкладке `Service Accounts` создадим сервисный аккаунт в контексте которого скрипт будет обращаться к сервисам KMS и Lockbox.

Обратите внимание, что на данном этапе роли не назначаются, тк роли уровня каталога дадут сервисному аккаунту доступ ко всем ключам и секретам каталога.### 2. Создать ключ KMS
Создадим ключ KMS и на вкладке **Access Bindings** ключа назначим сервисному аккаунту роль `kms.keys.encrypterDercrypter`.

Роль на уровне ключа гарантирует гранулярный доступ к операциям на конкретном ключе для сервисного аккаунта.### 3. Создать секрет в Lockbox
Создадим секрет с указанием ключа шифрования.

В одном секрете может быть несколько пар ключ-значение. Каждая пара ключ-значение представляет из себя логин и пароль пользователя. Первым всегда должен стоять локальный администратор по умолчанию. Остальные пользователи будут циклично созданы с минимальными правами в ОС.
На вкладке **Access Bindings** выдадим сервисному аккаунту роль `lockbox.payloadViewer`
### 4. Создать Виртуальную машину
Создадим файл `init.ps1` с содержимым:```PowerShell
#ps1
# ^^^ 'ps1' is only for cloudbase-init, some sort of sha-bang in linux# logging
Start-Transcript -Path "$ENV:SystemDrive\provision2.txt" -IncludeInvocationHeader -Force
"Bootstrap script started" | Write-Host# You have to create Lockbox secret
# and assign service account with roles lockbox.payloadViewer and kms.key.encryptorDecryptor to VM# HERE'S ENTER YOUR SECRET'S ID OF IMPORT FROM TERRAFORM VARIABLE:
$SecretID = ""[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$SecretURL = "https://payload.lockbox.api.cloud.yandex.net/lockbox/v1/secrets/$SecretID/payload""Secret ID is $SecretID"
"Payload URL is $SecretURL"$YCToken = (Invoke-RestMethod -Headers @{'Metadata-Flavor'='Google'} -Uri "http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token").access_token
if (!$YCToken) {
throw "Service Account doesn't connected to VM. Please, add Service account with roles lockbox.payloadViewer and kms.key.encryptorDecryptor to VM and try again."
}# Creating parameters for REST-invokations
$Headers = @{
Authorization="Bearer $YCToken"
}$Params = @{
Uri = $SecretURL
Method = "GET"
Headers = $Headers
}# Getting secret via REST invoke
$Secret = Invoke-RestMethod @Params
$SecretAdministratorPlainTextPassword = $Secret.entries[0].textValue# inserting value's from terraform
if (-not [string]::IsNullOrEmpty($SecretAdministratorPlainTextPassword)) {
"Set local administrator password" | Write-Host
$SecretAdministratorPassword = $SecretAdministratorPlainTextPassword | ConvertTo-SecureString -AsPlainText -Force
# S-1-5-21domain-500 is a well-known SID for Administrator
# https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/security-identifiers-in-windows
$Administrator = Get-LocalUser | Where-Object -Property "SID" -like "S-1-5-21-*-500"
$Administrator | Set-LocalUser -Password $SecretAdministratorPassword
}# Creating new users if any
if($Secret.entries.count -gt 1) {
foreach($User in $Secret.entries[1..($Secret.entries.count-1)]){
$SecretUserPassword = $User.textValue | ConvertTo-SecureString -AsPlainText -Force
New-LocalUser -Name $User.key -Password $SecretUserPassword -FullName $User.key
Add-LocalGroupMember -Group Users -Member $User.key
Add-LocalGroupMember -Group "Remote Desktop Users" -Member $User.key
}
}"Bootstrap script ended" | Write-Host
```Здесь в переменную `$SecretID` необходимо указать id секрета Lockbox. Тк id секрета - не сам секрет, то это не является чувствительной информацией.
**Создание ВМ (yc cli):**
```Bash
yc compute instance create --name --hostname --zone ru-central1-a --create-boot-disk image-id= --cores 2 --core-fraction 100 --memory 4 --metadata-from-file user-data=init.ps1 --network-interface subnet-name=,nat-ip-version=ipv4 --service-account-name --platform standard-v3
```**Создание ВМ (UI):**
В UI можно передать в user-data скрипт инициализации. Для этого в поле `key` нужно написать `user-data`, а в поле `Value` вставить скрипт инициализации
### 5. Проверка
Теперь в метаданных ВМ чувствительные данные отсутствуют:
