Wednesday, June 20, 2012

Encrypt partition (LUKS, cryptsetup) on an external hard-drive/pendrive in Linux & mounting/unmounting it

So, this blog post is about how to create encrypted partition on a hard disk & then use it on linux.

The first thing you need to do is delete all data that's on the partition. Deleting the data by formatting is not the way. This way, the complete files or a part of it still exist on the partition.

My external hard disk looks like this in parted:
shadyabhi@MBP-archlinux ~ $ sudo parted /dev/sdb
GNU Parted 3.1
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) p                                                                
Model: Seagate FreeAgent GoFlex (scsi)
Disk /dev/sdb: 1000GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags: 

Number  Start   End     Size    Type      File system  Flags
 1      1049kB  15.7GB  15.7GB  primary   ntfs
 2      15.7GB  1000GB  984GB   extended               lba
 5      15.7GB  338GB   322GB   logical   ntfs
 6      338GB   660GB   322GB   logical   ntfs
 7      660GB   928GB   268GB   logical   ntfs
 8      928GB   982GB   53.7GB  logical

(parted)


If you want to use a local file as your encrypted partition, just do 
dd if=/dev/urandom of=/location/to/file bs=1MB count=100 #Creates a 100MB file
& mount it as a loopback device by doing
losetup /dev/loop0 /location/to/file
Now, skip to the part of using cryptsetup command and use /dev/loop0 instead of /dev/sdb8

I plan to make my /dev/sdb8 (53.7GB) partition as the encrypted one. First we need to make all the data that is already available on the partition unrecoverable. To do that I will write Zeros to the whole partition.
dd if=/dev/zero of=/dev/sdb8 bs=1MB
I have kept the block size as 1MB which means the dd command will read/write 1MB at a time. The above command executed with around 30MBps on my MBP.

Next thing that I need to do is put random bytes on my hard disk so that another user cannot identify my encrypted data from the zeros that are already on the drive.
dd if=/dev/urandom of=/dev/sdb8 bs=1MB
The above command had a speed of around 10MBps on my MBP. Now that we have our disk ready with random bytes, we will get started with creating the encrypted partition.

First make sure that dm_mod module is loaded, if not, load it. Then, execute this command to prepare the partition using LUKS. LUKS is just a disk-encryption specification.
[root@MBP-archlinux ]# cryptsetup --verbose --cipher=aes-xts-plain64 --key-size=512 --hash=sha512 luksFormat /dev/sdb8

WARNING!
========
This will overwrite data on /dev/sdb8 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase: 
Verify passphrase: 
Command successful.
[root@MBP-archlinux ]# 
Make sure that you write the YES in caps. I chose a pretty damn powerful password of more than 30 characters!

Remember the dm_mod we loaded learlier, that will come in to play here. Now, we will map our partition using the Device Mapper.
[root@MBP-archlinux notes]# cryptsetup luksOpen /dev/sdb8 encrypted_external
Enter passphrase for /dev/sdb8: 
[root@MBP-archlinux ]# ls /dev/mapper/
control  encrypted_external
[root@MBP-archlinux ]#
Now, there is an entry under /dev/mapper for encrypted_external which we will use in future to access our device. REMEMBER, now, we will not use /dev/sdb8 anymore. If we access via /dev/mapper/encrypted_external, the kernel will take care of doing the translation for us.
The partition is there but it's not having a filesystem as we wiped it out by writing random bits of data using dd). Let's create the partition now. While creating the partition, I will reduce the size used by superuser to do his stuff. More info about that can be seen in the manpage.
   -m reserved-blocks-percentage
              Specify the percentage of the filesystem blocks reserved for the super-user. This avoids fragmentation, and allows root-owned daemons,  such as  syslogd(8),  to  continue to function correctly after non-privileged processes are prevented from writing to the filesystem.  The default percentage is 5%.
To create the filesystem,
[root@MBP-archlinux ~]# mkfs.ext4 -m 1 /dev/mapper/encrypted_external 
mke2fs 1.42.3 (14-May-2012)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
3276800 inodes, 13106688 blocks
131066 blocks (1.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=4294967296
400 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
        4096000, 7962624, 11239424

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done   

[root@MBP-archlinux ~]# 
Now, we have a working ext4 partition with reduced reserved blocks. To mount the partition, simply use the mount command: (make sure that /mnt/secret exists)
mount -t ext4 /dev/mapper/encrypted_external /mnt/secret/
The encrypted filesystem is now available under /mnt/secret/ for you to read/write on it. Whenever you are done with the read/writing on partition, you can close the partition using:
umount /mnt/secret
cryptsetup luksClose encrypted_external
You might have noticed that for luksOpen/luksClose commands, I always use the mapper name instead of accessing it directly using /dev.

That's it! Next time you want to access the partition again, do
cryptsetup luksOpen /dev/sdb8 encrypted_external
mount -t ext4 /dev/mapper/encrypted_external /mnt/secret/
And to unmount the partition gracefully, use:
umount /mnt/secret
cryptsetup luksClose encrypted_external
And in case you are shit-scared to use command everytime you access the partition, nautilus can do that for you.
Device is shown as encrypted partition in nautilus

And when clicked gives a nice dialog to enter the passphrase and mount the partition

If you just want a have a 100MB file on your filesystem that will contain your encrypted data, that is also possible. The idea is to make a 100MB file, mount it as a loopback filesystem & do everything what you did above. For that just make sure that "loop" module is loaded in the kernel & simply do as stated here.

If you get an issue like the encrypted partition is not writable by users other than root even if you mounted a partition using the nautilus. You need to redo the permission on the files of the partitions.
sudo chown -R root:users /mnt/secret/ #Give root and other users with group "users" access to files in partition
sudo chmod -R 775 /mnt/secret/
Happy encrypting data.

1 comment:

  1. Looking at the wipe part, it's no point in first dd zero and then urandom since urandom will write same blocks.

    Also, urandom is cpu bound, a much faster way is to
    Encrypt the hard disk using a random key:

    cryptsetup create random_sdx /dev/sdb8 -d /dev/random
    Fill the encrypted disk
    dd if=/dev/zero of=/dev/mapper/random_sdx bs=1M
    clean up
    cryptsetup remove random_sdx

    Then it's mostly IO bound and on my system speed did go from 16 to 113 MB/sec

    ReplyDelete