Using SmartKey for block storage encryption on Linux servers

Updated: January 29th, 2018

Overview

Following instructions can be used to encrypt block devices using SmartKey on cloud (Amazon AWS, Microsoft Azure, Google GCE) or local Linux instances. You can manage key permissions, view audit log and disable keys anytime through our REST APIs or web interface.

Create a SmartKey account

Create an account on SmartKey. Create an SmartKey app and an app group for your target application. This creates a unique API_KEY for the app which will later be used to authenticate with SmartKey.

ec-created

Import your secret/key into SmartKey

Base64 encode your passphrase/key and import it in your app group as a security object.

$ echo "MyEncryptedKey" | base64
RUMyRW5jcnlwdGVkS2V5Cg==

This import will be assigned a UUID (KEY_UUID) to uniquely identify the passphrase. You can use the SmartKey web app or REST APIs to import a key (more examples in SmartKey SDK)

#!/bin/bash

#example run  ./sdkm_script.sh KeyName bXlwYXNzd29yZAo=

# API ENDPOINT

API_ENDPOINT=https://www.smartkey.io

#API_KEY for your APP
api_key=NjdkNmRkYmEtYmMwMy00ODFhLWIwMTMtYWY1N2...

# log in app
log_in_app() {
curl -s -X POST -H "Content-Type: application/json" -H "Authorization: Basic $api_key" -d '' "$API_ENDPOINT/sys/v1/session/auth" \
| sed -e 's/[{}]/''/g' | awk -v RS=',"' -F: '/^access_token/ {print $2}' | tr -d \"
}

# get your secret passphrase
get_secret() {
secret=`curl -s -X GET -H "Authorization: Bearer $app_bearer_token" \
"$API_ENDPOINT/crypto/v1/keys/${key_uuid}/export" \
| sed -e 's/[{}]/''/g' | awk -v RS=',"' -F: '/^value/ {print $2 "\n" }' \
| tr -d \" | base64 --decode`
}

# generate secret key
create_secret() {
#json_params='{"alg": "'$alg'", "cipher": "'$cipher'", "mode": "'$mode'", "iv":"'$iv'" }'
json_params='{"name": "'$1'", "description": "Ec2 Encryp", "obj_type": "SECRET", "value": "'$2'","enabled": true}'
key_resp=`curl -s -X PUT -H "Authorization: Bearer ${app_bearer_token}" -d \
"${json_params}" "${API_ENDPOINT}/crypto/v1/keys"`

echo "SmartKey Key generation request response:"
echo $key_resp
key_uuid=`echo $key_resp | jq ".kid" | tr -d \"`
}

if [ $# -lt 2 ]; then
echo "./usage Kyename Base64keyvalue"
exit 1
fi

# get session token
app_bearer_token=$(log_in_app)
echo "Session token"
echo $app_bearer_token

create_secret $1 $2 $3 key_uuid
echo "New Key UUDID"
echo $key_uuid

echo "get secret"
get_secret $key_uuid secret
echo $secret

ec-created

Customize your deployment script

Note down the API_KEY and KEY_UUID for the secret you created and update . We tested this script on Ubuntu 16.04 LTS server image which have cryptsetup package installed. Please install cryptset on your Linux servers.

#!/bin/bash

## Initial setup to be executed on boot
##====================================

# Create an empty file. This file will be used to host the file system.
# In this example we create a 2 GB file called secretfs (Secret File System).
dd of=secretfs bs=1G count=0 seek=2
# Lock down normal access to the file.
chmod 600 secretfs
# Associate a loopback device with the file.
losetup /dev/loop0 secretfs



API_ENDPOINT=https://www.smartkey.io

## Copy paste your api_key and uuid here.

api_key=NjdkNmRkYmEtYmMwMy00ODFhLWIwMTMtYWY1N2UyMGUxOWVjOnRqUWN5VFdfN0ZncHVjVmxmblVGVkppMmRYaGp0OGktWndGM2ZWb3E1Y3BXZ01XS25ldE0tT3ZMRTluTml2SS1SSHlGX3BLQW5GSUhLTUVNUHZXRl
key_uuid=dd61b89c-e761-41ee-a700-4f3e4915f7c9


log_in_app() {
curl -s -X POST -H "Content-Type: application/json" -H "Authorization: Basic $api_key" -d '' "$API_ENDPOINT/sys/v1/session/auth" \
| sed -e 's/[{}]/''/g' | awk -v RS=',"' -F: '/^access_token/ {print $2}' | tr -d \"
}
get_secret() {
LuksClearTextKey=`curl -s -X GET -H "Authorization: Bearer $app_bearer_token" \
"$API_ENDPOINT/crypto/v1/keys/${key_uuid}/export" \
| sed -e 's/[{}]/''/g' | awk -v RS=',"' -F: '/^value/ {print $2 "\n" }' \
| tr -d \" | base64 --decode`
}

# get session token
app_bearer_token=$(log_in_app)
echo $app_bearer_token
get_secret LuksClearTextKey
echo $LuksClearTextKey

# Encrypt storage in the device. cryptsetup will use the Linux
# device mapper to create, in this case, /dev/mapper/secretfs.
# Initialize the volume and set an initial key.
echo "$LuksClearTextKey" | cryptsetup -y luksFormat /dev/loop0
# Open the partition, and create a mapping to /dev/mapper/secretfs.
echo "$LuksClearTextKey" | cryptsetup luksOpen /dev/loop0 secretfs
# Clear the LuksClearTextKey variable because we don't need it anymore.
unset LuksClearTextKey
# Check its status (optional).
cryptsetup status secretfs

This script can be used on Amazon AWS, Azure Compute, Google GCE or as a post-install script inside the Linux environment in your data center.

This solution uses a loop-back device /dev/loop0 but any block device /dev/sd(id) or /dev/xvd(id) attachments is valid use case.

Use the deployment script for block device encryption

Amazon Ec2

For Amazon Ec2 use the above script as input in advance details of EC2 instance launch section and launch the instance.

Microsoft Azure

For Azure compute use the above script as input to custom script for Linux on Azure compute portal or use Azure custom extension cmdline.

You can also and an custom extention from Azure command line, Upload the above script on you web-server or cloud storage as smartkey_azure.sh for this example.

az vm extension set ' --resource-group exttest `
--vm-name exttest ` --name customScript `
--publisher Microsoft.Azure.Extensions `
--settings '{"fileUris": ["https://your-script-server/smartkey_azure.sh"],
"commandToExecute": " sudo sh smartkey_azure.sh"}'
    

Google Compute Engine

For Google Compute Engine the above script is used in the startup script section of the GCE portal or use gcloud start-script cmdline.

gcloud compute instances create example-instance \
    --metadata-from-file startup-script="scripts/smartkey_gcloud.sh"

Verify encryption and mount the block device

Now you can verify and mount the encrypted block device and see the key operation on SmartKey web interface. SmartKey logs all key operations in a tempter proof audit log.

To check the status of the device mapper secretfs and see encryption details:

$cryptsetup status secretfs

To verify the passphrase see the key slot id for encrypted device

$sudo cryptsetup luksDump /dev/loop0

To verify your password works (enter password when prompted):

$cryptsetup luksOpen --test-passphrase --key-slot 0 /dev/loop0 && echo correct

To mount the encrypted block device:

$mkfs.ext4 /dev/mapper/secretfs

$mkdir /mnt/encrypted

$mount /dev/mapper/secretfs /mnt/encrypted

To clean up your secret storage:

$sudo cryptsetup luksClose /dev/mapper/secretfs

$sudo losetup -d /dev/loop0

$rm secretfs