Adding an external encrypted drive with LVM to Ubuntu Linux

I recently added an external eSATA drive to my home computer so I could back up critical data from my home network to one drive. I bought a Western Digital 1TB “green” drive and a Thermaltake external hard drive enclosure with eSATA and USB connectors.

Since my internal hard drives are encrypted it didn’t make sense to back up all of that data to an unencrypted external drive. I’d read Uwe Hermann’s excellent how-to article on disk encryption, but he didn’t cover setting up an LVM partition, which I always use so I can change drive volume sizes on the fly.

This is what I did to set up an external encrypted drive with LVM on an Ubuntu system:

  1. Open a terminal
  2. Get a root prompt:
    sudo /bin/bash
  3. Watch the system log:
    tail -f /var/log/messages
  4. Attach the external drive. The system log tells me that it was detected as /dev/sdc.
  5. Check the drive for bad blocks (takes a couple of hours):
    badblocks -c 10240 -s -w -t random -v /dev/sdc
  6. Write random data to the entire drive. This step takes all night, but it ensures that never-written drive space can’t be differentiated from encrypted data if someone ever tries to crack the drive. (If you’re going to do this, you might as well do it right.)
    shred -v -n 1 /dev/sdc
  7. Create one big LVM partition on the drive using fdisk. Set up one big primary partition /dev/sdc1, set the tag to system id “8e” LVM, and write the changes to disk:
    > fdisk /dev/sdc                                                                                                                                              
    Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel                                                                                                  
    Building a new DOS disklabel with disk identifier 0xa6846916.                                                                                                                       
    Changes will remain in memory only, until you decide to write them.                                                                                                                 
    After that, of course, the previous content won't be recoverable.                                                                                                                   
    
    
    The number of cylinders for this disk is set to 121575.
    There is nothing wrong with that, but this is larger than 1024,
    and could in certain setups cause problems with:               
    1) software that runs at boot time (e.g., old versions of LILO)
    2) booting and partitioning software from other OSs                                                                                                                                 
       (e.g., DOS FDISK, OS/2 FDISK)                                                                                                                                                    
    Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)                                                                                                      
                                                                                                                                                                                        
    Command (m for help): p                                                                                                                                            
                                                                                                                                                                                        
    Disk /dev/sdc: 999.9 GB, 999989182464 bytes                                                                                                                                         
    255 heads, 63 sectors/track, 121575 cylinders                                                                                                                                       
    Units = cylinders of 16065 * 512 = 8225280 bytes                                                                                                                                    
    Disk identifier: 0xa6846916                                                                                                                                                         
                                                                                                                                                                                        
       Device Boot      Start         End      Blocks   Id  System                                                                                                                      
                                                                                                                                                                                        
    Command (m for help): n                                                                                                                                            
    Command action                                                                                                                                                                      
       e   extended                                                                                                                                                                     
       p   primary partition (1-4)                                                                                                                                                      
    p                                                                                                                                                                  
    Partition number (1-4): 1                                                                                                                                          
    First cylinder (1-121575, default 1): [ENTER]                                                                                                                      
    Using default value 1
    Last cylinder, +cylinders or +size{K,M,G} (1-121575, default 121575): [ENTER]
    Using default value 121575
    
    Command (m for help): t
    Selected partition 1
    Hex code (type L to list codes): 8e
    Changed system type of partition 1 to 8e (Linux LVM)
    
    Command (m for help): p
    
    Disk /dev/sdc: 999.9 GB, 999989182464 bytes
    255 heads, 63 sectors/track, 121575 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes
    Disk identifier: 0xa6846916
    
       Device Boot      Start         End      Blocks   Id  System
    /dev/sdc1               1      121575   976551156   8e  Linux LVM
    
    Command (m for help): w
    The partition table has been altered!
    
    Calling ioctl() to re-read partition table.
    Syncing disks.
  8. Use cryptsetup to encrypt the drive:
    cryptsetup --verbose --verify-passphrase luksFormat /dev/sdc1
  9. Unlock the drive:
    cryptsetup luksOpen /dev/sdc1 backupexternal
  10. Create the LVM physical volume:
    pvcreate /dev/mapper/backupexternal
  11. Create the LVM volume group:
    vgcreate xbackup /dev/mapper/backupexternal
  12. Create a logical volume within the volume group:
    lvcreate -L 500G -n backupvol /dev/xbackup
  13. At this point you have a device named /dev/xbackup/backupvol, so create a filesystem on the logical volume:
    mkfs.ext4 /dev/xbackup/backupvol
  14. Mount the volume:
    mount /dev/xbackup/backupvol /mnt/backup
  15. To get the volume to mount automatically at boot time add this line to your /etc/fstab file:
    /dev/xbackup/backupvol      /mnt/backup     ext4    defaults        0 5
  16. To be prompted for the decryption key / passphrase at boot time first get the drive’s UUID:
    ls -l /dev/disk/by-uuid

    (In my example I use the UUID for /dev/sdc1)

  17. Then add this line to the /etc/crypttab file:
    backupexternal UUID=[the UUID of the drive] none luks

That’s it. You now have an external, encrypted hard drive with LVM installed. You’ve created one 500GB volume that uses half the disk, leaving 500GB free for other volumes, or for expanding the first volume.

Hope you find this useful.

16 thoughts on “Adding an external encrypted drive with LVM to Ubuntu Linux

  1. Thanks for the write up. Very helpful.

    Everything is working as expected. However, if i turn my external drive off while the OS is running, I’m left with a stale vg and crypt mapping.

    I finally figured out how to get rid of the stale lvm mapping (sudo vgchange -a n vg_bak_crypt, sudo vgchange -a n vg_bak_crypt), but the mapping that was setup via crypttab is still lingering (/dev/mapper/ext_bak). Is there anyway to get ride of that?

    More to the point, what else do I need to do/change in order to allow turning the drive off and one while the OS is running and having it remap everything correctly?

  2. Sorry, that was the following 2 commands to remove the vg mapping:

    sudo vgchange -a n vg_bak_crypt
    sudo vgremove vg_bak_crypt

  3. to elaboarte…here is what I’m seeing in the output of pvs after turning the drive off and back on…If I reboot with the drive on….all will be well, but I’d like to be able to turn it off an on without rebooting if possible…

    Note: I think the issue may have to do with the fact that the hd dev name changes from sdh to sdi when i turn it off and back on…but then I suspect there may be more too it as well…

    /dev/mapper/ext_bak: read failed after 0 of 2048 at 0: Input/output error
    /dev/mapper/ext_bak: read failed after 0 of 1024 at 1000201584640: Input/output error
    /dev/mapper/ext_bak: read failed after 0 of 1024 at 1000201703424: Input/output error
    /dev/mapper/ext_bak: read failed after 0 of 1024 at 0: Input/output error
    /dev/mapper/ext_bak: read failed after 0 of 1024 at 4096: Input/output error
    /dev/mapper/ext_bak: read failed after 0 of 2048 at 0: Input/output error

  4. In my case if my computer is powered then the external drive is powered, because I want it there for unattended backups. However, I’ve also done this for drives that I want to be able to attach and detach at any time.

    If you want to be able to power the drive on or off any time, do not add the drive to /etc/fstab or /etc/cryptab. Also, DO NOT USE vgremove! That deletes the volume group, destroying your data. You basically want to unmount the drive and then turn off the crypto layer in order to detach the drive.

    Follow the steps above through step #14. That gives you a mounted, encrypted drive. To unmount:

    sudo umount /dev/xbackup/backupvol
    sudo cryptsetup luksClose /dev/xbackup/backupvol

    At this point you can power off the drive and disconnect it. To start using it again, power it up, plug it back in and:

    sudo cryptsetup luksOpen /dev/sdc1 backupexternal
    sudo mount /dev/xbackup/backupvol /mnt/backup

    After you type the luksOpen command you’ll be prompted for the passphrase. The drive should appear as /mnt/backup again after you mount it.

    I’m using the same drive letter (/dev/sdc1) and volume group name (xbackup) that I used in the article. You should use the drive letters and names appropriate for your setup.

  5. First of all thanks for posting this usefull information :)

    However, cryptsetup luksClose did respond to me with “Device is busy.” and failed to close the device.

    To get the device closed it is needed to deactivate the volume group with

    vgchange -an

    before calling luksClose

  6. Excellent guide.

    I used it to set up an encrypted volume for a RAID on a SAN enclosure. It worked like a charm. The only difference is you don’t have to partition the RAID before creating the crypt.

    Thanks for posting this.

  7. Good guide, but beware this is no longer applicable in Ubuntu 12.
    It will work the first time, but after a reboot none of the created devices will be available, and regaining access to your data is tricky, to say the least.

    • ThreePercenter: I’m using this method with the latest versions of both Ubuntu and OpenSUSE. You can add the drive to cryptab and fstab or manually run the cryptsetup/vgchange/mount commands manually, it should work either way.

  8. Thanks for the instructions but i am getting this error when manually mounting:

    Device Boot Start End Blocks Id System
    /dev/sda1 2048 1953523054 976760503+ 8e Linux LVM

    root@rp1:~# sudo cryptsetup luksOpen /dev/sda1 backupexternal
    Enter passphrase for /dev/sda1:

    root@rp1:~# sudo mount /dev/xbackup/backupvol /mnt/backup
    mount: special device /dev/xbackup/backupvol does not exist

    • Try running “vgchange -ay” to make sure all volume groups are activated before mounting the volume. Some distros seem to do this automatically for you and some do not.

  9. I will just leave it here for the people:

    There is one “small” thing when applying this to the Ubuntu Server:
    The config file for encrypted volumes is:
    /etc/crypttab
    not
    /etc/cryptab as mentioned above

    Anyway, thanks for tutorial :)

  10. Section about automatic mounting is very useful and saved me a lot of time. Thank you for this guide.

  11. Excellent article. Thanks you kindly sir for putting this together in a step by step guide.
    Perfect.

  12. Pingback: Automatically decrypt multiple LUKS-encrypted volumes | Earl C. Ruby III

  13. Pingback: Linux Encrypted Backup solution to USB HD (Open Source)

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.