Thu 02 of Sep, 2010 [15:27 UTC]  
Menu

luksopen

edit print PDF
English

luksopen


NEW - see below for a dynamic mount and unmount script, which allows you to use a command very similar to "mount" to mount a luks encrypted filesystem in a file (loopback mount), and then later unmount that mountpoint.



It's just intended for opening and mounting devices... If you wish to close and unmount your devices without halting/restarting your system, you have to do it by hand.



1. You need to edit these arrays which you can find at the beginning of the script:

devArray: Enter the devices you wish to open and mount using this script, seperated by whitespace.

mapArray: You need to add/remove elements here depending on how many devices you put into "devArray".
Also, you need to adjust the indexes (the numbers inside the square brakets: 0, 1, 2, ..., n) of each element.

mntArray: Enter the mount points you wish to use. First element in "devArray" will be opened and the
matching mapper device will then be mounted on the first element in "mntArray" etc.
Make sure you did not forget to create the mount points.


2. Save file as "/sbin/luksopen" (or whatever else you choose) and do "chmod 755 /sbin/luksopen".


3. If you like, add the new line "/sbin/luksopen" to your /etc/conf.d/local.start (Gentoo).

#! /bin/bash

devArray=(/dev/hda7 /dev/hda10 /dev/hda11 /dev/hda13)
mapArray=(${devArray[0]:5} ${devArray[1]:5} ${devArray[2]:5} ${devArray[3]:5})
mntArray=(/tmp /mnt/bergen /mnt/trondheim /mnt/oslo)

if ! cryptsetup --help | grep -q luksFormat ; then
	echo "This script requires cryptsetup luks" >&2
	exit 1
fi

for (( i=0 ; i < ${#devArray[@]} ; ++i )) ; do
	dev=${devArray[$i]}
	if [ -z "$dev" ] || [ ! -e "$dev" ] ; then
		echo "Unable to find \"$dev\"" >&2
		continue
	elif ! cryptsetup isLuks "$dev" ; then
		echo "\"$dev\" doesn't seem to be a Luks encrypted volume" >&2
		continue
	fi

	map=${mapArray[$i]}
	# check whether device is already opened
	if [ -z "$map" ] ; then
		echo "Map name unspecified for \"$dev\"" >&2
		continue
	elif [ -e "/dev/mapper/$map" ]; then
		echo "\"/dev/mapper/$map\" already exists" >&2
		continue
	fi

	mnt=${mntArray[$i]}
	if [ -z "$mnt" ] || [ ! -d "$mnt" ] ; then
		echo "Unable to find mount point for \"$dev\"" >&2
		continue
	fi

	# ask whether to open the device or not
	read -p "Next device in list is \"$dev\". Do you want to open and mount it? (y/N): "

	# skip device if desired
	case "$answer" in
		y|Y)
			;;
		*)
			echo "Skipping \"$dev\"" >&2
			continue
			;;
	esac

	# open and mount device
	j=3
	while [ $j -gt 0 ] && ! cryptsetup luksOpen "$dev" "$map" ; do
		let "--j"
	done
	if [ $j -le 0 ] || ! mount "/dev/mapper/$map" "$mnt" ; then
		echo "Failed to mount \"/dev/mapper/$map\" on \"$mnt\"" >&2
	fi
done





NEW - Here's the dynamic mount and unmount script!

OK, here's the (optional) config file, expected to be at /etc/zmount/zmount.conf:

# Directory to store fstab/ config file for each dynamic mount:
FSTAB_DIR="/etc/zmount/mounts"


And here's the zmount/zumount script - just symlink the zmount script to zumount, and it will work:

#!/bin/sh

# Config: /etc/zmount/zmount.conf (see CONFIG_ENV in this file).

# Must (?) run this script as root. symlink this script to "zumount" to unmount
# corresponding mounts.

# This is a script to [un]mount a single encrypted loopback filesystem using
# dm-luks.

# To create such a filesystem, see
# http://www.freeotfe.org/docs/Linux_examples__LUKS.htm#Linux_examples__LUKS
# (local copy tech/doc)

# A script to encapsulate the creation would be nice too. At the moment I create
# my volumes manually, as per the link above (it has an unnecessary excess
# loopbak mount which I don't do in this script).

# TODO:
#
# Support embedded/ recursive type crypto mounts (unmount command which checks
# for mounts within mounts, because unmounting a crypto mount which has other
# crypt filesystem source files inside it (which are themselves loopback crypto
# mounted), means that those on the inside need to be unmounted first).

# Author: Zenaan Harkness. Email dm-crypt _at_ freedbms _dot_ net
# Copyright (c) 2006 Zenaan Harkness and UPMART, all rights reserved.
# You may use this program under the terms of the GNU General Public License,
# either version 2 or (at your option) any later version.

PCOUNT=$#
MYNAME=`basename $0`
if [ $MYNAME == "zumount" ]; then
   UNMOUNT="true"
fi

if [ "$PCOUNT" -lt 2 ]; then
   if [ x$UNMOUNT = xtrue ]; then
      if [ "$PCOUNT" -lt 1 ]; then
         echo "ERROR: Destination un-mountpoint missing."
         echo "Usage:"
         echo "  $MYNAME un-mountpoint [--verbose]"
         exit 1
      fi
   else
      echo "ERROR: Encrypted filesystem source file &/or destination mountpoint missing."
      echo "Usage:"
      echo "  $MYNAME encrypted-filesystem-file destination-mountpoint [--verbose]"
      exit 1
   fi
fi

if [ x$UNMOUNT != xtrue ]; then
   # Source location of crypt fs file to be mounted:
   if [ ! -f $1 ]; then
      echo "ERROR: (Crypto) source file ($1) not found."
      exit 2
   fi
   ENC_SRC=`realpath $1`; shift
   # Name of crypt fs device; arbitrary; must be unique wrt other dm devices:
   ENC_SRC_NAME=`echo $ENC_SRC|sed -e "s#/#=#g;"`
   ENC_DEV_NAME=$ENC_SRC_NAME
   # Grab next available loop device (are these now dynamically allocated in Linux?):
   LOOP_DEV=`losetup -f`
fi

# Destination [un]mount point; arbitrary:
if [ ! -d $1 ]; then
   echo "ERROR: Destination directory ($1) not found."
   exit 3
fi
ENC_DST=`realpath $1`; shift
ENC_DST_NAME=`echo $ENC_DST|sed -e "s#/#=#g;"`

WHOAMI=`whoami`

# Default directory to store dynamic mount configs:
FSTAB_DIR="/etc/zmount/mounts"
CONFIG_ENV=/etc/zmount/zmount.conf
if [ -r $CONFIG_ENV ]; then . $CONFIG_ENV; fi

FSTAB_FILE=$FSTAB_DIR/${ENC_DST_NAME}.sh

if [ x$1 = x--verbose ]; then
   VERBOSE=true; shift
   # Display status/ config:
   echo "CONFIGURATION:"
   echo "  whoami ................: $WHOAMI"
   echo "  pwd ...................: `pwd`"
   echo "  Encrypted filesystem ..: $ENC_SRC"
   echo "   (( \$CONFIG_ENV .......: $CONFIG_ENV ))"
   echo "   (( \$FSTAB_FILE .......: $FSTAB_FILE ))"
fi

if [ x$UNMOUNT = xtrue ]; then
   if [ ! -f $FSTAB_FILE ]; then
      echo "ERROR: Crypto fstab file ($FSTAB_FILE) for this mount not found."
      exit 4
   fi
   # Grab data about filesystem to unmount:
   . $FSTAB_FILE
fi

ENC_DEV=/dev/mapper/$ENC_DEV_NAME

if [ x$VERBOSE = xtrue ]; then
   echo "   (( Crypt device ......: $ENC_DEV ))"
   echo "   (( Loop device .......: $LOOP_DEV ))"
   echo "  [Un]mountpoint ........: $ENC_DST"
   echo
fi

# Can only [un]mount when we are root (perhaps better group/perms setup):
if [ ! "x$WHOAMI" == "xroot" ]; then
   echo "ERROR: Need to run as root user. Try: \"sudo $MYNAME\""
   exit 11
fi

if [ x$UNMOUNT = xtrue ]; then
   if umount $ENC_DST && cryptsetup luksClose $ENC_DEV_NAME && losetup -d $LOOP_DEV && rm $FSTAB_FILE; then
      #echo "Unmount apparently successful ($ENC_DST, $ENC_DEV_NAME, $LOOP_DEV)."
      echo "Umount apparently successful."
   else
      echo "WARNING: Unmount may have had problems."
   fi
   exit
fi

if [ ! -d $FSTAB_DIR ]; then
   mkdir -p $FSTAB_DIR
fi

# Mount filesystem:
# Create loop device attached to encrypted source file:
if losetup $LOOP_DEV $ENC_SRC; then
   # Create LUKS Crypt device:
   #cryptsetup luksDump $LOOP_DEV
   echo "Enter password to unlock encrypted volume \"$ENC_SRC\":"
   if cryptsetup luksOpen $LOOP_DEV $ENC_DEV_NAME; then
      #dmsetup table
      #cryptsetup status $ENC_DEV[_NAME]
      # Mount the encrypted filesystem device:
      if mount $ENC_DEV $ENC_DST; then
         #echo "Mount apparently successful ($ENC_SRC, $LOOP_DEV, $ENC_DEV_NAME, $ENC_DST)."
         echo "Mount apparently successful."
      else
         echo "ERROR: Mount failure: mount $ENC_DEV $ENC_DST"
         echo "Closing crupto device $ENC_DEV_NAME and removing loop device $LOOP_DEV"
         cryptsetup luksClose $ENC_DEV_NAME
         losetup -d $LOOP_DEV
         exit 7
      fi
   else
      echo "ERROR: Crypt setup failure: cryptsetup luksOpen $LOOP_DEV $ENC_DEV_NAME"
      echo "Removing loop device $LOOP_DEV"
      losetup -d $LOOP_DEV
      exit 6
   fi
else
   echo "ERROR: Loop device setup failure: losetup $LOOP_DEV $ENC_SRC"
   exit 5
fi

# umount data/ fstab file:
echo "LOOP_DEV=\"$LOOP_DEV\""          >> $FSTAB_FILE
echo "ENC_DEV_NAME=\"$ENC_DEV_NAME\""  >> $FSTAB_FILE
echo "ENC_DST=\"$ENC_DST\""            >> $FSTAB_FILE



Feel free to email me: dm-crypt _at_ freedbms _dot_ net

Links:
logo design
sell gold for cash
commission ritual
Acne Scar Treatment
Gold Plated Belly Rings

Created by: embro last modification: Wednesday 01 of September, 2010 [19:43:19 UTC] by Anonymous


Posted messages

Top Hide all
author message
Some advise
on: Fri 02 of Dec, 2005 [08:11 UTC] score: 0.00
Using pairs of arrays are somewhat fragile. It is somewhat better to use either arrays of arrays (should be possible), arrays of strings, or array of associative values (an array of strings of variable names). The strings could be the values or could be names of variables to be eval'd. The later can be done using $(eval echo \${$variable}) where $variable can be an combination of strings and multiple variables.

Rather than setting up the dev_shortArray and mapArray, just set these to loop variables.

If you are using continue, you probably don't want to do nested ifs.

When using $?, the value will always be a number so tests should probably use -ne 0 instead of ="0".

The loop to call cryptsetup can be greatly simplified:
# Try 3 times to get the password right
j=3
while [ $j -gt 0 ] && ! cryptsetup luksOpen ${devArray[$i]} ${dev_shortArray[$i]} ; do
   let "--j"
done
if [ $j -le 0 ] ; then
   echo "Failed to open ${devArray[$i]}"
fi
let "++i"


Using continue everywhere is somewhat clumsy.


author message
bash shell error in 'read' variable
on: Tue 28 of Mar, 2006 [15:44 UTC] score: 0.00
At least in the bash shell, the default variable assigned in a 'read' statement is "$REPLY". In your script as currently written, this causes an error when you get to the following part:

...
  1. ask whether to open the device or not
read -p "Next device in list is \"$dev\". Do you want to open and mount it? (y/N): "

  1. skip device if desired
case "$answer" in
...

Note that the 'read' statement has no variable name assigned, whereas the 'case' statement is looking for $answer. You might want to change the 'read' line to be:

read -p "Next device in list is \"$dev\". Do you want to open and mount it? (y/N): " answer

so that '$answer' is the explicitly assigned variable.

HTH,

Marc



author message
Suggested modification when using LVM
on: Thu 25 of May, 2006 [17:06 UTC] score: 0.00
If you are using LVM, you may find the following modification useful:

1) Delete the entire mapArray variable line

2) Replace the line that reads:
map=${mapArray$i}
with:
# assign last directory name of device name to $map variable
map_elements=`echo ${devArray$i} | sed -e 's/^\///' -e 's/\// /g'`
for e in $map_elements ; do map=$e ; done

What this does is address the fact that the directory names of physical devices that are represented by logical volumes are longer than the directory names of devices that are not logical volumes. For example, the fully qualified names of all the devices in /dev begin with "/dev/", such as /dev/hda1, /dev/hb1/ and /dev/sda1. However, the fully qualified names of physical devices that are represented by logical volumes begin with something like "/dev/VolGroup00/" or "/dev/vg0", such as /dev/VolGroup/LogVol00 or /dev/vg0/home. The modification suggested above addresses this difference regardless of whether you use logical volumes or not.

John


author message
Re: Suggested modification when using LVM
on: Sun 28 of May, 2006 [15:41 UTC] score: 0.00
I apologize. Where ${devArray$i} is indicated in my comment above should actually read ${devArray$i}.

John


author message
Workaround for bad passphrase test failure
on: Sat 10 of Jun, 2006 [12:26 UTC] score: 0.00
Currently, there is a bug in some versions of crytpsetup LUKS relative to the exit codes. There have been posts about this on the e-mail list covering both Debian and FC5. On FC5, the current RPM version is:

cryptsetup-luks-1.0.3-0.rc2

The problem is that cryptsetup luksOpen returns an exit code of 0, whether or not the correct passphrase is entered by the user at the prompt. This will cause the test in the loop in luksopen to pass, even when a bad passphrase is entered and thus, not allow for a re-try. The current test is:

# open and mount device
j=3
while [ $j -gt 0 ] && ! cryptsetup luksOpen "$dev" "$map" ; do
let "--j"
done

A temporary workaround is to test for the presence of the /dev/mapper device instead:

j=3
while [ "$j" -gt 0 ] && [ ! -e /dev/mapper/"$map" ] ; do
cryptsetup luksOpen "$dev" "$map"
let "--j"
done

HTH,

Marc




Page: 1/1
1