SECURITY FileSystem Encryption without ROOT
From Gentoo Linux Wiki
| Installation • Kernel & Hardware • Networks • Portage • Software • System • X Server • Gaming • Non-x86 • Emulators • Misc |
Please format this article according to the guidelines and Wikification suggestions, then remove this notice {{Wikify}} from the article
[edit] Introduction
There currently exist a lot of HOWTO's out there that explain how to encrypt partitions, including the ROOT partition. So why am I writing this HOWTO?
- I have done the root filesystem encryption and I don't really like it. Why?
- I have had updates break the encryption process I was using.
- Everytime you build a kernel, update a module, you have to potentially generate a new initramfs image. This is a repetitive task that is a definite accident waiting to happen. I know, it happened to me and all the steps required to get the system back in working order are annoying.
Initially I was using loop-aes, with the encryption process described in (** place link here **) which worked great on my last notebook.
When it died, I obviously tried the same process on my new notebook. It didn't work!!
After 2 or 3 days of struggle, I finally found out, far as I can tell, that the standard GENTOO 2.6.12 kernel no longer directly supports initrd images, you have to use initramfs.
After having spent another 2 or 3 days trying to figure out what initramfs was and how to build an image, with no success, I finally gave up on the encryption scheme (I even tried building by hand the image generated by genkernel, using the files genkernel created, and it wouldn't even boot).
I still haven't figured out initramfs, so I'm using the genkernel to generate the images, but since this notebook is my life, I couldn't live without encryption. I finally found a link SECURITY System Encryption DM-Crypt with LUKS (which is also my main source of inspiration for writing this HOWTO), which showed another process to encrypt the root.
After having encrypted all of my partitions, and when I was trying to figure out how I was going to build the initramfs image (I was planning on modifying the *.cpio.gz file genkernel uses, before it created the image) is when I realized that, considering my current partition scheme, there was really no need to encrypt the root partition, since it had basically nothing that could be considered a security risk.
Basically, encrypting the ROOT partition is a non-standard process. What do I mean by non-standard? By non-standard I mean that root file system encryption is not normally supported by the various distros out there including GENTOO. By support, I mean a feature that can be used without having to step out of the standard configuration files, or modify the basic required system files (init.d, conf.d, etc) by hand.
If you're curious about ROOT File System encryption, I have included a set of reference links which all of them describing an approach that can be taken to encrypt the ROOT filesystem and the required changes for it to work correctly.
So what is our objective?
- To encrypt all the partitions (filesystems) on our hard drive, without encrypting the root filesystem.
- To create a security level as good (or almost as good) as if we had encrypted the root filesystem.
- To do all of this, without using non-standard methods in the GENTOO System.
[edit] Disclaimer
Basic Rules:
- BACKUP EVERYTHING, before TRYING ANYTHING. If it's important you definitely don't want to lose it.
- Read the MANUAL PAGES for the commands you are going to use, to make sure that I haven't made a mistake.
- BEFORE you hit enter, make sure the commands you type MAKES SENSE.
[edit] Requirements
This Lists not the requirements but my system platform, since I really have not tried this out on any other systems.
- Arch: Intel Pentium 4
- Kernel: GENTOO (gentoo-sources) 2.6.12-r10
- Bootable CD (in case of goof): Gentoo LIVECD (preferred) or Knoppix
[edit] Steps
[edit] Step 1: Preparing the Disks
Follow the steps in the Gentoo HANDBOOK Installation Handbook, UP TO, the chapter on Preparing the DISKS.
The partition scheme I use is:
hdc1 : Windows XP hdc2 : extended partition hdc5 : NTFS (Data Partition) hdc6 : /boot hdc7 : LVM2 Logical Volume (LVM2 Resource Page)
The following scheme, is the PREFERRED scheme that we will be using for the configuration of the system that follows. It is based on my hard drive (you will have to adapt it to your capacity):
hdc1 : Windows XP hdc2 : extended partition hdc5 : NTFS (Data Partition) hdc6 : /boot (512 MB) EXT2 hdc7 : swap (512 MB) hdc8 : / (256 MB) EXT2 hdc9 : /tmp ( 1 GB) EXT2 hdc10 : /usr ( 10 GB) ReiserFS hdc11 : /var ( 5 GB) ReiserFS hdc12 : /opt ( 4 GB) ReiserFS hdc13 : /home ( 15 GB) ReiserFS
which leaves me with 9 GB Free.
Partitions hdc6, hdc9, hdc10, hdc11, hdc12, hdc13 will be mounted onto our root partition at the respective mount poins. Therefore when we mount partition hdc8 under /mnt/gentoo (Step 4e in the Handbook) we will also have to create the mount points in the root filesystem (tmp,usr,var,opt,home) and mount these partitions into there respective mount points, BEFORE you continue with anything else.
[edit] Step 2: Configuring the Kernel
In the chapter on Configuring the Kernel in the Gentoo Handbook, we will need the following extra modules configured.
| Linux Kernel Configuration: Extra modules |
Device Drivers -->
Block Devices -->
Multi-device support (RAID and LVM) --->
CONFIGURE ALL OPTIONS as MODULES "<M>"
Cryptographic options -->
CONFIGURE ALL OPTIONS as BUILTIN "<*>" except Testing module
(you can choose if you want, but it it is better to have everything)
|
[edit] Step 3: Emerging the required modules
This step can be applied as part of the installation, but it is better to wait until you have finished the rest of the installation and have a stable running system.
EMERGE the following packages:
emerge sys-fs/multipath-tools (usefull programs for multipath) emerge sys-fs/cryptsetup-luks (might require ACCEPT_KEYWORDS="~x86" and should USE="-dynamic" see man emerge )
Emerging the cryptsetup-luks, will bring with the GENTOO support for encrypted partitions (i.e. a new file cryptfs will be created under /etc/conf.d to support automatic loading of encrypted partitions during the boot process).
What are the benefits of LUKS over the standard cryptsetup?
- Multiple Passwords per encrypted filesystem.
- Being Able to add/delete/modify a password without having to re-encrypt the partition.
- Potential portability of the encrypted filesystems across platform (see truecrypt.org), even though I haven't tried this.
[edit] Step 4: Considerations
1. Passwords
The 1st thing we have to consider is that, the encryption process requires passwords, and there are 2 basic types of passwords:
- User defined
- Random Generated Password.
In terms of security, random generated password are always best, since there is no possible dictionary attack against them, and the character set used is greater than is normally used for user defined password.
The only problem is that, since they can't be entered by hand, we have to use a key file to store them, which will have to be saved somewhere!
User defined keys, are more user friendly, but considering that we will be encrypting 5 partitions, this implies that we will have to enter this password correctly atleast 5 times. Which makes these passwords very user unfriendly.
2. A single password for all partitions or not?
The next thing we have to consider is that, since we are encrypting each partition individually, are we going to use one master password for all the partitions or one password per partition?
Using only a single password increases the security risk, but using multiple passwords can be more complicated.
Using LUKS partially solves this problem because:
- The master password, the password used to encrypt the file system is always random. The password we choose will only be used to encrypt the master password (which is stored along with the file system on the partition, please see (** add linkhere **)).
- We can have more than one password per partition.
But in reality, the security of the master password is only as good as the security of the password you use to encrypt it!
So how are we going to solve these problems?
If you are like me, you hate entering passwords. So what I wanted was a system in which I wasn't required to enter any passwords at all!
With that in mind, I implemented the following system (I will only describe it here and leave the implementation till later on):
- I bought a USB PenDrive (memory stick, or what ever they are called these days).
- I created a encrypted filesystem on the memory stick.
- I stored the random generated keys, created to encrypt the partitions, on the USB drive.
- I kept the random generated key used to decrypt the USB drive on my root (un-encrypted) partition.
- Modified cryptfs so that it 1st mounts the USB Drive, and then decrypts the rest of the partitions.
This basically creates an interlinked authentication between the PenDrive and the Notebook (without both you can't start the system).
(See Security Considerations Later on for Potential Problems).
[edit] Step 5: Encrypting SWAP and TMP Partitions
We will start the encryption process by "encrypting" the SWAP and TMP partition.
The SWAP partition doesn't contain any real permanent data. The TMP on the other hand does, but like it says it's should only contain temporary information (information that does not have to be maintained between sessions) so we will be treating them basically the same.
All that is required to encrypt these 2 partitions is to modify the cryptfs and fstab files, examples follow.
Changes for the CRYPTFS:
For SWAP:
swap=crypt-swap options='-c serpent -s 256 -h sha1 -d /dev/urandom' source='/dev/hdc7'
For TMP:
target=crypt-tmp
options='-c serpent-cbc-essiv:sha256 -d /dev/urandom'
source='/dev/hdc9'
pre_mount='/sbin/mke2fs ${dev}'
post_mount='chown root:root ${mount_point}; chmod 1777 ${mount_point}'
NOTE: Using -d /dev/urandom does not work with 1.0.4-r3(at least) it will read /dev/urandom till it Seg Faults. I assume you will need to create a key file like the rest of the FSs
These example come directly from the example configurations in the cryptfs file.
You will see from the examples that I am using the SERPENT cypher to encrypt both partitions. Considering the temporary nature of these partitions SERPENT is probably an overkill and you're probrably better off using the faster (but still secure) AES.
Changes for the FSTAB:
/dev/mapper/crypt-swap none swap sw 0 0 /dev/mapper/crypt-tmp /tmp ext2 noatime 0 1
you will notice that the table now refers to the encrypted partitions and not the original devices. That's all that is required to encrypt both the SWAP and TMP.
You should now REBOOT the system to verify that the system is now in fact using the new encrypted partitions.
The mount and swapon -s commands should list the tmp and swap partitions as being mounted on /dev/mapper/crypt-tmp and /dev/mapper/crypt-swap respectively.
[edit] Step 6: Converting Existing Partitions to Encrypted Partitions
What I outline below is actually a TEMPLATE of the steps that are to be applied to encrypt a single partition. This template than has to be applied repeatedly to all the partitions (usr,var,opt,home). I will be using the /usr partition (/dev/hdc10) as the basis for the template.
To begin with, the empty space you should have left on your hard disk, is now needed.
Therefore:
- Using fdisk, create a new partition out of the free space you have left.
- Create a mount point for the new partition (i.e. /mnt/free).
TEMPLATE (we will create the template using the /dev/hdc10 or usr partition):
1. Format and Mount the Free Space
mke2fs /dev/hdc14 mount /dev/hdc14 /mnt/free
2. Copy the partition to be encrypted to /mnt/free, you can use:
cd /usr cp -ax . /mnt/free
OR
cd /usr tar cvpf usr.tar . cd /mnt/free tar xvpf /usr/usr.tar
3. Modify the fstab file, as in the following example: CHANGE
/dev/hdc10 /usr reiserfs noatime,notail 0 1
TO
/dev/hdc14 /usr reiserfs noatime,notail 0 1
4. Reboot the system, so that partition /dev/hdc14 takes the place of the old partition.
5. SHRED the old partition (for security reasons) before using:
shred -n 4 /dev/hdc10
(I overwrote my data with shred 4 times. [25 times, the default, would really take a really long time...]) ESSIV= "encrypted sector salt initial value" By combining the key with a salt that is different for every block of data on disk the known plaintext and watermark attacks become impossible: Identical blocks of data encrypt to different ciphertext due to differing salt values. Note that since ESSIV is not the default DM-Crypt, it is insecure by default, you must explicitly enable ESSIV mode to create a secure encrypted filesystem.
6. Encrypt the file system:
head -c 256 /dev/urandom > /etc/conf.d/usr.key (KEY FILE) cryptsetup -c serpent-cbc-essiv:sha256 luksFormat /dev/hdc10 /etc/conf.d/usr.key (KEY FILE)
modprobe dm_crypt modprobe cryptoloop
7. Create dm (device-map) for the partition:
cryptsetup -c serpent-cbc-essiv:sha256 -d /etc/conf.d/usr.key luksOpen /dev/hdc10 crypt-usr
8. Format and Mount the encrypted file system:
mkreiserfs /dev/mapper/crypt-usr mount /dev/mapper/crypt-usr /mnt/free
9. Copy the files back to the newly encrypted partition:
cd /usr cp -ax . /mnt/free
OR
cd /usr tar cvpf usr.tar . cd /mnt/free tar xvpf /usr/usr.tar
10. Modify the /etc/conf.d/cryptfs:
# Encrypted USR target=crypt-usr source='/dev/LINUX/usr' type=luks options='-c serpent-cbc-essiv:sha256 -d /etc/conf.d/usr.key'
11. Modify the /etc/fstab:
/dev/mapper/crypt-usr /usr reiserfs noatime,notail 0 1
12. Reboot AGAIN.
If everything ran okay, the original partition /dev/hdc10 should now be encrypted (verify using mount: /usr should now be mounted on /dev/mapper/crypt-usr).
All you have to do now, is repeat this step for all the other partitions. Don't forget to take into account the changes in the steps above, required for each partition (i.e. /usr to /home, /dev/hdc10 to /dev/hdc13, etc).
AFTER, you have converted all the partitions to encrypted partitions and before using fdisk to release the space on the /dev/hdc14 partition, do the following on it:
shred -n 4 /dev/hdc14
No use leaving any potential juicy information around :)
[edit] Step 7: Creating the USB Token
Creating the USB token is relatively easy by now. I'm just going to list the steps directly (most should now be self explanatory). I will be assuming that the USB Pendrive is on /dev/sda.
# You will lose everything on the PenDrive, so make sure it's empty shred -n 4 /dev/sda # Create KEY File for Encrypting the PenDrive head -c 256 /dev/urandom > /etc/conf.d/token.key # Encrypt the PenDrive (Notice we are using LUKS) cryptsetup -c serpent-cbc-essiv:sha256 luksFormat /dev/sda /etc/conf.d/token.key # Create the dm entry for the PenDrive cryptsetup -c serpent-cbc-essiv:sha256 -d /etc/conf.d/token.key luksOpen /dev/sda crypt-token # Format the Encrypted Partition mke2fs /dev/mapper/crypt-token # Mount the PenDrive mkdir /mnt/token mount /dev/mapper/crypt-token /mnt/token # Copy the KEY Files for the partitions to the PenDrive cp /etc/conf.d/*.key /mnt/token # List to make sure we have everything ls /mnt/token # Unmount the Pendrive and Close the Device Mapper Entry umount /mnt/token cryptsetup luksClose crypt-token
So the only thing left is to put are PenDrive to use. We, again need to alter the /etc/conf.d/cryptfs to add the following entry:
# Encrypted PENDRIVE (Required for Mount) target=crypt-token source='/dev/sda' type=luks options='-c serpent-cbc-essiv:sha256 -d /etc/conf.d/token.key' pre_mount='mount -o ro /dev/mapper/crypt-token /mnt/token' post_mount='umount /mnt/token; cryptsetup luksClose crypt-token'
Basically this will mount the encrypted LUKS partition on /mnt/token (pre_mount option), during the boot process and before the other partitions are decrypted.
A little further on, after the mount process for the local partitions has completed, it will close and free up the USB Token (post_mount option). As of the moment that the post_mount commands have been executed, you can and should remove the USB Token. This token should only be inserted during the boot process, at all other times it should be secured somewhere else (you key chain, etc.).
Before going any further, you should reboot the system (again) with the pendrive plugged in to verify that the pendrive works!!! you should see an entry for crypt-token appear during the boot process.
If you are sure that the PenDrive is being mounted correcly, then all we have to do is alter the rest of the entries in cryptfs so as to refer to the new location /mnt/token/???.key: FROM
options='-c serpent-cbc-essiv:sha256 -d /etc/conf.d/home.key'
TO
options='-c serpent-cbc-essiv:sha256 -d /mnt/token/home.key'
Rebooting, should prove that the PenDrive is now being used.
[edit] Step 8: Backup
If you have reached this step, you should have all the linux partitions encrypted, except the root. But, in terms of security you still have all the passwords that are required to decrypt the partitions on the root, unencrypted partition.
So why don't we just delete them?
- Because you really should delete anything, you should SHRED them!
- Because if you lose the token, without having a backup system YOU LOSE EVERYTHING.
So how do we create a backup?
By creating a secure encrypted volume, with everything we can't lose.
For this backup we will be using a loop partition mounted on file in our file system. Again I will only be listing the steps there is nothing really new here.
# Create a 280M file to store the backup (I use a 256M USB PenDrive # so this create an image file a little larger than the drive, alter # the size according to you PenDrive Size i.e. PenDrive+10M more or less) # Note: /home/root is not the same as /root (the /root is store in the # un-encrypted root partition, where /home/root is on the encrypted /home # partition) dd if=/dev/random of=/home/root/backup bs=1024 count=286720 # Shred the Backup to guarantee it contains garbage shred -n 4 /home/root/backup # Mount the backup file under a LOOP Device (requires modprobe loop if the loop # device not built into kernel) losetup /dev/loop1 /home/root/backup # Encrypt the PenDrive (Notice we are using LUKS) # Notice that we are not using a KEY FILE so you will prompted for a PASSWORD # This PASSWORD has to guarantee the security of the BACKUP (So make it good) cryptsetup -c serpent-cbc-essiv:sha256 luksFormat /dev/loop1 # Create the dm entry for the PenDrive (Again the PASSWORD Prompt) cryptsetup -c serpent-cbc-essiv:sha256 luksOpen /dev/loop1 crypt-backup # Create and Mount the File System mke2fs /dev/mapper/crypt-backup mkdir /mnt/backup mount /dev/mapper/crypt-backup /mnt/backup cd /mnt/backup # SAVE an IMAGE of the USB PenDrive # Note: THAT WE ARE SAVING THE IMAGE DIRECTLY FROM THE PENDRIVE # (LUKS FORMAT and ALL) and not a decrypted image as we would get # from /dev/mapper/crypt-token dd if=/dev/sda of=pendrive.img # Backup the keys cp /etc/conf.d/*.key . # Close Everything cd /home/root umount /mnt/backup cryptsetup luksClose crypt-backup losetup -d /dev/loop1
Done, or almost done, we now have a file called /home/root/backup (which really is an encrypted file system that contain our USB Token image and all the KEY Files required to decrypt the partitions, including the KEY file to decrypt the USB Token).
All we to do now, if write this file to some permanent medium (i.e. a CD, but not CD-RW). If you use the NASA philosophy you will write this file to 3 CD (one for a safe in your home/office, one for a safe offsite, and one for you to use on need to basis).
[edit] Step 9: Removing the Evidence
All we have to do is remove all the KEY files in /etc/conf.d directory, except the "token.key" file, which is required to decrypt the USB PenDrive during the boot process.
To remove the files we use:
# Shred and Remove the KEY FILE shred -u /etc/conf.d/usr.key
Finally DONE. Reboot to verify everything is working okay.
[edit] Troubleshooting
One of the benefits of not encrypting the root, is that if you make a mistake, or an update messes with your system, you will still be able to mount the system to a minimal rescue prompt. If you have completed all the steps in the previous section you can test this, by booting the system without the USB token plugged in. The boot process will eventually get you to a place where you're prompted for the root password, and once entered you will have a command prompt with complete access to your system configuration (i.e. /etc directory) and installed binaries. This will save you a lot of trouble, since you don't have to use Bootable CD with the potential hassel of different kernel/binary/module versions.
On my system, I didn't have to alter /etc/modules.autoload.d/kernel-2.6 to automatically load dm-crypt (but this might be because of the genkernel initramfs). So if cryptsetup is giving you problems, the first thing to verify is if the dm-crypt module is loaded (i.e. lsmod or dmsetup targets).
Sometimes the cryptsetup will refuse to run, giving you an "invalid parameters" errors. Sometimes the parameters are correct but it still refuses, so try the command by hand (after reading man cryptsetup) to see which parameter is giving you problems. I had a problem with the aes cypher, that I had set as built-in kernel module not being available, so things like aes-cbc-essiv:sha256 wouldn't work for me.
The step by step approach I use, should basically never leave you in a situation in which the system doesn't boot. But in the case that something happens, REMEMBER, you should still have access to a boot prompt on your system (see above) and the complete set of configuration for your system, so just try to alter the files back to their original state and reboot.
REMEMBER, that in the encryption process for the partitions, you should always have a backup of the partition that you are trying to encrypt (either in encrypted form, or in it's original form).
REMEMBER, that the boot prompt that you should still have available, allows you to manually boot any of the partitions AND you should still have access to cryptsetup and the KEY files to decrypt any of the partitions.
REMEMBER, to mount an encrypted partition you have to use:
cryptsetup -c serpent-cbc-essiv:sha256 luksOpen /dev/.... crypt-.....
The luksFormat is only required when you want to FORMAT the partition (and is not needed when you are just trying to mount the partition).
As a last RESORT you can always use the GENTOO LIVECD to get to a point where you can access the partitions on your HARD Drive.
[edit] Other Security Considerations
First, you're only secure as the security of your weakest link. In this case, I would have to consider the USB Token as the weak point (others might consider the un-encrypted root as a the weak point).
The system works on the concept that, for your system to be comprimised somebody will have to have access to both your computer and usb token. This does not imply that this access has to be at the same time.
As an example:
1. You leave you USB token alone. 2. Some "spy" takes your token and makes an image of it (just like we did) and places your token back (without you noticing).
Now the "spy" can make a copy of the image to another USB drive and he will have complete access to your system, without you knowing it, using his USB Token.
another Example:
The "spy" steals your notebook with the USB Token attached (that you forgot to remove).
Potential Solution to this Problem:
- When we made our USB Token, we used a random key, that we stored in the KEY FILE on the un-encrypted root partition. This isn't required. We could have created the key using a password we chose (no KEY File on the root partition). The only difference will be that the system, during the boot process, will prompt you for a password. So without your password, there is no use to copying the USB Token.
Problems with the above Solution:
- The way the cryptfs system is implemented, you have no failsafe, if you make a mistake on the password you will not be prompted again, and the system will continue with the boot process and drop you into the minimal shell.
- User defined password are inherently weaker than random password, therefore easier to crack, if the "spy" had access to your token.
We can solve one of the problems above by using a 3 step system (which I describe)
- Create an encrypted filesystem on the USB token using a random key (as we did).
- On the encrypted device (crypt-token) create another encrypted filesystem using our keyword.
- Alter the cryptfs to mount the second encrypted filesystem (and prompt us for our password), before continuing.
This creates a 3 way dependency (computer, USB Token, user), with our weaker user defined key, being protected by the random key stored on the root filesystem (but again this is relative).
Second, some of you may feel uneasy about leaving the root partition unencrypted. The solution to this is to move basically everything that is not required for booting to one of the other partitions and linking them to the original source.
Example (for the /root directory):
- Create a /home/root directory, with root only privilegdes.
- Move all the files in /root to /home/root (rememeber to shred the originals).
- Link all the files in /home/root back to /root (Even on a fail boot, the only thing that will be visible is links).
an identical process can be used with the /etc directory, leaving only those files required to boot in /etc and moving all others to an encrypted partition.
Note: Some applications don't like links, so this has to be done with caution.
[edit] Final Words
I have tried for a more step-by-step aproach to this HOWTO without trying to explain everything.
For those of you who need an explanation, which should basically be all of you, you can refer to SECURITY System Encryption DM-Crypt with LUKS and [1].
The first site, as I said, served as the model for this HOWTO and has series of great links to other sources of informations.
The second site, is the reference site for LUKS (Linux Unified Key Setup).
I haven't really had more time to dedicate to this WIKI, but it might be interesting to set up a forum for people who would like to discuss problems or share their implementation stories. If somebody does setup a forum for this HOWTO, please alter this WIKI by placing a linkk to the forum for easy access.
I noticed that AnMaster took the trouble to cleanup the formatting of this WIKI, for which I am realy gratefull.
