Skip to content

Instantly share code, notes, and snippets.

@salrashid123
Created October 20, 2020 15:32
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save salrashid123/008371c75e303727214c1012939a0ace to your computer and use it in GitHub Desktop.
Save salrashid123/008371c75e303727214c1012939a0ace to your computer and use it in GitHub Desktop.
Create LUKS mount on GCP COS image (direct)

Stage Disk with LUKS (direct)

Procedure to mount a LUKS encrypted device into a Container Optimized OS.

  • Create a disk and attach to a plain VM
  • Create format and mount as LUKS
  • Write file to LUKS mount path
  • Detach disk from VM
  • Create COS VM and attach disk (in this case, as /dev/sdb)
  • Start container with cloud-init and map device /usr/bin/docker run --rm -u 0 --privileged --device /dev/sdb:/dev/sdb --name=mycloudservice docker.io/
  • Mount disk
  • Initialize as LUKS
  • Access file

ref: Mounting CSEK protected disk with LUKS encryption on Google Compute Engine

Create plain VM, Disk

### Create VM
$ gcloud compute  instances create instance-2 \
  --zone=us-central1-a  --no-service-account \
  --no-scopes --image=debian-10-buster-v20201014 \
  --image-project=debian-cloud --boot-disk-size=10GB \
  --boot-disk-type=pd-standard --boot-disk-device-name=instance-2

### Create and attach disk
$ gcloud beta compute disks create luks-direct  --type=pd-standard --size=10GB --zone=us-central1-a

$ gcloud compute instances attach-disk instance-2  --disk luks-direct

Init disk as LUKS

### SSH to VM
$ gcloud compute ssh instance-2

$ export DEBIAN_FRONTEND=noninteractive
$ apt-get update && apt-get install -y cryptsetup

### Check block devices
$ lsblk -a
      NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
      sda       8:0    0   10G  0 disk 
      ├─sda1    8:1    0  9.9G  0 part /
      ├─sda14   8:14   0    3M  0 part 
      └─sda15   8:15   0  124M  0 part /boot/efi
      sdb       8:16   0   10G  0 disk          < Disk

### Init LUKS  /dev/sdb

$ export luks_key=`openssl rand 16 | xxd -p`
$ echo $luks_key
# Static
$ export luks_key=e8e580f16de5d34ba73f66151bd4363a


$ echo  -n $luks_key | cryptsetup luksFormat --type luks1 /dev/sdb -
$ echo  -n $luks_key | cryptsetup luksOpen /dev/sdb my_encrypted_volume -

Mount LUKS

$ mkdir -p /mnt/disks/test-direct
$ mkfs.ext4 /dev/mapper/my_encrypted_volume
$ mount /dev/mapper/my_encrypted_volume /mnt/disks/test-direct


$ lsblk -a
    NAME                  MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
    sda                     8:0    0   10G  0 disk  
    ├─sda1                  8:1    0  9.9G  0 part  /
    ├─sda14                 8:14   0    3M  0 part  
    └─sda15                 8:15   0  124M  0 part  /boot/efi
    sdb                     8:16   0   10G  0 disk                           < Disk
    └─my_encrypted_volume 254:0    0   10G  0 crypt /mnt/disks/test-dir      < LUKS

Create test file onLUKS

### Write file
$ echo fooobar > /mnt/disks/test-direct/a.txt

Unmount, unwind

$ umount /mnt/disks/test-direct
$ cryptsetup luksClose   /dev/mapper/my_encrypted_volume 

$ lsblk -a
    NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
    sda       8:0    0   10G  0 disk 
    ├─sda1    8:1    0  9.9G  0 part /
    ├─sda14   8:14   0    3M  0 part 
    └─sda15   8:15   0  124M  0 part /boot/efi
    sdb       8:16   0   10G  0 disk 

Detach the disk

gcloud compute instances detach-disk instance-2  --disk luks-direct

COS Image

Create COS image with Disk attached

Note image ExecStart mounts device directly

gcloud compute instances create cos-2  \
 --image cos-stable-81-12871-130-0 \
 --image-project cos-cloud \
 --disk=auto-delete=no,boot=no,device-name=sdb,mode=rw,name=luks-direct  \
 --zone us-central1-a --machine-type n1-standard-1  \
 --metadata-from-file user-data=cloud-init.yaml

COS initscript runs container to mount disk and LUKS

Normally the container image would perform the steps contained within /home/cloudservice/luksmount/mount.sh

  • cos-init.yaml:
#cloud-config

users:
- name: cloudservice
  uid: 2000

write_files:
- path: /home/cloudservice/luksmount/mount.sh
  permissions: 0644
  owner: root
  content: |
    export DEBIAN_FRONTEND=noninteractive                                                 
    apt-get update && apt-get install -yq cryptsetup

    export luks_key=e8e580f16de5d34ba73f66151bd4363a
    echo  -n $luks_key | cryptsetup luksOpen /dev/sdb my_encrypted_volume -

    mkdir -p /mnt/disks/test-direct
    mount /dev/mapper/my_encrypted_volume /mnt/disks/test-direct  

    sleep 10000  
  
- path: /etc/systemd/system/cloudservice.service
  permissions: 0644
  owner: root
  content: |
    [Unit]
    Description=Start a simple docker container
    Wants=gcr-online.target
    After=gcr-online.target

    [Service]
    Environment="HOME=/home/cloudservice"
    ExecStartPre=/usr/bin/docker-credential-gcr configure-docker
    ExecStart=/usr/bin/docker run --rm -u 0 --privileged --device /dev/sdb:/dev/sdb -v /home/cloudservice/luksmount/:/luksmount --name=mycloudservice docker.io/debian:buster /bin/bash /luksmount/mount.sh
    ExecStop=/usr/bin/docker stop mycloudservice
    ExecStopPost=/usr/bin/docker rm mycloudservice

# bootcmd:
# - iptables -D INPUT -p tcp -m tcp --dport 22 -j ACCEPT
# - systemctl mask --now serial-getty@ttyS0.service

runcmd:
- systemctl daemon-reload
- systemctl start cloudservice.service

Verify

$ gcloud compute ssh cos-1

cos-2 ~ # lsblk -a
    NAME                  MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
    loop0                   7:0    0        0 loop  
    loop1                   7:1    0        0 loop  
    loop2                   7:2    0        0 loop  
    loop3                   7:3    0        0 loop  
    loop4                   7:4    0        0 loop  
    loop5                   7:5    0        0 loop  
    loop6                   7:6    0        0 loop  
    loop7                   7:7    0        0 loop  
    sda                     8:0    0   10G  0 disk  
    |-sda1                  8:1       5.9G  0 part  /mnt/stateful_partition
    |-sda2                  8:2    0   16M  0 part  
    |-sda3                  8:3    0    2G  0 part  
    |-sda4                  8:4    0   16M  0 part  
    |-sda5                  8:5    0    2G  0 part  
    |-sda6                  8:6       512B  0 part  
    |-sda7                  8:7    0  512B  0 part  
    |-sda8                  8:8        16M  0 part  /usr/share/oem
    |-sda9                  8:9    0  512B  0 part  
    |-sda10                 8:10   0  512B  0 part  
    |-sda11                 8:11        8M  0 part  
    `-sda12                 8:12   0   32M  0 part  
    sdb                     8:16   0   10G  0 disk                               <  Disk
    `-my_encrypted_volume 253:1    0   10G  0 crypt                              <  LUKS
    md0                     9:0    0        0 md  


$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
ec33a523ea9a        debian:buster       "/bin/bash /luksmoun…"   About a minute ago   Up About a minute                       mycloudservice

$ docker exec -ti ec33a523ea9a /bin/bash

root@ec33a523ea9a:/# df -kh
    Filesystem                       Size  Used Avail Use% Mounted on
    overlay                          5.7G  262M  5.5G   5% /
    tmpfs                             64M     0   64M   0% /dev
    tmpfs                            1.9G     0  1.9G   0% /sys/fs/cgroup
    shm                               64M     0   64M   0% /dev/shm
    /dev/sda1                        5.7G  262M  5.5G   5% /luksmount
    /dev/mapper/my_encrypted_volume  9.8G   37M  9.3G   1% /mnt/disks/test-direct

root@ec33a523ea9a:/$ cd /mnt/disks/test-direct

root@ec33a523ea9a:/mnt/disks/test-direct$ ls
a.txt  lost+found

root@ec33a523ea9a:/mnt/disks/test-direct$ cat a.txt 
fooobar
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment