#1493 PR merged
: Improve cryptographic security and user-friendliness for LUKS volumes¶
Labels: enhancement
, fixed / solved / done
OliverO2 opened issue at 2017-09-15 09:07:¶
Problem¶
ReaR 2.2 with cryptsetup 1.6.6 (as on Ubuntu 16.04.3 LTS) uses compiled-in default values which are not up-to-date in terms of cryptographic security:
Option | cryptsetup 1.6.6 Default | More Secure | Auto-detectable |
---|---|---|---|
Key size | --key-size 256 | --key-size 512 | Yes |
Passphrase processing time (msecs) | --iter-time 1000 | --iter-time 2000 | No |
Random number generation device | --use-urandom | --use-random | No |
For details, see Encryption options for LUKS mode in the ArchWiki.
In addition, ReaR can neither auto-detect nor use existing keyfiles for the automatic decryption of recreated LUKS volumes. A recovered system will ask the user for a passphrase where the original system would not.
Solution¶
This PR improves LUKS recovery with these characteristics:
- Auto-detect the
--key-size
option from the original volume. - Auto-detect keyfiles in crypttab and add them to recreated LUKS volumes.
- Allow additional cryptsetup options, which cannot be auto-detected, to be configured.
Strategy¶
See comment in commit c9e7e1bdc5a788590e3a378839fbc6e099158a04.
Note: Removing the documented mode
option is an incompatible change,
which simplifies the code by processing each option in the same way.
Since disklayout.conf
is usually re-generated before being edited,
introducing this change seems OK to me.
Tested on Ubuntu 16.04.3 LTS.
jsmeix commented at 2017-09-15 09:36:¶
@OliverO2 only FYI
you may have a look at the related issue
https://github.com/rear/rear/issues/1444
@gozora
I know nothing at all about LUKS so that it is bad luck for you ;-)
that you are curious about how ReaR works with LUKS
https://github.com/rear/rear/issues/1444#issuecomment-324071821
so that I dare to assign this one to you :-)
jsmeix commented at 2017-09-15 09:44:¶
@OliverO2
as far as I see in your comments in your
usr/share/rear/finalize/GNU/Linux/240_reassign_luks_keyfiles.sh
original keyfiles should have been restored from the backup
it means that with this pull request nothing secret
will be added into the ReaR recovery system?
At least not by default without an explicit user setting?
Cf.
https://github.com/rear/rear/pull/1472#issuecomment-328459748
and
https://github.com/rear/rear/issues/1444#issuecomment-324294539
OliverO2 commented at 2017-09-15 10:15:¶
@jsmeix
Yes, no secrets will be added to the rescue medium as stated in the
comment of commit c9e7e1bdc5a788590e3a378839fbc6e099158a04:
Auto-detect 'keyfile' option, enable unattended (password-less)
decryption via temporary keyfile without leaking original keyfiles on
rescue medium, securely re-assign keyfiles after restore.
Also see this comment in 160_include_luks_code.sh.
When you have encrypted disks and you leak secrets onto the unencrypted rescue medium it is like building an expensive underground bank vault and then putting the key into a tin box on your desk. So I just went the extra mile to avoid this.
I agree with https://github.com/rear/rear/pull/1472#issuecomment-328459748 and below.
My next task is actually to provide a ReaR option to encrypt ssh keys which
- currently leak onto ReaR's rescue media, and
- may lack passphrase-protection for unattended operations, and
- may provide access to the central backup repository.
The idea incorporates asking the user for an initial recovery master password (resembling https://github.com/rear/rear/issues/1444#issuecomment-324294539), although I would not recommend putting this into configuration files.
jsmeix commented at 2017-09-15 10:31:¶
@OliverO2
many thanks for your explanation.
As you can also see in
https://github.com/rear/rear/pull/1489#issuecomment-329424147
encryption stuff is not one of my favourite areas of interest.
Accordingly I do very much appreciate it when you check
and even improve those things in ReaR.
I look forward to your ssh improvements.
As long as in etc/rear/local.conf even a dumb
SSH_ROOT_PASSWORD="rear"
still "just works" to "just get" ssh access into the recovery system
I am happy because I use that all the time on my testing systems.
( I do not what to have the "good old times" back when one had
to do special setup to get ssh access into the recovery system. ;-)
OliverO2 commented at 2017-09-25 19:02:¶
@gozora
For me implementing automatic volume unlocking is somehow politic decision, and as I don't like politics I let @schlomo decide whether something like this should or should not be implemented. (c.f. #1444 (comment)).
Isn't that the original system administrator's decision that we just recreate during recovery? He has finally decided to go with crypttab keyfiles after all. Do you think that this decision should be overruled by ReaR?
this PR is broken for systems that don't use automatic unlocking of volumes (which is completely valid setup)
You are right. I'll correct this. Can you point me to the manpage you've used? It seems to be a rather old version of the cryptsetup suite as newer versions (like this one) don't seem to allow verbatim passwords there anymore.
gozora commented at 2017-09-25 19:12:¶
Isn't that the original system administrator's decision that we just recreate during recovery? He has finally decided to go with crypttab keyfiles after all. Do you think that this decision should be overruled by ReaR?
Like I said, for me this is politics, I don't like politics. ReaR is my
spare time project and I don't do thing I don't like in my spare time.
So again, if @schlomo does not object neither me will object.
You are right. I'll correct this. Can you point me to the manpage you've used? It seems to be a rather old version of the cryptsetup suite as newer versions (like this one) don't seem to allow verbatim passwords there anymore.
I don't think so.
Excerpt from http://manpages.ubuntu.com/manpages/xenial/en/man5/crypttab.5.html:
It can also be a device name (e.g. /dev/urandom), note however that LUKS requires a persistent key and therefore does not support random data keys. If the key file is the string “none”, a passphrase will be read interactively from the console. In this case, the options precheck, check, checkargs and tries may be useful.
But to answer your question I've used man crypttab
from CentOS 7.3
OliverO2 commented at 2017-09-25 19:24:¶
OK, I misunderstood this one:
The third field specifies the encryption password.
It initially sounded to me like is was meant to be a verbatim password first, and a path to a keyfile only under certain circumstances. When reading more carefully, it was never really meant to be a password. So they have just improved the explanation in newer incarnations of that manual page.
Anyway, I'll take care of the special cases of 'none' and '-'.
jsmeix commented at 2017-09-26 09:30:¶
A "caution!" regarding running any programs in ReaR
that may (sometimes) do interactive user dialogs like
"a passphrase will be read interactively from the console":
In ReaR interactive user dialogs won't work by default because
both STDERR and STDOUT are redirected into ReaR's log file,
cf. "What to do with stdout and stderr" at
https://github.com/rear/rear/wiki/Coding-Style
OliverO2 commented at 2017-09-26 17:13:¶
@gozora Should work now:
- temporary keyfiles are named after the target (
/dev/mapper
) name, which must be unique none
entries in crypttab are recognized
OliverO2 commented at 2017-09-26 17:23:¶
@jsmeix
I've even tried to use the new UserInput -C
variant to gather a
password in layout/prepare/GNU/Linux/160_include_luks_code.sh
,
replacing the two branches in the elif ... fi
section at the end with:
else
if [ -n "$password" ] ; then
password="$(UserInput -I LUKS_DEVICE_PASSWORD -C -t 0 -p "Please enter the password for LUKS device $target_name ($source_device):")"
fi
echo "echo \"$password\" | cryptsetup luksFormat --batch-mode $cryptsetup_options $source_device"
echo "echo \"$password\" | cryptsetup luksOpen $source_device $target_name"
fi
UserInput works as advertised...
2017-09-26 16:17:10.938445407 UserInput: called in /usr/share/rear/layout/prepare/GNU/Linux/160_include_luks_code.sh line 54
2017-09-26 16:17:10.940826635 UserInput: No choices specified
2017-09-26 16:17:10.942013330 Please enter the password for LUKS device Foxtrot-02 (/dev/sdb1):
2017-09-26 16:17:26.970608078 UserInput: 'read' got user input
...but passwords then appeared in diskrestore.sh
and in the logfile
nonetheless:
+++ echo '2017-09-26 16:18:11.732036596 Creating luks device Foxtrot-02 on /dev/sdb1'
2017-09-26 16:18:11.732036596 Creating luks device Foxtrot-02 on /dev/sdb1
+++ echo abcdef5
+++ cryptsetup luksFormat --batch-mode --cipher aes-xts-plain64 --key-size 512 --hash sha256 --uuid e1949e50-2b2a-46ae-becf-70e0122df4fb --iter-time 2000 --use-random /dev/sdb1
+++ cryptsetup luksOpen /dev/sdb1 Foxtrot-02
+++ echo abcdef5
+++ component_created /dev/mapper/Foxtrot-02 crypt
So I've reverted this change.
schlomo commented at 2017-09-26 17:57:¶
@OliverO2 isn't that in debug mode? Then I would expect the passwords to show up. Users are not expected to use ReaR in debug mode so that regular usage would be save.
OliverO2 commented at 2017-09-26 19:18:¶
@schlomo Invocation was just rear recover
. Neither -d
nor -D
were
used.
Seems like it's in diskrestore.sh
, which begins:
#!/bin/bash
LogPrint "Start system layout restoration."
mkdir -p /mnt/local
if create_component "vgchange" "rear" ; then
lvm vgchange -a n >/dev/null
component_created "vgchange" "rear"
fi
set -e
set -x
Log output looks like this:
2017-09-26 19:09:23.782373730 ======================
2017-09-26 19:09:23.783321212 Running 'layout/recreate' stage
2017-09-26 19:09:23.784120375 ======================
2017-09-26 19:09:23.789236573 Including layout/recreate/default/100_ask_confirmation.sh
2017-09-26 19:09:23.790280158 Please confirm that '/var/lib/rear/layout/diskrestore.sh' is as you expect.
2017-09-26 19:09:24.823612547 User selected: 5) Continue recovery
2017-09-26 19:09:24.827109572 Including layout/recreate/default/200_run_script.sh
2017-09-26 19:09:24.830486207 Start system layout restoration.
/var/lib/rear/layout/diskrestore.sh: line 7: lvm: command not found
+++ create_component /dev/sda disk
+++ local device=/dev/sda
+++ local type=disk
+++ local touchfile=disk--dev-sda
+++ '[' -e /tmp/rear.QUvz5k8O4h9QKwx/tmp/touch/disk--dev-sda ']'
+++ return 0
+++ Log 'Stop mdadm'
++++ date '+%Y-%m-%d %H:%M:%S.%N '
+++ local 'timestamp=2017-09-26 19:09:24.835891725 '
+++ test 1 -gt 0
+++ echo '2017-09-26 19:09:24.835891725 Stop mdadm'
2017-09-26 19:09:24.835891725 Stop mdadm
+++ grep -q md /proc/mdstat
+++ Log 'Erasing MBR of disk /dev/sda'
++++ date '+%Y-%m-%d %H:%M:%S.%N '
+++ local 'timestamp=2017-09-26 19:09:24.838378106 '
+++ test 1 -gt 0
+++ echo '2017-09-26 19:09:24.838378106 Erasing MBR of disk /dev/sda'
2017-09-26 19:09:24.838378106 Erasing MBR of disk /dev/sda
+++ dd if=/dev/zero of=/dev/sda bs=512 count=1
1+0 records in
1+0 records out
512 bytes copied, 0.0308365 s, 16.6 kB/s
+++ sync
[...]
+++ component_created btrfsmountedsubvol:/mnt/reserve btrfsmountedsubvol
+++ local device=btrfsmountedsubvol:/mnt/reserve
+++ local type=btrfsmountedsubvol
+++ local touchfile=btrfsmountedsubvol-btrfsmountedsubvol:-mnt-reserve
+++ touch /tmp/rear.QUvz5k8O4h9QKwx/tmp/touch/btrfsmountedsubvol-btrfsmountedsubvol:-mnt-reserve
+++ set +x
2017-09-26 19:10:02.921303941 Disk layout created.
2017-09-26 19:10:02.923994344 Including layout/recreate/default/250_verify_mount.sh
2017-09-26 19:10:02.928602720 Finished running 'layout/recreate' stage in 39 seconds
2017-09-26 19:10:02.929844149 ======================
2017-09-26 19:10:02.930850913 Running 'restore' stage
2017-09-26 19:10:02.932030174 ======================
schlomo commented at 2017-09-26 19:19:¶
Maybe the code around diskrestore actually enables set -x
permanently.
OliverO2 commented at 2017-09-26 19:32:¶
Apparently, it's layout/prepare/default/540_generate_device_code.sh
.
Nothing for me to mess with at this time ;-).
gozora commented at 2017-09-27 09:41:¶
@OliverO2 thanks for updating this PR.
From my point of view, this improvement works well enough to be merged,
so if there are not other objections I'll merge it next days.
V.
jsmeix commented at 2017-09-27 10:16:¶
Only a side note how to run commands really silently:
To run commands that deal with confidential data
really silently in ReaR see the comment in the
UserInput function that reads:
# If confidential user input is needed also in debugscripts mode the caller of the UserInput function # must call it in an appropriate (temporary) environment e.g. with STDERR redirected to /dev/null like: # { password="$( UserInput -I PASSWORD -C -r -s -p 'Enter the pasword' )" ; } 2>/dev/null
I.e. you need to put confidentially working commands into
an appropriate silencing enviroment for example like
{ root_password="$( grep '^root:' /etc/shadow | cut -d ':' -f2 )" ; } 2>/dev/null { echo "$root_password" ; } 1>/dev/null 2>/dev/null
You cannot rely on that 'set -x' is not somehow set.
The user can set it, a script may set it, whatever else...
gozora commented at 2017-10-04 08:42:¶
@OliverO2 thanks for this improvement!
[Export of Github issue for rear/rear.]