Want to deploy a bunch of Canaries and have them pre-configured during the deployment? We can do this using the equivalent cloud-init for each of our Cloud and Virtual platforms:
- AWS, GCP and OCI using the user-data of the instance via a cloud-init yaml file. (jump)
- Azure using the json user-data file of the instance via the instance metadata api. (jump)
- Hyper-V using a base64 encoded key-value pair via the Hyper-V VMbus. (jump)
- VMware using Advanced Configuration Parameters available on vSphere and ESXi. (jump)
What can we set during bootstrapping?
All of the Cloud and Virtual platforms can set:
- Initial profile
- Initial settings
- Network DNS settings
- Network device name
- Auto Commission Token
Configuring Initial Settings and Services for a Virtual Canary
Initial settings is a json block that has been base64 encoded. If you were to configure the Canary to boot with the FTP service enabled.
You would need to convert the following json:
{"ftp.banner": "Test FTP banner", "ftp.enabled": True, "ftp.port": 21}Using Linux/MacOS
- echo -n '{"ftp.banner": "Test FTP banner", "ftp.enabled": true, "ftp.port": 21}' | base64
Using Windows
- [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes('{"ftp.banner": "Test FTP banner", "ftp.enabled": true, "ftp.port": 21}'))
into base64:
eyJmdHAuYmFubmVyIjogIlRlc3QgRlRQIGJhbm5lciIsICJmdHAuZW5hYmxlZCI6IFRydWUsICJmdHAucG9ydCI6IDIxfQ==The VMware birds can also set:
- Network IP and netmask
- DHCP enabled or disabled
AWS, GCP and OCI Canaries
AWS, GCP and OCI make use of Cloud init directives and require the '#cloud-config' line at the top of the file to work correctly.
#cloud-config
canary_cloud_init:
autocommission_token: 87b543236c5054706218
initial_profile: oracle-linux-8
initial_settings: eyJmdHAuYmFubmVyIjogIlRlc3QgRlRQIGJhbm5lciIsICJmdHAuZW5hYmxlZCI6IHRydWUsICJmdHAucG9ydCI6IDIxfQ==
network:
custom_dns: true
dns1: 1.1.1.1
dns2: 8.8.8.8
name: test-cloud-initwhere the initial settings is a base64 encoded string for the settings json block defined as
{
"ftp.banner": "Test FTP banner",
"ftp.enabled": True,
"ftp.port": 21
}Launching a new AWS Canary with user-data
Using the AWS CLI the user-data can easily be added on by using '--user-data' parameter
For example:
aws ec2 run-instances --image-id <ami-id> --subnet-id <subnet-id> --security-group-ids <security-group-id> --region eu-west-1 --instance-type t3.micro --user-data file://canary_cloud_init.yamlLaunching a new GCP Canary with user-data
Using the GCP CLI the user-data can be configure using the '--metadata-from-file' parameter.
For example:
gcloud compute instances create DevOpsStaging-1A --machine-type=e2-micro --image=<image-name> --zone=europe-west4-a --network-interface subnet=<subnet-name> --metadata-from-file user-data=canary_cloud_init.yamlLaunching a new OCI Canary with user-data
User-data can be defined under the Advanced options section of the OCI new VM UI.
For example:
Azure Canaries
Azure Canaries are configured using a json formatted user-data file:
{
"autocommission_token": "87b543236c5054706218",
"initial_profile": "oracle-linux-8",
"initial_settings": "eyJmdHAuYmFubmVyIjogIlRlc3QgRlRQIGJhbm5lciIsICJmdHAuZW5hYmxlZCI6IHRydWUsICJmdHAucG9ydCI6IDIxfQ==",
"network": {
"name": "test-cloud-init",
"custom_dns": true,
"dns1": "1.1.1.1",
"dns2": "8.8.8.8"
}
}where the initial settings is a base64 encoded string for the settings json block defined as
{
"ftp.banner": "Test FTP banner",
"ftp.enabled": True,
"ftp.port": 21
}Launching a new Azure Canary with user-data
Using the Azure CLI the user-data can be configure using the '--user-data' parameter.
For example:
az vm create --name DevOpsStaging-1A --resource-group <resource-group-name> --image <image-name> --vnet-name <vmnet-name> --nsg <network-security-group-name> --subnet <subnet-name> --user-data canary_cloud_init.jsonHyper-V Canaries
Hyper-V Canaries require the whole file to be a base64 encoded string
eyJhdXRvY29tbWlzc2lvbl90b2tlbiI6ICI4N2I1NDMyMzZjNTA1NDcwNjIxOCIsICJpbml0aWFsX3Byb2ZpbGUiOiAib3JhY2xlLWxpbnV4LTgiLCAiaW5pdGlhbF9zZXR0aW5ncyI6ICJleUptZEhBdVltRnVibVZ5SWpvZ0lsUmxjM1FnUmxSUUlHSmhibTVsY2lJc0lDSm1kSEF1Wlc1aFlteGxaQ0k2SUhSeWRXVXNJQ0ptZEhBdWNHOXlkQ0k2SURJeGZRPT0iLCAibmV0d29yayI6IHsibmFtZSI6ICJ0ZXN0LWNsb3VkLWluaXQiLCAiY3VzdG9tX2RucyI6IHRydWUsICJkbnMxIjogIjEuMS4xLjEiLCAiZG5zMiI6ICI4LjguOC44In19with the config being defined as
{
"autocommission_token": "87b543236c5054706218",
"initial_profile": "oracle-linux-8",
"initial_settings": "eyJmdHAuYmFubmVyIjogIlRlc3QgRlRQIGJhbm5lciIsICJmdHAuZW5hYmxlZCI6IHRydWUsICJmdHAucG9ydCI6IDIxfQ==",
"network": {
"name": "test-cloud-init",
"custom_dns": true,
"dns1": "1.1.1.1",
"dns2": "8.8.8.8"
}
}where the initial settings is a base64 encoded string for the settings json block defined as
{
"ftp.banner": "Test FTP banner",
"ftp.enabled": True,
"ftp.port": 21
}Launching a new Hyper-V Canary with user-data
The Hyper-V Canary expects the key of the KVP to be 'UserData'
Do not power on your Canary before configuring the KVP parameters.
The KVP information can be set using a powershell script for example:
# Define variables for the VM name, key, and data
vmName = "DevOpsStaging-1A"
keyName = "UserData"
keyData = "eyJhdXRvY29tbWlzc2lvbl90b2tlbiI6ICI4N2I1NDMyMzZjNTA1NDcwNjIxOCIsICJpbml0aWFsX3Byb2ZpbGUiOiAib3JhY2xlLWxpbnV4LTgiLCAiaW5pdGlhbF9zZXR0aW5ncyI6ICJleUptZEhBdVltRnVibVZ5SWpvZ0lsUmxjM1FnUmxSUUlHSmhibTVsY2lJc0lDSm1kSEF1Wlc1aFlteGxaQ0k2SUhSeWRXVXNJQ0ptZEhBdWNHOXlkQ0k2SURJeGZRPT0iLCAibmV0d29yayI6IHsibmFtZSI6ICJ0ZXN0LWNsb3VkLWluaXQiLCAiY3VzdG9tX2RucyI6IHRydWUsICJkbnMxIjogIjEuMS4xLjEiLCAiZG5zMiI6ICI4LjguOC44In19"
# Get the Virtual System Management Service
VmMgmt = Get-WmiObject -Namespace root\virtualization\v2 -Class Msvm_VirtualSystemManagementService
# Get the VM object by its name
vm = Get-WmiObject -Namespace root\virtualization\v2 -Class Msvm_ComputerSystem -Filter "ElementName='$vmName'"
# Create an instance of the KVP Exchange Data Item
kvpDataItem = ([WMIClass][String]::Format("\\{0}\{1}:{2}", `
$VmMgmt.ClassPath.Server, `
$VmMgmt.ClassPath.NamespacePath, `
"Msvm_KvpExchangeDataItem")).CreateInstance()
# Set the key-value pair
kvpDataItem.Name = $keyName
kvpDataItem.Data = $keyData
kvpDataItem.Source = 0 # Source 0 indicates that the data is from the host to the guest
# Add the KVP to the VM
VmMgmt.AddKvpItems($vm, $kvpDataItem.PSBase.GetText(1))
# Output the data being set
Write-Output "Key Name: $($kvpDataItem.Name)"
Write-Output "Key Data: $($kvpDataItem.Data)"VMware Canaries
See the dedicated article for
- Customising VMware Canaries on Deployment using vSphere
- Customising VMware Canaries on Deployment using ESXi
OpenStack Canaries
OpenStack Canaries are configured with a JSON-formatted settings object.
{
"autocommission_token": "123456789abcdef12345",
"initial_profile": "oracle-linux-8",
"initial_settings": "eyJmdHAuYmFubmVyIjogIlRlc3QgRlRQIGJhbm5lciIsICJmdHAuZW5hYmxlZCI6IHRydWUsICJmdHAucG9ydCI6IDIxfQ==",
"network": {
"name": "test-cloud-init",
"custom_dns": true,
"dns1": "1.1.1.1",
"dns2": "8.8.8.8"
}
}where the initial settings is a base64 encoded string for the settings json block defined as
{
"ftp.banner": "Test FTP banner",
"ftp.enabled": True,
"ftp.port": 21
}Add the JSON-formatted settings object to the instance before launching it by navigating to the Configuration section and then pasting the object into the Customisation Script textarea.
Nutanix Canaries
Nutanix makes use of Cloud init directives and requires the '#cloud-config' line at the top of the file to work correctly.
#cloud-config
canary_cloud_init:
autocommission_token: 123456789abcdef12345
initial_profile: oracle-linux-8
initial_settings: eyJmdHAuYmFubmVyIjogIlRlc3QgRlRQIGJhbm5lciIsICJmdHAuZW5hYmxlZCI6IHRydWUsICJmdHAucG9ydCI6IDIxfQ==
network:
custom_dns: true
dns1: 1.1.1.1
dns2: 8.8.8.8
name: test-cloud-initwhere the initial settings is a base64 encoded string for the settings json block defined as
{
"ftp.banner": "Test FTP banner",
"ftp.enabled": True,
"ftp.port": 21
}Nutanix Canaries can also be launched with static IPs as shown in the example below.
#cloud-config
canary_cloud_init:
network:
dhcp_enabled: false
dns1: 1.1.1.1
dns2: 8.8.8.8
ip_address: 192.168.0.10
netmask: 255.255.255.0
gw: 192.168.0.1
name: test-cloud-initThe settings shown above should be added when creating the VM by scrolling down to the Custom Script checkbox and ticking it. Select Type or Paste Script and paste the script into the textarea before saving the VM.