Ever since I played with Knoppix 3.3, I have been fascinated with
encrypted filesystems (Knoppix allows you to keep your persistent
data on a USB pen drive, either in the clear or encrypted).

If you have not played with encrypted filesystems, the magic is
done by the 'loop' device, /dev/loop#.  I won't go into it here,
but you can Google for 'cryptoloop'.

Recently, I read an article that showed how to do some neat tricks
with encrypted filesystems.  Most of the time you simply encrypt a
filesystem using a passphrase.  However, if you want to change your
passphrase, you have to create a second encrypted filesystem with
the new passphrase and then copy over all of your data.  Ugh.  This
article explained how to use a key file, and then encrypt that key
file with your passphrase.

This led me to experiment a little, and it eventually led to a
little shell script to automate the process.  I have included it
here, because I think the TriLUG community might find it useful.

You can play with it in your own home directory (it does not have
to be used on a USB pen drive, but that's a good situation where
an encrypted filesystem is handy).

Simply run the script to create an encrypted filesystem image:

  sudo ./crypto.sh create test1

It'll ask you a few questions and then create a big file that looks
like gibberish.  Then mount the filesystem:

  sudo ./crypto.sh mount test1

It'll create a mount point directory called "test1.mnt" and it will
mount the encrypted filesystem there.  When you're done, just unmount
it the same way.

  sudo ./crypto.sh umount test1

You can change the passphrase with the script as well.

  sudo ./crypto.sh password test1

None of this stuff is really new, and it's not really rocket science.
But I liked how the article used that key file, and I have found the
script to the useful.  Maybe you will, too.

If you have questions about the script or about encrypted filesystems
in general, email me (either on-list of off-list).

Alan


[1] One common gotcha is storing a journaled filesystem image on top
of another journaled filesystem -- this can lead to data corruption.
In my script, I use a non-journaled ext2 filesystem.  In practice, I
store this image on a FAT-based USB pen drive.

[2] This script was written for use on a Ubuntu system.  I have seen
problems under Fedora, since their version of losetup took different
command-line parameters.  I might not have had loop-aes-utils installed
properly.


--



#!/bin/sh

#-------------------------------------------------------------------------------

usage() {
  echo "$program_name [ mount | unmount | create | password ] <basename>"
  echo "   example: $program_name mount crypto"
  echo "            mounts the 'crypto.img' filesystem on 'crypto.mnt'"
  exit 0
}

#-------------------------------------------------------------------------------

find_available_loop_device () {
  for loop_device in `( cd /dev ; ls -1 loop[0-9]* )` ; do
     sudo losetup /dev/$loop_device 2> /dev/null
     if [ $? -gt 0 ] ; then
        return
     fi
  done
  loop_device=""
}

#-------------------------------------------------------------------------------

find_loop_device_in_use () {
loop_device=`losetup -a | grep "\($image_file\)" | sed -e "s/^\/dev\///g" | sed -e "s/:.*$//g"`
}

#-------------------------------------------------------------------------------

crypto_mount () {
  # set up a loop device
  find_available_loop_device
  echo "Openssl will now ask for the password to the encrypted drive..."
openssl aes-256-ecb -d -in $key_file | losetup -p 0 -e AES256 /dev/$loop_device $image_file
  if [ $? -ne 0 ] ; then
     echo "Could not set up the loop device '$loop_device'."
     losetup -d /dev/$loop_device
     return
  fi
  echo "The loop device '$loop_device' has been set up."
  losetup /dev/$loop_device
  # create a mount point
  mkdir $mount_point
  # mount the filesystem
  mount -t ext2 /dev/$loop_device $mount_point
  if [ $? -ne 0 ] ; then
     echo "The encrypted drive was not mounted properly."
     losetup -d /dev/$loop_device
     return
  fi
  echo "The encrypted drive has been mounted OK."
}

#-------------------------------------------------------------------------------

crypto_unmount () {
  # unmount the filesystem
  umount $mount_point
  if [ $? -ne 0 ] ; then
     echo "Could not unmount the encrypted drive."
  else
     echo "The encrypted drive is unmounted."
  fi
  # remove the mount point
  rmdir $mount_point
  # de-configure the loop device
  find_loop_device_in_use
  for ld in $loop_device ; do
     losetup -d /dev/$ld
     if [ $? -ne 0 ] ; then
        echo "Could not deactivate the loop device '$ld'."
     else
        echo "The loop device '$ld' has been deactivated."
     fi
  done
# change the timestamp so we know that the image file may have been modified
  touch $image_file
}

#-------------------------------------------------------------------------------

crypto_password () {
  echo "You are about to change the password for the encrypted drive."
  echo "Enter the old password..."
  plain=`openssl aes-256-ecb -d -in $key_file`
  echo "Your old key file will be saved as '$key_file.old'."
  mv $key_file $key_file.old
  echo "Enter the new password (twice)..."
  echo $plain | openssl aes-256-ecb -e -out $key_file
  echo "The password has been changed."
}

#-------------------------------------------------------------------------------

crypto_create () {
  # create the image file
  if [ -f $image_file ] ; then
     echo "File '$image_file' already exists... operation aborted."
     return
  fi
  echo -n "Enter the filesystem size in megabytes: "
  read size
  dd if=/dev/zero of=$image_file bs=1M count=$size
  # create the key file
plain=`head -c 2880 /dev/urandom | uuencode -m - | head -n 65 | tail -n 64 | tr -d '\r\n'`
  echo "Enter the encryption password (twice)..."
  echo $plain | openssl aes-256-ecb -e -out $key_file
  # find an available loop device
  find_available_loop_device
  # configure the loop device
  echo $plain | losetup -p 0 -e AES256 /dev/$loop_device $image_file
  # create the filesystem
  mkfs.ext2 /dev/$loop_device
  # de-configure the loop device
  losetup -d /dev/$loop_device
}

#-------------------------------------------------------------------------------

crypto_test () {
  find_available_loop_device
  echo "available=[$loop_device]"
  find_loop_device_in_use
  echo "in_use=[$loop_device]"
}

#-------------------------------------------------------------------------------

# PERMISSIONS

if [ $EUID -ne 0 ] ; then
  echo "You must be root to run this script."
  exit
fi

# COMMAND-LINE OPTIONS

program_name=`basename $0`
if [ $# -ne 2 ] ; then
  usage
fi
action=$1
basename=$2

# CONFIGURATION

image_file="$basename.img"
key_file="$basename.key"
mount_point="$basename.mnt"

# load mondules
modprobe aes
modprobe cryptoloop

# COMMAND-LINE PARAMETERS

case "$action" in
  mount)
     crypto_mount
     ;;
  unmount|umount)
     crypto_unmount
     ;;
  password|passwd)
     crypto_password
     ;;
  create)
     crypto_create
     ;;
  test)
     crypto_test
     ;;
  *)
     usage
     ;;
esac


--
TriLUG mailing list        : http://www.trilug.org/mailman/listinfo/trilug
TriLUG Organizational FAQ  : http://trilug.org/faq/
TriLUG Member Services FAQ : http://members.trilug.org/services_faq/

Reply via email to