Secure password transmission to an initialization script
When creating a VM from an image with the Windows OS, you can use an initialization script. For example, you can set up username-password pairs for the administrator and other system users. To protect sensitive data, use Yandex Lockbox tools and Yandex Key Management Service keys instead of explicitly specifying settings in the script.
In this tutorial, you will create a Windows VM with its initialization script receiving usernames and passwords from Yandex Lockbox.
To create a VM while protecting sensitive information in its initialization script:
If you no longer need the resources you created, delete them.
Getting started
Sign up for Yandex Cloud and create a billing account:
- Go to the management console
and log in to Yandex Cloud or create an account if you do not have one yet. - On the Yandex Cloud Billing
page, make sure you have a billing account linked and it has theACTIVE
orTRIAL_ACTIVE
status. If you do not have a billing account, create one.
If you have an active billing account, you can go to the cloud page
Learn more about clouds and folders.
Required paid resources
The infrastructure support cost includes:
- Fee for continuously running VMs (see Yandex Compute Cloud pricing).
- Fee for using an image (depends on the image).
- Fee for using a KMS key (see KMS pricing).
- Fee for using a secret (see Yandex Lockbox pricing).
Create a service account
- In the management console
, select the folder where you want to create a service account. - In the list of services, select Identity and Access Management.
- Click Create service account.
- Specify the service account name, e.g.,
win-secret-sa
. - Click Create.
The folder specified in the CLI profile is used by default. You can specify a different folder through the --folder-name
or --folder-id
parameter.
To create a service account, run the command below, specifying win-secret-sa
as the service account name:
yc iam service-account create --name win-secret-sa
Where name
is the service account name.
Result:
id: ajehr0to1g8b********
folder_id: b1gv87ssvu49********
created_at: "2024-03-15T09:03:11.665153755Z"
name: win-secret-sa
To create a service account, use the ServiceAccountService/Create gRPC API call or the create REST API method for the ServiceAccount
resource.
Create a KMS key
-
Create an encryption key:
Management consoleCLITerraformAPI- In the management console
, select the folder where you want to create a key. - Select Key Management Service.
- In the left-hand panel, select
Symmetric keys. - Click Create key and specify its attributes:
- Name:
win-secret-key
. - Encryption algorithm:
AES-256
. - Leave other attributes as default.
- Name:
- Click Create.
This will create an encryption key and its first version; click the key in the list to open its attribute page.
Run this command:
yc kms symmetric-key create \ --name win-secret-key \ --default-algorithm aes-256
Where:
--name
: Key name.--default-algorithm
: Encryption algorithm:aes-128
,aes-192
, oraes-256
.
With Terraform
, you can quickly create a cloud infrastructure in Yandex Cloud and manage it using configuration files. These files store the infrastructure description written in HashiCorp Configuration Language (HCL). If you change the configuration files, Terraform automatically detects which part of your configuration is already deployed, and what should be added or removed.Terraform is distributed under the Business Source License
. The Yandex Cloud provider for Terraform is distributed under the MPL-2.0 license.For more information about the provider resources, see the documentation on the Terraform
website or mirror website.If you don't have Terraform, install it and configure the Yandex Cloud provider.
To create a key:
-
Describe the parameters of the
yandex_kms_symmetric_key
resource in the configuration file:resource "yandex_kms_symmetric_key" "key-a" { name = "<key_name>" description = "<key_description>" default_algorithm = "AES_128" rotation_period = "8760h" deletion_protection = true lifecycle { prevent_destroy = true } }
Where:
-
name
: Key name. The name format is as follows:- It must be 2 to 63 characters long.
- It may contain lowercase Latin letters, numbers, and hyphens.
- It must start with a letter and cannot end with a hyphen.
-
description
: Key description. -
default_algorithm
: Encryption algorithm. The possible values areAES-128
,AES-192
, orAES-256
. -
rotation_period
: Rotation period (how often to change key versions). To create a key without automatic rotation, do not specify therotation_period
parameter. -
deletion_protection
: Key deletion protection. To create a key without deletion protection, do not specify thedeletion_protection
parameter. -
lifecycle.prevent_destroy
: Key deletion protection when running Terraform commands. To create a key without such protection, do not specify thelifecycle
section.
Warning
Deleting a KMS key destroys all data encrypted with that key: the data becomes unrecoverable after the key is deleted. The
deletion_protection
parameter and thelifecycle
section are required to prevent the deletion of the key (e.g., with theterraform destroy
command).For more information about resource parameters in Terraform, see the provider documentation
. -
-
Check the configuration using this command:
terraform validate
If the configuration is correct, you will get this message:
Success! The configuration is valid.
-
Run this command:
terraform plan
The terminal will display a list of resources with their parameters. No changes will be made at this step. If the configuration contains any errors, Terraform will point them out.
-
Apply the configuration changes:
terraform apply
-
Confirm the changes: type
yes
into the terminal and press Enter.This will create all the resources you need in the specified folder. You can check the new resources and their configuration using the management console
or these CLI commands:yc kms symmetric-key list
Use the create REST API method for the SymmetricKey resource or the SymmetricKeyService/Create gRPC API call.
- In the management console
-
Assign the
kms.keys.encrypterDercrypter
role to thewin-secret-sa
service account:Management consoleCLIAPI- Navigate to the Access rights tab on the key page.
- Navigate to the Access bindings tab.
- Find the
win-secret-sa
account in the list and click . - Click Edit roles.
- In the dialog box that opens, click Add role and select
kms.keys.encrypterDercrypter
.
Run this command:
yc resource-manager folder add-access-binding <folder_ID> \ --role kms.keys.encrypterDercrypter \ --subject serviceAccount:<service_account_ID>
To assign a role for the folder to the service account, use the setAccessBindings REST API method for the ServiceAccount resource or the ServiceAccountService/SetAccessBindings gRPC API call.
Create a secret
Create a Yandex Lockbox secret to save usernames and passwords of Windows user accounts.
Warning
When selecting passwords, make sure to comply with mandatory password requirements.
These password requirements are:
- At least 8 characters long.
- Does not incude the account name.
- Must include three of the following:
- Latin uppercase letters (A-Z)
- Latin lowercase letters (a-z)
- Numbers (0-9)
- Non-alphanumeric characters (
!
,?
,%
,$
,#
, etc.)
- In the management console
, select the folder where you want to create your secret. - In the list of services, select Lockbox.
- Click Create secret.
- In the Name field, specify the secret name:
win-secret
. - In the KMS key field, specify the
win-secret-key
key. - Under Version:
- In the Key field, specify the
Administrator
username. - In the Value, specify the administrator password.
- In the Key field, specify the
- You can add more users by clicking Add key/value and specifying their usernames and passwords.
- Click Create.
-
Run this command:
yc lockbox secret create \ --name win-secret \ --kms-key-id <key_ID> \ --payload "[{'key': 'Administrator', 'text_value': '<administrator_password>'},{'key': 'user1', 'text_value': '<user_password>'}]" \ --cloud-id <cloud_ID> \ --folder-id <folder_ID>
Where:
--name
: Secret name (required).--kms-key-id
: KMS key ID.--description
: Secret description (optional).--payload
: Secret content in YAML or JSON format.--cloud-id
: ID of the cloud where you want to create your secret.--folder-id
: ID of the folder where you want to create your secret.
If you don't have Terraform, install it and configure the Yandex Cloud provider.
-
In the configuration file, describe the resources you want to create:
resource "yandex_lockbox_secret" "win_secret" { name = "<secret_name>" folder_id = "<folder_ID>" kms_key_id = "<encryption_key_ID>" } resource "yandex_lockbox_secret_version" "win_secret_version" { secret_id = yandex_lockbox_secret.win_secret.id entries { key = "Administrator" text_value = "<administrator_password>" } entries { key = "user1" text_value = "<user_password>" } }
Where:
name
: Secret name (required).folder_id
: ID of the folder where you want to create a secret (optional).kms_key_id
: ID of the Key Management Service encryption key used to encrypt your secret.entries
: Secret content.
Note
We recommend using
yandex_lockbox_secret_version_hashed
: it stores values in Terraform state in hashed format. We continue supportingyandex_lockbox_secret_version
.For more information about
yandex_lockbox_secret_version_hashed
, see the relevant provider documentation .Warning
For better security, instead of setting the password directly in your configuration file, use a reference to an environment variable.
-
Create the resources:
-
In the terminal, change to the folder where you edited the configuration file.
-
Make sure the configuration file is correct using the command:
terraform validate
If the configuration is correct, the following message is returned:
Success! The configuration is valid.
-
Run the command:
terraform plan
The terminal will display a list of resources with parameters. No changes are made at this step. If the configuration contains errors, Terraform will point them out.
-
Apply the configuration changes:
terraform apply
-
Confirm the changes: type
yes
in the terminal and press Enter.
-
To create a secret, use the create REST API method for the Secret resource or the SecretService/Create gRPC API call.
-
Assign the
lockbox.payloadViewer
role to thewin-secret-sa
service account:Management consoleCLIAPI- Navigate to the Access rights tab on the secret page.
- Navigate to the Access bindings tab.
- Find the
win-secret-sa
account in the list and click . - Click Edit roles.
- In the dialog that opens, click Add role and select the
lockbox.payloadViewer
role.
Run this command:
yc resource-manager folder add-access-binding <folder_ID> \ --role lockbox.payloadViewer \ --subject serviceAccount:<service_account_ID>
To assign a role for the folder to the service account, use the setAccessBindings REST API method for the ServiceAccount resource or the ServiceAccountService/SetAccessBindings gRPC API call.
Create a VM
Create a Windows VM and add the administrator and user accounts to it.
-
Create the
init.ps1
file with the following code:#ps1 # logging Start-Transcript -Path "$ENV:SystemDrive\provision2.txt" -IncludeInvocationHeader -Force "Bootstrap script started" | Write-Host # SECRET'S ID: $SecretID = "<secret_id>" [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
-
Replace
<secret_id>
with the ID of the secret with user account data you created in the previous step. -
Create a VM:
Management consoleCLI-
In the management console
, select the folder where you want to create your VM. -
At the top right, click Create resource and select
Virtual machine instance
. -
Under Boot disk image, select the Windows image.
-
Under Location, select an availability zone where your VM will reside.
-
Under General information, specify the VM name, e.g.,
win-test
. -
Under Advanced, specify the VM access credentials:
- Select the
win-secret-sa
service account. - Grant it access to the serial console.
- Select the
-
Under Metadata:
- In the Key field, specify
user-data
. - In the Value field, paste the contents of the
init.ps1
file.
- In the Key field, specify
-
Click Create VM.
Run this command:
yc compute instance create --name win-test --hostname windows10 --zone ru-central1-a --create-boot-disk image-id=<imade_id> --cores 2 --core-fraction 100 --memory 4 --metadata-from-file user-data=init.ps1 --network-interface subnet-name=<subnet_name>,nat-ip-version=ipv4 --service-account-name win-test-sa --platform standard-v3
Where:
imade_id
: Windows image ID.subnet_name
: Name of the subnet where your VM will get connected.
{% include cli-metadata-variables-substitution-notice %}
-
Log in to Windows
To make sure the setup created user accounts from your secret, log in to Windows on your VM:
-
In the management console
, select your VM folder. -
Select Compute Cloud.
-
Select the
win-test
VM. -
Navigate to the Serial console tab.
-
Under Serial console, select
COM2
and click Connect. You will see the command line prompt:SAC>
-
Show the list of open channels:
SAC>ch Channel List (Use "ch -?" for information on using channels) # Status Channel Name 0 (AV) SAC 1 (AV) Cmd0001
-
To switch to a channel, press Esc + Tab or run the following command:
SAC>ch -sn Cmd0001 Name: Cmd0001 Description: Command Type: VT-UTF8 Channel GUID: e203fb79-d80d-11ea-87e3-c2679e14957d Application Type GUID: 63d02271-8aa4-11d5-bccf-00b0d014a2d0 Press <esc><tab> for next channel. Press <esc><tab>0 to return to the SAC channel. Use any other key to view this channel.
-
Press Enter and specify the following:
- Username.
- Domain, if you logged in under a domain account; otherwise, enter your host name or nothing.
- Password.
Please enter login credentials. Username: Administrator Domain : Password: ***************
-
If you logged in successfully, you will see the Windows command prompt:
C:\Windows\system32>
A successful login means that the setup created user accounts from your secret.
How to delete the resources you created
To stop paying for the resources you created: