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 functionality instead of explicitly specifying settings in the script.
In this tutorial, you will create a VM with the Windows OS using an initialization script which will get username-password pairs of system users from Yandex Lockbox.
To create a VM and protect confidential information in the 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 VMs (see Yandex Compute Cloud pricing).
- Fee for image use (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.
- Enter a name for the service account, e.g.,
win-secret-sa
. - Click Create.
The folder specified in the CLI profile is used by default. You can specify a different folder using the --folder-name
or --folder-id
parameter.
Run the command below to create a service account, specifying win-secret-sa
as its 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 the key attributes:
- Name:
win-secret-key
. - Encryption algorithm:
AES-256
. - Leave the other parameters at their default settings.
- Name:
- Click Create.
The key is created together with its first version: click the key in the list to open the page with its attributes.
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" lifecycle { prevent_destroy = true } }
Where:
-
name
: Key name. The name format is as follows:- The name must be from 3 to 63 characters long.
- It may contain lowercase Latin letters, numbers, and hyphens.
- The first character must be a letter and the last character cannot be 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.
Warning
Deleting a KMS key destroys all data encrypted with that key: the data becomes unrecoverable after the key is deleted. The
lifecycle
block is necessary to prevent users from destroying keys (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 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.All the resources you need will then be created 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- Go to the Access rights tab on the key page.
- Go to the Access bindings tab.
- Find the
win-secret-sa
account in the list and click . - Click Edit roles.
- Click Add role in the dialog box that opens and select the
kms.keys.encrypterDercrypter
role.
Run this command:
yc resource-manager folder add-access-binding <folder_ID> \ --role kms.keys.encrypterDercrypter \ --subject serviceAccount:<service_account_ID>
To assign the service account a role for the folder, use the setAccessBindings REST API method for the ServiceAccount resource or the ServiceAccountService/SetAccessBindings gRPC API call.
Create a secret
Create a secret in Yandex Lockbox and use it to save username-password pairs of users for whom accounts will be created in the Windows OS.
Warning
When choosing a password, make sure to comply with the password security requirements; otherwise, the account will not be created for the user.
The password must:
- Contain eight or more characters.
- Not contain the account name.
- Contain characters from at least three of the following four groups:
- Latin uppercase letters (A-Z)
- Latin lowercase letters (a-z)
- Digits (0-9)
- Non-alphanumeric characters (!, ?, %, $, #, etc.)
- In the management console
, select the folder where you want to create a secret. - In the list of services, select Lockbox.
- Click Create secret.
- In the Name field, enter a name for the secret:
win-secret
. - In the KMS key field, specify the
win-secret-key
key. - Under Version:
- In the Key field, enter the username for
Administrator
. - In the Value, enter the administrator password.
- In the Key field, enter the username for
- Add more users if needed by clicking Add key/value and entering the username and password for the next user.
- 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. This is a required parameter.--kms-key-id
: ID of the KMS key.--description
: Secret description. This is an optional parameter.--payload
: Contents of the secret as a YAML or JSON array.--cloud-id
: ID of the cloud where you want to create your secret.--folder-id
: ID of the folder where you want to create a secret.
If you don't have Terraform, install it and configure the Yandex Cloud provider.
-
In the configuration file, describe the parameters of 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. This is a required parameter.folder_id
: ID of the folder where you want to create a secret. This is an optional parameter.kms_key_id
: ID of the Key Management Service encryption key. The specified Key Management Service key is used to encrypt your secret.entries
: Contents of the secret.
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
To improve security, you should set the password in the configuration file using the environment variable.
-
Create 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- Go to the Access rights tab on the secret page.
- Go to the Access bindings tab.
- Find the
win-secret-sa
account in the list and click . - Click Edit roles.
- Click Add role in the dialog box that opens 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 the service account a role for the folder, use the setAccessBindings REST API method for the ServiceAccount resource or the ServiceAccountService/SetAccessBindings gRPC API call.
Create a VM
Create a VM with the Windows OS having the administrator and user accounts.
-
Create a file named
init.ps1
and save the following code in it:#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
-
In the
init.ps1
file, replace<secret_id>
with the real ID of the secret where you saved the user accounts. -
Create a VM:
Management consoleCLI-
In the management console
, open the folder to create your VM in. -
At the top right, click Create resource and select
Virtual machine instance
. -
Under Boot disk image, select the image with the Windows OS.
-
Under Location, select an availability zone to place your VM in.
-
Under General information, specify the VM name, e.g.,
win-test
. -
Under Advanced, specify the data for access to the VM:
- Select the
win-secret-sa
service account. - Grant 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: ID of the image with the Windows OS.
- subnet_name: Subnet name in the folder where you want to place the VM.
-
Log in to Windows
To check that the data from the secret was successfully used to create users, log in to the VM's OS:
-
In the management console
, select the folder the VM belongs to. -
Select Compute Cloud.
-
Select the
win-test
VM. -
Go to the Serial console tab.
-
Under Serial consoleAdvanced settings, select
COM2
and click Connect. The command line will prompt you to enter commands:SAC>
-
View 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 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 in the given order:
- Username.
- Domain if the domain account is used for logging in. Otherwise, enter the hostname or leave empty.
- Password.
Please enter login credentials. Username: Administrator Domain : Password: ***************
-
If you log in successfully, an instance of the command line interpreter will start:
C:\Windows\system32>
If you log in successfully, it means that the data from the secret was used to create the VM.
How to delete the resources you created
To stop paying for the resources you created:
- Delete the VM.
- Delete the secret.
- Destroy keys.