In this tutorial, we'll generate SSH secrets that we'll use to connect to our Azure VM via SSH.
Create a template
The first step will be to create a template for VM. You can refer to the "Create a Buckypaper VMs template" tutorial for a better understanding of how to do this.
Create a namespace
The second step will be to create a namespace. This is a mandatory requirement for creating attestation. You can learn how to create and use namespaces in the documentation .
Create dkv-v2 engines
The third step is to create two engines. The first is called "vm-auth", where we'll store the SSH secrets. The second engine is called "buckypaper", where we will store the description key.
VM Auth Buckypaper
POST
http://localhost:8200/v1/sys/mounts/vm-auth
Headers
Body
Response
POST
http://localhost:8200/v1/sys/mounts/buckypaper
Headers
Body
Response
Generate SSH secrets
At this stage, we need to generate SSH secrets. SSH KEY - generation of private and public key. SSH PW - password generation.
Azure AWS
SSH KEY SSH PW
GET
http://localhost:8200/v1/vm-auth/data/:user/ssh-key/:name
We have generated the secrets for the azure user, which will be stored under the name "azureuser ".
Params
Headers
Response
Copy {
"request_id" : "729ee29d-ddf5-58a7-ffe5-8bd61d2b9b46" ,
"lease_id" : "" ,
"renewable" : false ,
"lease_duration" : 0 ,
"data" : {
"data" : {
"private": "LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFBQUFBQkc1dmJtVUFBQUFFYm05dVpRQUFBQUFBQUFBQkFBQUFNd0FBQUF0egpjMmd0WldReU5UVXhPUUFBQUNDd0pDTDdaZmlkanpxUW9EN1BmcXYwbHBpWTFJbTJ3akphbVpKdEFlZUQxUUFBCkFJaW1NYnN4cGpHN01RQUFBQXR6YzJndFpXUXlOVFV4T1FBQUFDQ3dKQ0w3WmZpZGp6cVFvRDdQZnF2MGxwaVkKMUltMndqSmFtWkp0QWVlRDFRQUFBRUN4S3dRNTNFWGN0UGdlUjA1WnRWNmNMcStRSDZBclYrNmw4TmsvMFZhYwpTYkFrSXZ0bCtKMlBPcENnUHM5K3EvU1dtSmpVaWJiQ01scVprbTBCNTRQVkFBQUFBQUVDQXdRRgotLS0tLUVORCBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0K",
"public": "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUxBa0l2dGwrSjJQT3BDZ1BzOStxL1NXbUpqVWliYkNNbHFaa20wQjU0UFYK"
} ,
"metadata" : {
"created_time" : "2024-04-22T07:40:18.023159651Z" ,
"custom_metadata" : null ,
"deletion_time" : "" ,
"destroyed" : false ,
"version" : 1
}
} ,
"wrap_info" : null ,
"warnings" : null ,
"auth" : null
}
GET
http://localhost:8200/v1/vm-auth/data/:user/ssh-pw/:name
We have generated the secrets for the azure user, which will be stored under the name "azureuser ".
Params
Headers
Response
Copy {
"request_id" : "0c47dfbe-b2b7-a764-bd6c-ef8007ed1827" ,
"lease_id" : "" ,
"renewable" : false ,
"lease_duration" : 0 ,
"data" : {
"data" : {
"value" : "H36VDP5D335PJIXNMHSBULJOSJUPZIHVJAIRLFJTTZAAWU3FWTJQ"
} ,
"metadata" : {
"created_time" : "2024-04-22T07:47:08.024377569Z" ,
"custom_metadata" : null ,
"deletion_time" : "" ,
"destroyed" : false ,
"version" : 1
}
} ,
"wrap_info" : null ,
"warnings" : null ,
"auth" : null
}
SSH KEY SSH PW
GET
http://localhost:8200/v1/vm-auth/data/:user/ssh-key/:name
We have generated the secrets for the azure user, which will be stored under the name "azureuser ".
Params
Headers
Response
Copy {
"request_id" : "729ee29d-ddf5-58a7-ffe5-8bd61d2b9b46" ,
"lease_id" : "" ,
"renewable" : false ,
"lease_duration" : 0 ,
"data" : {
"data" : {
"private": "LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFBQUFBQkc1dmJtVUFBQUFFYm05dVpRQUFBQUFBQUFBQkFBQUFNd0FBQUF0egpjMmd0WldReU5UVXhPUUFBQUNDd0pDTDdaZmlkanpxUW9EN1BmcXYwbHBpWTFJbTJ3akphbVpKdEFlZUQxUUFBCkFJaW1NYnN4cGpHN01RQUFBQXR6YzJndFpXUXlOVFV4T1FBQUFDQ3dKQ0w3WmZpZGp6cVFvRDdQZnF2MGxwaVkKMUltMndqSmFtWkp0QWVlRDFRQUFBRUN4S3dRNTNFWGN0UGdlUjA1WnRWNmNMcStRSDZBclYrNmw4TmsvMFZhYwpTYkFrSXZ0bCtKMlBPcENnUHM5K3EvU1dtSmpVaWJiQ01scVprbTBCNTRQVkFBQUFBQUVDQXdRRgotLS0tLUVORCBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0K",
"public": "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUxBa0l2dGwrSjJQT3BDZ1BzOStxL1NXbUpqVWliYkNNbHFaa20wQjU0UFYK"
} ,
"metadata" : {
"created_time" : "2024-04-22T07:40:18.023159651Z" ,
"custom_metadata" : null ,
"deletion_time" : "" ,
"destroyed" : false ,
"version" : 1
}
} ,
"wrap_info" : null ,
"warnings" : null ,
"auth" : null
}
GET
http://localhost:8200/v1/vm-auth/data/:user/ssh-pw/:name
We have generated the secrets for the azure user, which will be stored under the name "azureuser ".
Params
Headers
Response
Copy {
"request_id" : "0c47dfbe-b2b7-a764-bd6c-ef8007ed1827" ,
"lease_id" : "" ,
"renewable" : false ,
"lease_duration" : 0 ,
"data" : {
"data" : {
"value" : "H36VDP5D335PJIXNMHSBULJOSJUPZIHVJAIRLFJTTZAAWU3FWTJQ"
} ,
"metadata" : {
"created_time" : "2024-04-22T07:47:08.024377569Z" ,
"custom_metadata" : null ,
"deletion_time" : "" ,
"destroyed" : false ,
"version" : 1
}
} ,
"wrap_info" : null ,
"warnings" : null ,
"auth" : null
}
Register new workload
POST
http://localhost:8200/v1/auth/ratls/attestation/create
For more detailed information on creating attestation, you can refer to the documentation .
Body
Headers
Response
200
Copy {
"request_id" : "0bde6eee-f55b-e9a5-e1ba-7a382c6a0d50" ,
"lease_id" : "" ,
"renewable" : false ,
"lease_duration" : 0 ,
"data" : {
"instance" : "77255d88-754c-42a3-954f-58fb86bf48a5"
} ,
"wrap_info" : null ,
"warnings" : null ,
"auth" : null
}
Create a VM
Azure AWS
At this stage, we will create an Azure VM from the DC2as_v5 family with the Ubuntu 20_04-lts-cvm operating system version, as it supports confidential VMs.
When creating the VM, you should also include cloud-init. The configuration for cloud-init is shown below.
In the ENCLAVE_FEATURES variable, "method" can be either "ssh-key" or "ssh-pw", "user" is the scope in which the secrets are stored, "secret" is the name under which we store the secret, and "name" is the username to which the keys are added. We need to set which method for SSH connection will be added for the user.
SSH KEY SSH PW
Copy ENCLAIVE_FEATURES=ssh-key:azure:azureuser:root
Copy ENCLAIVE_FEATURES=ssh-pw:azure:azureuser:root
Copy #cloud-config
runcmd:
- |
set -eu
export ENCLAIVE_PROTOCOL=sev-snp
export ENCLAIVE_SOURCE=azure
export ENCLAIVE_INSTANCE=77255d88-754c-42a3-954f-58fb86bf48a5
export ENCLAIVE_RESOURCE=azure-vm
export ENCLAIVE_NITRIDE=http://localhost:8200
export ENCLAIVE_KEYSTORE=http://localhost:8200
export ENCLAIVE_FEATURES=ssh-pw:azure:azureuser:root
if [ -x "$(command -v curl)" ];then
COMMAND="wget -q -O"
elif [ -v "$(command -v wget)" ];then
COMMAND="curl -s -o"
else
echo "Not installed: curl|wget"
exit 1
fi
$COMMAND client "$ENCLAIVE_NITRIDE/static/enclaivelet"
$COMMAND provision "$ENCLAIVE_NITRIDE/static/provision"
chmod +x client provision
./client
echo 'PermitRootLogin yes' | sudo tee -a /etc/ssh/sshd_config
sudo systemctl restart sshd
At this stage, we will create an AWS EC2 from the M6a family with the Ubuntu 23.04 operating system version, as it supports confidential VMs.
When creating the VM, you should also include cloud-init. The configuration for cloud-init is shown below.
In the ENCLAVE_FEATURES variable, "method" can be either "ssh-key" or "ssh-pw", "user" is the scope in which the secrets are stored, "secret" is the name under which we store the secret, and "name" is the username to which the keys are added. We need to set which method for SSH connection will be added for the user.
SSH KEY SSH PW
Copy ENCLAIVE_FEATURES=ssh-key:aws:ec2-user:root
Copy ENCLAIVE_FEATURES=ssh-pw:aws:ec2-user:root
Copy #cloud-config
runcmd:
- |
set -eu
export ENCLAIVE_PROTOCOL=sev-snp
export ENCLAIVE_SOURCE=aws
export ENCLAIVE_INSTANCE=77255d88-754c-42a3-954f-58fb86bf48a5
export ENCLAIVE_RESOURCE=aws-vm
export ENCLAIVE_NITRIDE=http://localhost:8200
export ENCLAIVE_KEYSTORE=http://localhost:8200
export ENCLAIVE_FEATURES=ssh-pw:aws:ec2-user:root
sudo apt-get update -y
sudo apt-get install -y linux-modules-extra-$(uname -r)
sudo modprobe sev-guest
if [ -x "$(command -v curl)" ];then
COMMAND="wget -q -O"
elif [ -v "$(command -v wget)" ];then
COMMAND="curl -s -o"
else
echo "Not installed: curl|wget"
exit 1
fi
$COMMAND client "$ENCLAIVE_NITRIDE/static/enclaivelet"
$COMMAND provision "$ENCLAIVE_NITRIDE/static/provision"
chmod +x client provision
./client
echo 'PermitRootLogin yes' | sudo tee -a /etc/ssh/sshd_config
sudo systemctl restart sshd
Once all the steps have been completed, the result of the attestation will be sent to the webhook you specified when creating the attestation. Below is an example of what is sent to the webhook. Ensure that the webhook accepts the HTTP POST method.
Copy {
"Success" : true ,
"Message" : "success" ,
"Instance" : "77255d88-754c-42a3-954f-58fb86bf48a5" ,
"Resource" : "name" ,
"Quote" : "eyJWZXJzaWlE9PSJ9fQ=="
}
After receiving the attestation result via webhook , we can connect to the VM using the secrets we created earlier.
SSH KEY SSH PW
Copy ssh -i <PATH TO SSH KEY> root@<IP ADDRESS>
Copy ssh root@<IP ADDRESS>