Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Trying to "fix" dmcrypt swap, need suggestions/help
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Other Things Gentoo
View previous topic :: View next topic  
Author Message
Sadako
Advocate
Advocate


Joined: 05 Aug 2004
Posts: 3792
Location: sleeping in the bathtub

PostPosted: Tue Aug 14, 2007 4:39 pm    Post subject: Trying to "fix" dmcrypt swap, need suggestions/hel Reply with quote

I've been using the simple method of encrypting swap via cryptsetup and /etc/conf.d/cryptfs for quite a while, and I've had one major gripe with it from the beginning:
Upon each boot, it runs mkswap on the device/partition specified.

No matter how you look at it, this is not desirable behaviour, and is made much worse by the fact that there are no checks performed in the device before running the command.

(Note: for all examples given I'll be using hda2 as the swap partition).

Typical checks such as the swap signature or even the UUID wont work in this case, and the one check that was performed in an alternative method (fdisk -l | grep "hda2") is insufficient (although it's certainly better than nothing).

Anyway, for the most part I was willing to just live with it, but it just dawned on me today that there is a possibly really simple way to do this, as cryptsetup supports setting the dmcrypt mapping up with an offset (in sectors), so by simply using a 1 sector offset we would have 512 bytes of persistent data at the beginning of the partition for checking upon each boot.

For example you could easily run `dd if=/dev/urandom of=/dev/hda2 bs=512 count=1`, then `dd if=/dev/hda2 of=/var/lib/whatever bs=512 count=1`, and then upon each boot compare the first 512 bytes of the swap partition with the contents of /var/lib/whatever, and only run mkswap if they match.

I've had a look at the init script where this happens (/lib/rcscripts/addons/dm-crypt-start.sh, provided by sys-fs/cryptsetup(-luks)), and I think it would be fairly trivial to implement there, however my scripting skills are still somewhat basic and I'm not sure what the best method to proceed would be, which is why I'm posting this so it can be discussed, and hopefully you'll be able to help/advise me.

What I was thinking was adding a new variable to /etc/conf.d/cryptfs for the data to compare the "header" to, the nice thing about that is it will be simple to only perform the check and use an offset with cryptsetup if that variable is defined, making it completely backwards compatible.
It's my goal to come up with something which I can file a bug for, so it could be considered for inclusion in portage.

The two things I'm really unsure about is;
1) What to use for the "header", the random data specified above would probably be the best (also it would be created for you automatically for you if you overwrite the partition with random data first, as you should), or would it be better to use a simple user-defined string?
The variable could be either a string or the path to the "/var/lib/whatever" file, but it only makes sense to implement one method or the other, and I don't know which one would be best.
2) This depends on what's chosen for 1, but how should the comparison be carried out in the script?
This is mostly related to aforementioned lack of skills, but everything I can think of just seems very amateurish and untidy.

So, any thoughts, suggestions, words of encouragement, flames?

Is anyone else actually interested in this, or even using this dmcrypt swap method at all?

Even suggestions for a better topic title would be greatly appreciated, as mine just sucks.

For reference, my original whining about this a couple of months ago, the already mentioned alternative script, and yet another alternative, which seems to re-create the swap on the unencrypted partition upon shutdown, so it can be checked upon the next boot.

Apologies on this being so damn long, I seem to be completely incapable of brief, to-the-point posts.
Need to work on that.
_________________
"You have to invite me in"
Back to top
View user's profile Send private message
Sadako
Advocate
Advocate


Joined: 05 Aug 2004
Posts: 3792
Location: sleeping in the bathtub

PostPosted: Wed Aug 15, 2007 5:26 pm    Post subject: Reply with quote

Okay, spent a little time on this today and have come up with a fairly simple solution which I'm happy with.

I was thinking about using an md5sum of the first 512 bytes for the check, however the md5sum binary is on /usr, so that wouldn't really work.
Same problem with using cmp to compare with a copy of the first 512 bytes in a file, so unless someone knows of an alternative I think I'm stuck with using a string for the comparison.

Anyway, this is what I came up with:
Code:
        elif [ -n "$swap" ]; then
                target=${swap}
                # swap contents do not need to be preserved between boots, luks not required.
                # suspend2 users should have initramfs's init handling their swap partition either way.
                : ${options:='-c aes -h sha1 -d /dev/urandom'}
                if [ -n "$header" ]; then
                        options="-o 1 ${options}"
                        if [ "$header" == "`/bin/dd if=${source} bs=1 count=${#header} 2> /dev/null`" ]; then
                                : ${pre_mount:='mkswap ${dev}'}
                        else
                                ewarn "Swap header verification failed, not running mkswap on ${source}"
                                return
                        fi
                else
                        : ${pre_mount:='mkswap ${dev}'}
                fi
        else

If the "header" variable is simply not defined in /etc/conf.d/cryptfs, it behaves exactly the same as before.

If it is defined, it compares the header string with the first n characters/bytes, where n is the length of the header string.

If they match, everything proceeds, an offset of one (sector) is added to the cryptsetup options, and mkswap is run.
If the check fails, you get a warning and mkswap is not run.

You'll also get an error when the system tries to activate the swap as defined in /etc/fstab.

For the string, I'm just using a UUID, which can be acquired either from /proc/sys/kernel/random/uuid or by running uuidgen, but of course any string (up to 512 characters) would do.

simply echo'ing the string to the swap device works fine for writing it as the "header".

Any comments?
Is this worth creating a bug for?

Here's a diff with /lib/rcscripts/addons/dm-crypt-start.sh (as installed by sys-fs/cryptsetup-luks-1.0.4-r3)
Code:
--- dm-crypt-start.sh.orig      2007-08-15 17:02:16.000000000 +0100
+++ dm-crypt-start.sh   2007-08-15 18:13:43.000000000 +0100
@@ -20,7 +20,17 @@
                # swap contents do not need to be preserved between boots, luks not required.
                # suspend2 users should have initramfs's init handling their swap partition either way.
                : ${options:='-c aes -h sha1 -d /dev/urandom'}
-               : ${pre_mount:='mkswap ${dev}'}
+               if [ -n "$header" ]; then
+                       options="-o 1 ${options}"
+                       if [ "$header" == "`/bin/dd if=${source} bs=1 count=${#header} 2> /dev/null`" ]; then
+                               : ${pre_mount:='mkswap ${dev}'}
+                       else
+                               ewarn "Swap header verification failed, not running mkswap on ${source}"
+                               return
+                       fi
+               else
+                       : ${pre_mount:='mkswap ${dev}'}
+               fi
        else
                return
        fi
@@ -214,7 +224,7 @@
                                unset gpg_options key loop_file target options pre_mount post_mount source swap remdev
                                ;;
 
-                       gpg_options=*|remdev=*|key=*|loop_file=*|options=*|pre_mount=*|post_mount=*|source=*)
+                       gpg_options=*|remdev=*|key=*|loop_file=*|options=*|pre_mount=*|post_mount=*|source=*|header=*)
                                if [[ -z ${target} && -z ${swap} ]] ; then
                                        ewarn "Ignoring setting outside target/swap section: ${targetline}"
                                        continue


Edit: Changed it so that the "-o 1" is added to the cryptsetup options before the existing options, therefore if another -o or --offset is specified in the options in conf.d/cryptfs it won't be overridden by -o 1.
If you specify -o 0, you're on your own. :P
_________________
"You have to invite me in"
Back to top
View user's profile Send private message
Hu
Moderator
Moderator


Joined: 06 Mar 2007
Posts: 21607

PostPosted: Sat Aug 18, 2007 5:13 pm    Post subject: Reply with quote

I like it. If the user has busybox configured with certain features, you can get access to functionality equivalent to cmp through /bin/busybox cmp <file1> <file2>. Unfortunately, the latest version of busybox can be configured to omit cmp, so not all users are guaranteed to have the necessary functionality. A possible invocation (warning: requires GNU bash): /bin/busybox cmp --silent <( /bin/dd < "${source}" 2>/dev/null ) "${header_file}". This will produce no output, but the exit code will be success if the inputs are equal and failure if they are not. Standard error for /bin/dd is redirected to suppress the block count information that it would otherwise produce.
Back to top
View user's profile Send private message
Sadako
Advocate
Advocate


Joined: 05 Aug 2004
Posts: 3792
Location: sleeping in the bathtub

PostPosted: Sat Aug 18, 2007 6:12 pm    Post subject: Reply with quote

Thanks for the feedback.

cmp via busybox is an interesting idea, but a little cumbersome methinks, and like you said you can't rely on everyone having it.

I have an idea about how to enable the same check for other temporary file systems (like /tmp), but it'd require a lot more changes.

Anyway, do you think what I have is worth posting to bugs.gentoo.org?

And I wish somebody had told me that cryptsetup-luks is just cryptsetup now! :evil:
_________________
"You have to invite me in"
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Other Things Gentoo All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum