# Howto gpg encrypt your root using udev,cryptsetup,dm-crypt

## dreamshadow

Howto gpg encrypt your root using udev,cryptsetup,dm-crypt 

       Theres lots of documents on using dm-crypt to encrypt your root partition but i couldn't find any using gpg.  So heres how I did it.  Please be gentle, this is my first gentoo howto post.

Thanks to hulk2nd for this post https://forums.gentoo.org/viewtopic.php?t=108162&highlight=encrypted+root

Thanks to veezi for this post https://forums.gentoo.org/viewtopic.php?t=191052&highlight=dmcrypt

Both of these were a great help!

Things to Note:

This is all explain in regards to my setup, yours will differ.

This was all done immediately after a fresh install!

I use lilo instead of grub, so things are explained with lilo

I have done this and it is currently working on my laptop for 3 days now.

Very Important:

You will need a spare partition that can hold the entire contents of your / directory.  

All commands were done with regards to MY setup.

My Setup:

This was done on a Toshiba Tecra 8000, PentiumII, 256M ram, 10G HD.  Heres how i partitioned, yours will be           

different. Note: Im using hda3 as my / and ill be using hda7 as the backup / 

```

        hda1    /boot           ext2    25

        hda2    swap            sw      128

        hda3    /               ext3    2G                                                                     

        hda5    /usr            ext3    4G

        hda6    /usr/portage    ext3    2G

        hda7                    ext3    900M                                                

        hda8    /var            ext3    800M

```

Requirements

You must be using udev!

You will need a LiveCD disk, I'm using Knoppix but the gentoo install disk will work.

I'm using development sources 2.6.10-rc1,  You need the following in your kernel config:

```

             Device Drivers -->

                        Block Devices -->

                                <*> Loopback device support

                                <*>    Cryptoloop Support

                                <*> RAM disk support

                                (8192) Default RAM disk size (kbytes)

                                [*] Initial RAM disk (initrd) support

                                [*] Support for Large Block Devices

                        Multi-device support (RAID and LVM) -->

                                [*] Multiple devices driver support (RAID and LVM)

                                <*> Device mapper support

                                <*>   Crypt target support

                        File systems -->

                                Pseudo filesystems -->

                                        [ ] /dev file system support

                        Cryptographic options -->

                                <*> SHA256 digest algorithm

                                <*> SHA384 and SHA512 digest algorithms

                                <*> AES cypher algorithms (i586)

```

Im using a 8M initrd cause 4M isnt quite enough.

You need the following programs emerged: udev

 hotplug

 coldplug

 device-mapper

 cryptsetup

 gnupg

 sharutils (needed for uuencode)

and on last thing:

```

nano /etc/conf.d/rc

  set RC_DEVICE_TARBALL = no

```

Step 1

Boot from your Live CD.  Were going to make a mirror of your / directory then another backup.

```

        mkdir /{gentoo,newroot}

        mount /dev/hda3 /gentoo

        mke2fs -j /dev/hda7

        mount /dev/hda7 /newroot

        cp -r -p -v /gentoo/* /newroot/

        tar -cjvvf /newroot/root.tar.bz2 /gentoo/*

        mount /dev/hda1 /newroot/boot

        mount /dev/hda5 /newroot/usr

        mount /dev/hda6 /newroot/usr/portage

        mount /dev/hda8 /newroot/var

        mount -o bind /proc /newroot/proc

        chroot /newroot /bin/bash

        env-update

        source /etc/profile

        nano /etc/lilo.conf

```

Heres my new lilo.conf file:

```

        image=/boot/vmlinuz-2.6.10.0

        root=/dev/hda7            (NOT /dev/hda3 LIKE THE ORIGINAL)

        label=wonderland

```

after your done editing lilo.conf run lilo

```

        lilo

        nano /etc/fstab

                change the root=/dev/hda3 to root=/dev/hda7

        exit

        umount /newroot/{boot,usr/portage,usr,var,proc}

        umount /newroot

        umount /gentoo

        reboot

```

If things went as planned your new root should be /dev/hda7 and everything else worked ok.

Step 2

Now were on our new / (/dev/hda7) lets get some stuff installed

```

        mkdir /{rabbithole.rd,rabbithole,root/.gnupg}

        mount /boot

        cd /boot

```

Lets create our gpg key 

```

        head -c 2880 /dev/urandom | uuencode -m - | head -n 65 | \

tail -n 64 |  gpg -ac >/boot/rabbithole.key

```

Lets check the key to make sure it works ok:

```

        gpg --quiet -d /boot/rabbithole.key

```

that should give you a big screen of characters =)

now lets create our RAM disk

```

        cd /root

        touch rabbithole.rd

        dd if=/dev/zero of=/root/rabbithole.rd bs=1024k count=8

        losetup /dev/loop0 /root/rabbithole.rd

        mke2fs /dev/loop0

        mount /dev/loop0 /rabbithole.rd

        cd /rabbithole.rd

        mkdir {bin,boot,dev,etc,lib,proc,rabbithole,root,root/.gnupg,.gnupg}

        cp /boot/rabbithole.key /rabbithole.rd/boot/

        cp /root/.gnupg/* /rabbithole.rd/root/.gnupg/

        cp /root/.gnupg/* /rabbithole.rd/.gnupg/

        touch linuxrc

        chmod +x linuxrc

```

Step 3

Lets populate the rabbithole.rd

```

        cp /bin/{sh,cat,mount,umount,mkdir,chroot,cryptsetup} /rabbithole.rd/bin/

        cp /sbin/{pivot_root,blockdev} /rabbithole.rd/bin/

        cp /usr/bin/gpg /rabbithole.rd/bin/

```

Now to copy the libraries over.  For each file in /rabbithole.rd/bin find its

needed libraries by typing ldd filename, heres and example:

```

        ldd /rabbithole.rd/blockdev

                linux-gate.so.1 => (0xffffe000)

                libc.so.6 => /lib/libc.so.6 (0xb7ece000)

                /lib/ld-linux.so.2 (0xb7f3b000)

```

So blockdev requires libc.so.6, ld-linux.so.2 so copy these over:

```

        cp /lib/libc.so.6 /rabbithole.rd/lib/ 

        cp /lib/ld-linux.so.2 /rabbithole.rd/lib/

```

Now do this for all the other programs in /rabbithole.rd/bin and copy

there needed libraries over.

Step 4

Now lets create the devices on the RAM disk

```

        mknod /rabbithole.rd/dev/console c 5 1

        mknod /rabbithole.rd/dev/null c 1 3

        mknod /rabbithole.rd/dev/hda3 b 3 3

        mknod /rabbithole.rd/dev/tty c 4 0

        mkdir /rabbithole.rd/dev/mapper

        mknod /rabbithole.rd/dev/mapper/control c 10 63

        mknod /rabbithole.rd/dev/random c 1 8

        mknod /rabbithole.rd/dev/urandom c 1 9

```

Step 5

Now lets create the linuxrc  (thanks veezi)

```

        nano /rabbithole.rd/linuxrc

```

The following is what needs to be in the linuxrc

```

#!/bin/sh

export PATH=/bin

#grab the command line:

mount -t proc proc /proc

CMDLINE=`cat /proc/cmdline`

umount /proc

#mount the rabbithole and fall through it:

gpg --quiet -d /boot/rabbithole.key | cryptsetup -h plain -c aes \

-s 256 create rabbithole /dev/hda3

mount /dev/mapper/rabbithole /rabbithole

cd /rabbithole

mkdir potion

pivot_root . potion

#drink the potion and away we go

exec chroot . /bin/sh <<- EOF >dev/console 2>&1

umount potion

rm -rf potion

/sbin/blockdev --flushbufs /dev/ram0

exec /sbin/init ${CMDLINE}

EOF

```

Step 6

Lets check the RAM disk to make sure it works properly

```

        cd /

        chroot /rabbithole.rd /bin/sh

        /bin/blockdev --help

        /bin/cat --help

        /bin/chroot --help

        /bin/cryptsetup --help

        /bin/gpg --help

        /bin/mkdir --help

        /bin/mount --help

        /bin/pivot_root --help

        /bin/sh  --help

        /bin/umount --help

        /bin/gpg --quiet -d /boot/rabbithole.key

        exit

```

If all went good you should see a help screen for each program and your          

gpg should decrypt the key.  If theres missing library's, exit,   

copy them over and try again.  when all is good:

```

        umount /rabbithole.rd

        mount /boot

        cp /root/rabbithole.rd /boot

```

Step 7

Now lets prepare our encrypted root

```

dd if=/dev/zero of=/dev/hda3

gpg --quiet -d /boot/rabbithole.key | cryptsetup -h plain -c aes \

-s 256 create rabbithole /dev/hda3

mke2fs -j /dev/mappper/rabbithole

mount /dev/mapper/rabbithole /rabbithole

cd /rabbithole

tar jxvf /root.tar.bz2

mv gentoo/* ./

rmdir gentoo/lost*

rm gentoo/.bash*

rmdir gentoo

cd /rabbithole/etc/

nano fstab

```

Change the /dev/hda3 to /dev/mapper/rabbithole  so the line will look like this:

```

/dev/mapper/rabbithole  /       ext3    noatime 0 1

```

Now lets prepare lilo:

```
nano /etc/lilo.conf
```

heres what my new lilo looks like (im leaving the old root in there in case

things dont go so well)

```

        image=/boot/vmlinuz-2.6.10.0

                root=/dev/hda7

                read-only

                label=wonderland-bak

        image=/boot/vmlinuz-2.6.10.0

                label=wonderland

                root=/dev/ram0

                read-write

                initrd=/boot/rabbithole.rd

                append="init=linuxrc"

```

and then run lilo:

```
lilo
```

You may get the following error:

```

        Warning: '/proc/partitions' does not match '/dev' directory structure.

                Name change: '/dev/dm-0' -> '/dev/mapper/rabbithole'

```

but thats ok, dont worry about it.

now lets finish things up

```

        cp /etc/lilo.conf /rabbithole/etc/lilo.conf

        losetup -d /dev/loop0

        umount /rabbithole

        umount /boot

        cryptsetup remove rabbithole

```

Thats it, reboot.  You may get an error on shutdown saying theres a

file system error, enter root password. I just ignored this and it restarted as normal. If things went ok you'll be a happy camper.  I have been running this for a while now and it works pretty good.  Havent had any problems.

----------

## S_aIN_t

Sounds like fun. When I get more time to play with Linux I will be sure to try this.

Looks like excellent work. Thanks.

----------

## ali3nx

Just wanted to say thanks! very nice tutorial. I made a few adjustments to my setup to suit my requirements but all is working nicely   :Cool:  Good job.

----------

## mcpi

yep thanx thanx thanx, it works for me. 

ok I found some "errors", but I fixed them all and now it works. great. 

my changes:

important: if you create a hda device which is not hda3 you must modify the device number!

for me: hda6 is my rootpartion, so the command is: mknod /rabbithole.rd/dev/hda6 b 3 6 <------ that was my mistake (i wrote here 3 and that was wrong!)

and there is a mistake in your linuxrc:

exec chroot . /bin/sh <<- EOF > dev/console 2>&1

you should change it to 

exec chroot . /bin/sh <<- EOF > /dev/console 2>&1           (missing a slash "/" at the beginning)

do you know a good way to mount an usb stick or cdrom device into a initrd? background: I just want to put the gpg key to an external device.

thanx for help

----------

## cheops05

Hi, I want to implement this method of encrytion but with a few modifications.

(1). How would you modify this to also encrypt the swap partition and my home partition.

(2).Would it be possible to story the key file on a usb stick?

maybe a better method would be to get the USB stick to boot gentoo i.e boot partion on the SDA stick?

Thanks

cheops.

----------

## dreamshadow

ok a few things,

 to do the swap and /tmp directories look at /etc/conf.d/cryptfs, heres how mine looks:

```
swap=swamp

source='/dev/hda2'

mount=wasteland

source='/dev/hda8'

options='-d /dev/urandom'

pre_mount='/sbin/mke2fs /dev/mapper/wasteland'

post_mount='chown root:root /tmp; chmod 1777 /tmp'

```

and my /etc/fstab for those looks like:

```

/dev/mapper/swamp       none            swap            sw                      0 0  #/dev/hda2

/dev/mapper/wasteland   /tmp            ext2            defaults,noexec         0 0  #/dev/hda

```

that will give you an encrypted swap and and encrypted /tmp directory.

as for other partitions, heres how i did that:

i create a key directory in my /root directory

something like /root/.keys/

i made a key for all other partitions

/root/.keys/usr.key

/root/.keys/var.key

etc etc for each partition.

the command i used  was:

```

head -n 10 /dev/urandom | uuencode -m - | head -n 6 | tail -n 5 > usr.key

```

 this makes a pretty decent random key, and come on, im PaRanOiD, but some one trying to decrypt a gpg key on a gpg encrypted root partition, its going to take a long time.  they have to decrypt the root partition to even get these keys.

then i would encrypt those partitions by backing them up, and device mapping encrypting them like in the howto except this time it would be /usr or /home or whatever partition your working on instead of the root partition.

then all you need to do is write an init script that has the following lines:

```
       

ebegin "Setting up userland..."

cat /root/.keys/usr.key | cryptsetup -h plain -c anubis -s 320 create userland /dev/hda5

eend $?

ebegin "Setting up var..."

cat /root/.keys/var.key | cryptsetup -h plain -c anubis -s 320 create var /dev/hda7

eend $?

```

NOTE: this MUST be run right after /etc/init.d/modules, if you dont know how to do this, just add the above lines at the end or /etc/init.d/modules !!!!

also those files should be chmod 0400  read only by root, same with the directory /root/.keys

ok, i hope that makes sense, if not ask and ill g/et you an answer as soon as possible.

as for putting the key on a usb stick.  i havent had time to actually do it yet, but ill give you a couple things that should set you one the right path:

the kernel must be built with usb support and everything needed to normally read a usb key.

in your initrd, you will need to add the mount point to where the usb key mounts to and the device nodes for the usb device

example, mine usually is /dev/sda  and mounts to /usb so you would need devices for sda, sda1, etc etc depending on how

your usb key is partitioned. and a mount point ( /usb) make sure they have the right mknod settingds like mine mounts to /dev/sda

its a block device with 8, 0  so i woulnd create the following devices in my initrd:

```

mknod /dev/sda b 8 0

mknod /dev/sda1 b 8 1

mknod /dev/sda2 b 8 2

```

you will need to write some code that automatically mounts the usb device or sits and waits for the usb key to be inserted

then change the linuxrc to cat the gpg key off the usb instead of from /boot.  

kinda the same if you want to use a cdrom to store the key

anyways if someone actually gets time and makes this work, please post how you did it, and ill help anyone that needs help, just gotta

give me some time to respond, its final month of my senior year =|

quick bonus:  encrypted /home directoy

heres how i do mine

each user has a usb key with there encrypted home parition on it.

i have edited udev to do custom dev mapping depending on the serial number of the usb key

for example, johndoe has his usb key. when its put in udev make a link to /dev/johndoe

so then i have a init script that does the mounting of the home partition

NOTE: the following script will delete your initrd file if you fail it 3 times, to prevent this please read over it carefully and if testing

comment out the rm /boot/rabbithole.rd and shutdown -h 0 lines, YOU HAVE BEEN WARNED

now heres the code for /etc/init.d/crypt-home

```

#!/sbin/runscript

#coded by dreamshadow@futilesystems.net

#

depend() {

 after vixie-cron

}

check_vault() {

 thecheck="no"

 if [ -e /dev/johndoe ]; then

  thecheck="johndoe"

 fi

}

check_user() {

 case $thecheck in

  "johndoe")

   einfo "     Found user vault"

   cryptsetup -h sha1 -c anubis -s 320 create vault /dev/johndoe

   e2fsck /dev/mapper/vault

   mount /dev/mapper/vault /home/johndoe

   echo "0" > /etc/conf.d/homecount

   einfo "     Vault Opened"

   ;;

  "no")

   if [ "$keyerror" = "yes" ]; then

    key_wait

   else

    do_error

   fi

   ;;

 esac

}

do_error() {

 eerror "     No Vaults Found"

 let homecount=$homecount+1

 echo "$homecount" > /etc/conf.d/homecount

 if [ $homecount -eq 2 ]; then

  ewarn "     Unauthorized Access Attempt Detected"

  ewarn "     System will auto-erase on one more failure"      

  sleep 5

  shutdown -h 0

 elif [ $homecount -ge 3 ]; then

  mount /boot

  rm /boot/rabbithole.rd

  ewarn "     Unauthorized Access Detected........."

  ewarn "     Destroying the filesystem....YOU *&^(^&*!!!!!!!"

  shutdown -h 0

 else

  key_wait

 fi

}

key_wait() {

 let keycount=$keycount+1

 if [ $keycount -eq 1 ]; then

  eerror "     Please insert User Vault"

  sleep 10

  keyerror="yes"

  check_vault

  check_user

 elif [ $keycount -eq 2 ]; then

  eerror "          20 seconds remaining."

  sleep 10

  keyerror="yes"

  check_vault

  check_user

 elif [ $keycount -eq 3 ]; then

  eerror "          10 seconds remaining."

  sleep 10

  check_vault

  check_user

  shutdown -h 0

 fi

}

start() {

 ebegin "Checking for Vaults"

  if [ -e /etc/conf.d/homecount ]; then 

   homecount="$(cat /etc/conf.d/homecount)"

  else

   homecount=0

  fi

  keyerror="no"

  keycount=0

  check_vault

  check_user

 eend $?

}

stop() {

 ebegin "Closing the vault"

  if [ -e /dev/johndoe ]; then

   umount /home/johndoe >/dev/null 2>&1

  fi

  einfo "     The vault is closed"

  cryptsetup remove vault

 eend $?

}

```

ok, so with the above script a user just plugs there usb key during the boot and the script will run, ask for a password, mount the users

directory and walla, everythings encrypted on a portable usb key.  and yes it does work, ive been using it for over a couple months now.

----------

## cheops05

Thanks for all the new info it is just what I was looking for.

I will be trying all this new stuff soon as I sort out a problem with the encrypting root howto maybe you can help?

I have a problem with the boot up sequence everything works I can mount the encryted partition manually and see all my encryted partition when using the backup image but soon as I try and boot the encrypted partition

I get this error

```

Remounting  root filesystem read-only (if necessary)...

Checking root filesystem.

Failed to open the device '/dev/mapper/rabbithole': No Such file or directory.

```

My initrd is working fine it loads up with no errors I did have a few problems but managed to sort them out, I have read somewhere that people were having to put /bin/sleep 5 to wait for udev to catch up in the /etc/init.d/check* startup scripts which I have tried but it doesnt seem to make a difference.

I am at a total loss with what else to try if anyone can think of anything that could be causing this then it would be greatly appreciated. I know it can't be far off working now.  :Neutral: 

Thanks

Cheops

----------

## dreamshadow

couple things to check just off the top of my head

if you using lilo, you must have read-write in there instead of read-only.

```

image=/boot/vmlinuz-2.6.10.0

        label=nowhere

        read-write

```

same thing for grub.

is your initrd an ext2 filesystem, ext3 or others wont work, i dont know why

but thats all i can give you for now, ill check my notes when i make it home later today.

----------

## cheops05

Thanks

I finally got it working i needed to emerge the latest baselayout?

you might want to add it to your howto

Cheops

----------

## dreamshadow

cool, wonder why putting in the latest baselayout worked.  hmmm anyways now that you have it running, can you think of anything to make it a little more secure other than moving the gpg key to like a cd or usb disk.  i mean the encryption (depending on what you used) is  pretty good, ive tried to think of different ways that it could be bypassed, but it all boils down to the gpg key to decrypt the root parition.  which reminds me, this encryption method does do filechecking, so ive found that every 15-20th boot, its always nice to do a 

```

touch /forcefsck

```

this way it keeps the filesystem clean and the encryption doesnt get screwed.  i have killed my system a time or two from forgetting the password, and believe me, if you dont have a copy of that gpg key, your hard drive is screwed.  but if you have ideas of improvements and stuff please let me know.

----------

## ProtectionFault

Great howto...  :Smile: 

There was only a problem with the device numbers for the /dev/mapper/control device (had to use 10 61 instead of 10 63)

You may look up your device number with a 

```
cat /proc/devices
```

for the major number and a

```
cat /proc/misc
```

for the minor number.

If you want your filesystem to be automatically checked and you're using ext2/3, you may have a look at

```
man tune2fs
```

----------

## cheops05

Yeah I forgot to mention mknod thing.

Anyway I now have this booting from my USB Flash Drive My \boot partition now resides on the drive an when I stick it in it boots to gentoo otherwise cr**py windows...so my drive probably looks like junk

Cheops

----------

## Base

Hmm dm-crypt was patched with ESSIV for security increase earlier. does this guide make essiv unneccesary? since u dont seem to use it i mean

----------

## smv

This is a great tutorial!  I'm trying this out using VMWare on a fresh install.

The section for creating the devices has an incorrect major number for the tty device:

```
mknod /rabbithole.rd/dev/tty c 4 0
```

should be:

```
mknod /rabbithole.rd/dev/tty c 5 0
```

This results in having gpg sit there with no prompt for the passphrase.

----------

## pulzed

Nice tutorial! I'm trying to get this to work on my laptop...

lilo.conf

```
boot=/dev/hda

   default=gentoo

   prompt

   image=/boot/kernel-gentoo-sources-2.6.11-r11_050626

      label=gentoo

      root=/dev/ram0

      read-write

      initrd=/boot/rabbithole.rd

      append="init=linuxrc"

   image=/boot/kernel-gentoo-sources-2.6.11-r11_050626

      label=gentoo-bak

      read-only

      root=/dev/hda1

```

Running 'lilo' gives this output:

```
Warning: The initial RAM disk is too big to fit between the kernel and 

   the 15M-16M memory hole. It will be loaded in the highest memory as 

   though the configuration file specified "large-memory" and it will 

   be assumed that the BIOS supports memory moves above 16M.

Added gentoo ? *

Added gentoo-bak

```

Boot hangs on this error:

```
...

...

...

RAMDISK: ext2 filesystem found at block 0

RAMDISK: Loading 8192KiB [1 disk] into ram disk... done.

VFS: Mounted root (ext2 filesystem)

Freeing unused kernel memory: 252k freed

Kernel panic - not syncing: No init found.   Try passing init= option to kernel.

```

Any ideas howto fix this? Thanks!

Edit: I made a few errors and corrected them, and now it works like a charm  :Very Happy: 

----------

## dreamshadow

um, i had that same memory thing too when i first experimenting with this

my solution, although it may not work for you

in my bios i have the ability to turn off that memory hole so its not there.

if your bios allows this id get rid of it, i mean, do you really need that memory 

hole there on your laptop?

but thats just a suggestion, if that doesnt work i dont know what to tell you.

its been a while since ive gone through this doc and added improvements and

stuff ive made to it.

anyone else that has this working have any ideas?

----------

## escitalopram

Moving from linux-2.6.10 to linux-2.6.12.2 breaks my encrypted root fs ;(

I have compiled in dm-crypt as well as every cypher coming with linux-2.6.12.2; I even tried to recompile cryptsetup, but it doesn't work.

I can't cite the exact error message, but when I run cryptsetup with -v it says something like that:

"ioctl 0 is invalid for /dev/mapper/control"

and it doesn't even ask for a password

----------

## rajl

I had a similar problem upgrading from 2.6.8 to 2.6.9 kernel awhile ago.  Once I can figure out how to upgrade kernel's without seeing my encrypted partitions get nuked, I'll try doing it again.

----------

## pulzed

Is it possible to store the kernel and ramdisk on a bootable cdrom instead of boot partition? Anyone tried something like this?

----------

## Moriah

Regarding:

```
I can't cite the exact error message, but when I run cryptsetup with -v it says something like that:

"ioctl 0 is invalid for /dev/mapper/control"

and it doesn't even ask for a password
```

Please see the bugzilla bug report I just submitted today on a very similar problem: Bug 107680

The solution is not yet forthcoming, but the workaround I used is described in the bug report.    :Very Happy: 

----------

