Skill Level: Beginner

In this recipe you could see an example on how to configure Block Storage in IBM Cloud for Ubuntu Linux 16.04 LTS with iSCSI and encrypt the partition using LUKS with encryption keys managed in IBM Key Protect.


 Major building blocks

  • Configuring Block Storage in IBM Cloud used by a Virtual Machine based on Ubuntu Linux 16.04 LTS
  • Mounting IBM Cloud Block Storage with multi-path tools
  • Encrypting the block device with LUKS using enveloped Data Encryption Keys from IBM Key Protect.
  • Using the IBM IAM Token API and IBM Cloud Key Protect API


The IBM Cloud Block Storage Device will be configured as iSCSI configuration using multi-path tools in Ubuntu. The configuration and principle is described in the following guides:

Mounting Block Storage in IBM Cloud
Configuration of iSCSI in Ubuntu Linux

Once properly configured the Block Storage Device will be used to create a partition table and partition to be accessible by the Operating System. In IBM Key Protect a Customer-managed root key is defined, root keys could never leave the HSM Box behind the service. With this root Key a Data Encryption Key DEK is created via API Call. This unwrapped DEK is passed to cryptsetup luksFormat to create an Encrypted LUKS Partition. The DEK is also returned as wrapped DEK which could only be unwrapped by the Root Key stored in Key Protect and the call to the Keyprotect API. This wrapped DEK is stored on the Filesystem in a text file. After the encrypted partition is created a normal EXTFS4 Partition is created into that partition. To mount the enycrypted partition we need the unwrapped key data for an API Call to unwrap (decrypt) the DEK with the root key. The unwrapped Key is passed to cryptsetup luksOpen. This concept is called Envelope Encryption

Detailed Prerequisites

  • Full IBM Cloud account with IaaS permission to provision block storage and virtual machines.
  • An existing Virtual Machine with Ubuntu Linux 16.04 LTS in the IBM Cloud accessible via ssh with public and private network connection. For this example a small machine is enough.
  • basic Linux shell scripting


This is a Proof-of-Concept and should not to be used as a full production example without further hardening of the code:

  • use compiled code instead of a shell script
  • IAM Service Id API key should be passed with password input or store API Key outside in your CI/CD automation and pass as parameter to the script
  • clear the memory after the unwrapped DEK is passed to cryptsetup luksOpen
  • rotate Root Keys often
  • eventually use code obfuscation techniques
  • use a regular cron job to track the state of the Customer managed root key, once deleted the volume should be instantly unmounted, you could use meta data of Key Protect API to get state information about the key
  • you should regular track access to the keys with IBM Cloud Activity Tracker please check the description of theIntegration¬†and the events Key Protect is generating











  1. Order IBM Block Storage in the IBM Cloud portal

    Order some Block Storage in the same Data Center Location where your VM resides.


  2. Authorize the VM for the Block Storage

    Once you created the Block Storage you could authorize Devices like your VSI with Ubuntu to access the storage.

  3. Acquiring the iSCSI credentials for IBM Block Storage

    On the details Page of the IBM Block Storage you will find the following Information.

    • The target IP Addresses of the iSCSI Provider

    • Username
    • Password
    • Host IQN (iSCSI qualified name)

    Please note down that information for later use.


  4. Configure IBM Key Protect

    Create a new Instance of IBM Key Protect in your IBM Cloud Account and add a new Root Key and note the Root Key Id. Root Keys could never leave the Key Protect Service

    Copy the Root Key Id to the clipboard and save it.

    Create a Service ID and Service ID API Key for the instance:


  5. Configure iSCSI on Linux VM

     Install the required packages in Ubuntu 16.04 LTS

    apt-get update && apt-get install multipath-tools curl jq


    Edit the following 2 Files for the iSCSI Configuration and CHAP Settings, you need the Block Storage credentials

    /etc/iscsi/initiatorname.iscsi InitiatorName=<IQN>

    Restart the required services to make the configuration active.

    systemctl restart iscsid
    systemctl restart open-iscsi

    Do a discovery and a login using one of the IP Addresses retrieved in the Block Storage configuration.

    iscsiadm -m discovery -t sendtargets -p <IP Address>
    iscsiadm -m node --login

     Now the following command should display a dev mapper device pointing to your iSCSI Blockstorage, the GUID will different.

    ls -d /dev/mapper/*


  6. Create Partition on device

    Use fdisk to create a new GPT Partition Table and a new Linux Partition on the Block device.

    fdisk /dev/mapper/3600a098038304749775d4c4e554b7742
    Command (m for help): g
    Created a new GPT disklabel (GUID: CB7582D5-A8F7-4868-BA25-9A721FC15CD2).
    Command (m for help): n
    Partition number (1-128, default 1):
    First sector (2048-209715166, default 2048):
    Last sector, +sectors or +size{K,M,G,T,P} (2048-209715166, default 209715166):
    Created a new partition 1 of type 'Linux filesystem' and of size 100 GiB.
    Command (m for help): w
    The partition table has been altered.
    Calling ioctl() to re-read partition table.
    Re-reading the partition table failed.: Invalid argument
    The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8).

     Reread the partition Table:

    kpartx /dev/mapper/3600a098038304749775d4c4e554b7742
    3600a098038304749775d4c4e554b7742p1 : 0 209713119 /dev/mapper/3600a098038304749775d4c4e554b7742 2048

    Verify the Partition:

    fdisk -l /dev/mapper/3600a098038304749775d4c4e554b7742
    3600a098038304749775d4c4e554b7742p1 : 0 209713119 /dev/mapper/3600a098038304749775d4c4e554b7742 2048
    root@vm-luks:~# fdisk -l /dev/mapper/3600a098038304749775d4c4e554b7742
    Disk /dev/mapper/3600a098038304749775d4c4e554b7742: 100 GiB, 107374182400 bytes, 209715200 sectors
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 4096 bytes
    I/O size (minimum/optimal): 4096 bytes / 65536 bytes
    Disklabel type: gpt
    Disk identifier: CB7582D5-A8F7-4868-BA25-9A721FC15CD2

    Device Start End Sectors Size Type
    /dev/mapper/3600a098038304749775d4c4e554b7742-part1 2048 209715166 209713119 100G Linux filesystem
  7. Create, mount and umount encrypted LUKS Partition

    The whole magic is in simple shell script. Copy the scriptfile byok-block-final.sh and env.txt.template from the Github Repository to your Linux VM in the same directory. This shell script contains some functions to:

    • get an IAM Token
    • get an wrapped DEK and the DEK for LUKS commands via Key Protect API
    • encrypting the partition with LUKS and the DEK
    • create encrypted partition, mount, umount, delete Operations on the encrypted block device
    • test function to test IAM Token and Keyprotect API

    Rename env.txt.template to env.txt. In order to use the script you need to adopt some values in the env.txt file:

    # your dev mapper block device partition of the ISCSI Device
    # mount dir for encrypted FS
    # dev mapper name of encrypted fs /dev/mapper/byok
    # your IAM Service ID API Key (sensitive data)
    # your IAM Endpoint depends on IBM Cloud region
    # your instance id of Key Protect Service ibmcloud service
    # ibmcloud resource service-instance <YOUR Key Protect Instance Name> --id
    # second string:
    # Your Key Protect Root Key Id
    # Your Keyprotect API Key Endpoint
    # Filenname of wrapped Data Encryption Key


    Make the script executable

    chmod +x byok-block-final.sh



  8. Create the encrypted partition

    Now we can create an encrypted partition:

    ./byok-block-final.sh create
    Writing superblocks and filesystem accounting information: done

    This will create an encrypted partition and store the wrapped Data Encryption Key in cipherfile.txt.


  9. Mount the encrypted partition

    The next action is to mount the encrypted partition

    ./byok-block-final.sh mount
    # if your mount path is data you should see a lost+found dir, this is the encrypted LUKS partition
    ls /data/
    # you should be able to write some file
    echo "Hello World" > /data/hello.txt"
  10. Unmount the encrypted partition

    The next action is to umount the encrypted partition, after that you should not see the lost+found dir anymore.

    ./byok-block-final.sh umount
    # if your mount path is data you should see a lost+found dir, this is the encrypted LUKS partition
    ls /data/
  11. Enhancements

    Examine the script. Implement some enhancements like Root Key Rotation.

Join The Discussion