You are not logged in.
Pages: 1
Topic closed
Hello,
My laptop was stolen recently so I'm being extra careful this time to secure my new laptop (a cheap netbook). I've set up dm-crypt with LUKS following the guide on the ArchWiki but there's still the risk of cold-boot attacks.
To address that, I'm trying to follow the Tails live distro's approach of using the smem(1) tool from the secure-delete AUR package to wipe my RAM as the last step before my system halts (for both normal shutdown and for suspend-to-disk cases).
In particular, I need to somehow integrate this script into the Arch boot process. Any tips?
Thanks in advance.
Last edited by sunaku (2012-02-21 22:51:50)
Offline
/etc/rc.local ?
CPU-optimized Linux-ck packages @ Repo-ck • AUR packages • Zsh and other configs
Offline
/etc/rc.shutdown ? Not sure if it works for hibernation too.
Offline
At least for reboot/shutdown case, write a customized shutdown mkinitcpio hook. Something like "secure_shutdown" Should add /usr/bin/sdmem, and merge "shutdown" script with your script, should ensure thats run on ash.
Offline
Thanks for the hints, everyone. I ended up creating the following script, which works for the normal shutdown case.
/etc/rc.d/functions.d/shutdown_ramwipe
#!/bin/sh
#
# Wipes the system's RAM before shutting down in
# order to reduce the risk of cold-boot attacks.
#
# https://tails.boum.org/contribute/design/memory_erasure/
#
shutdown_ramwipe() {
# sysctl tweaks to prevent smem from crashing
# http://git.immerda.ch/?p=amnesia.git;a=blob_plain;f=config%2Fchroot_local-includes%2Fusr%2Fshare%2Finitramfs-tools%2Fscripts%2Finit-premount%2Fsdmem
echo 3 > /proc/sys/kernel/printk
echo 3 > /proc/sys/vm/drop_caches
echo 256 > /proc/sys/vm/min_free_kbytes
echo 1 > /proc/sys/vm/overcommit_memory
echo 1 > /proc/sys/vm/oom_kill_allocating_task
echo 0 > /proc/sys/vm/oom_dump_tasks
/usr/bin/smem -v -ll
}
add_hook shutdown_poweroff shutdown_ramwipe
I'm currently converting this into a pm-hibernate hook, but it's a little more tricky because the sysctl tweaks need to be reverted after resuming from hibernate.
Last edited by sunaku (2012-02-22 07:48:46)
Offline
If you are using encryption for /, the key is still in memory. Thats is why I recommended to be done via shutdown tmpfs.
Offline
Good point @djgera. My root filesystem is indeed encrypted so this memory wipe (as currently implemented) really doesn't help; in fact, it makes it easier for attackers to find the encryption key because all other memory is wiped (set to zero).
What is this "shutdown tmpfs" method you mention? I didn't see it on the ArchWiki page for LUKS.
I guess I need to copy the smem(1) binary into a tmpfs, then unmount the root filesystem, and finally wipe the memory, correct?
Last edited by sunaku (2012-02-22 18:08:20)
Offline
Ok I done for you. Please test, and maybe you want to add to the wiki They are just "shutdown" hook plus added what you need.
You need to add wiperam_on_shutdown to your mkinitcpio.conf HOOKS.
/lib/initcpio/hooks/wiperam_on_shutdown
#!/usr/bin/ash
run_hook() {
cp -ax / /run/initramfs
}
# vim: set ft=sh ts=4 sw=4 et:
/lib/initcpio/install/wiperam_on_shutdown
#!/bin/bash
build() {
BINARIES='cp'
SCRIPT='wiperam_on_shutdown'
add_file "/lib/initcpio/wiperam_on_shutdown" "/shutdown"
add_binary "/usr/bin/smem"
}
help() {
cat <<HELPEOF
Secure shutdown using smem to wipe RAM.
HELPEOF
}
# vim: set ft=sh ts=4 sw=4 et:
/lib/initcpio/wiperam_on_shutdown
#!/usr/bin/ash
findmnt -Rruno TARGET /oldroot | awk '
BEGIN { i = 0 }
! /^\/(proc|dev|sys)/ {
i++
mounts[i] = $0
}
END {
for (j = i; j > 0; j--) {
print mounts[j]
}
}
' | while read -r mount; do
umount -l "$mount"
done
# sysctl tweaks to prevent smem from crashing
# http://git.immerda.ch/?p=amnesia.git;a=blob_plain;f=config%2Fchroot_local-includes%2Fusr%2Fshare%2Finitramfs-tools%2Fscripts%2Finit-premount%2Fsdmem
echo 3 > /proc/sys/kernel/printk
echo 3 > /proc/sys/vm/drop_caches
echo 256 > /proc/sys/vm/min_free_kbytes
echo 1 > /proc/sys/vm/overcommit_memory
echo 1 > /proc/sys/vm/oom_kill_allocating_task
echo 0 > /proc/sys/vm/oom_dump_tasks
smem -v -ll
case $1 in
reboot)
type kexec >/dev/null && kexec -e
reboot -f
;;
poweroff|shutdown|halt)
"$1" -f
;;
*)
poweroff -f
;;
esac
Offline
Thanks djgera. Copying the necessary binaries into the boot image seems like the proper approach. In the mean time, I developed a simpler solution of wiping only the LUKS encryption key from memory (luksSuspend) instead of doing a brute-force wipe of all memory (smem):
--- /etc/rc.shutdown.bak 2012-02-09 13:04:47.000000000 -0800
+++ /etc/rc.shutdown 2012-02-22 15:37:54.461985929 -0800
@@ -129,14 +129,18 @@
printsep
if [[ $RUNLEVEL = 0 ]]; then
printhl "${C_H2}POWER OFF"
- poweroff -d -f -h -i
+ poweroff -d -f -h -i &
else
printhl "${C_H2}REBOOTING"
# if kexec is installed and a kernel is loaded, use it
[[ -x $(type -P kexec) ]] && kexec -e &>/dev/null
- reboot -d -f -i
+ reboot -d -f -i &
fi
+ stat_busy "Wiping Encryption Keys from Memory"
+ /sbin/cryptsetup luksSuspend root &&
+ ! /sbin/cryptsetup luksResume root --key-file /dev/null &&
+ stat_done || stat_fail
fi
# End of file
I made the above changes to my /etc/rc.shutdown file and it seems to work.
Last edited by sunaku (2012-02-23 00:01:52)
Offline
1) All things after poweroff/reboot, will never be executed. (maybe in some exceptional case where there is a delay.......)
2) Such command can not be used where cryptsetup reside.
If you do not want to use smem now, then add cryptsetup to shutdown tmpfs instead and execute what your want at that point
Offline
1. You are correct about the race condition. By coincidence, on my system, there is enough time after halt/reboot is backgrounded to wipe the encryption key and also verify the wipe.
2. True, that's what the man page said. But that is only a problem if you want to luksResume the suspended device. In this case, we are rebooting or halting so there will be no further access of the encrypted device.
3. The /lib/initcpio/install/encrypt script already puts cryptsetup into the mkinitcpio image. Could I use this somehow?
And in your previous example, I did not understand how and when /lib/initcpio/wiperam_on_shutdown is called. Is it triggered by the SCRIPT='wiperam_on_shutdown' line in the /lib/initcpio/install/wiperam_on_shutdown file?
Offline
1) Exactly!
2) OK, anyway does not look good and you are using luksResume, maybe you work because cryptsetup is cached from previous execution.
3) True. Yes.
Is called from /etc/rc.shutdown if -x /run/initramfs/shutdown. (this is created/copied at boot time (in initramfs) via the shutdown hook, in our case with hooks/wiperam_on_shutdown)
Offline
I researched and experimented on ways to apply the memory wiping before hibernation but it seems that nothing is possible from user space. The underlying hibernation command (echo disk > /sys/power/state) is an atomic, blocking call that causes the machine to halt or reboot according to the value of /sys/power/disk.
I will try to patch the kernel to wipe all memory just before halting/rebooting when it services the hibernation command. How do you folks maintain patches to your Arch kernel? Using ABS? I have so much to learn.
Last edited by sunaku (2012-02-23 08:55:54)
Offline
Bump
I made something like that.
If someone interested... https://github.com/zezadas/ramClean
Offline
Thanks, zezadas.
Given that this thread discusses solutions based on the old init system, I think it's time to close it.
My Arch Linux Stuff • Forum Etiquette • Community Ethos - Arch is not for everyone
Offline
Pages: 1
Topic closed