Adding remote SSH passphrase entry to LUKS

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

First, I want to say that you project seems really cool. Standardizing 
encrypted disk setup is an important step towards information confidentiality.

Have you thought about adding the possibility to enter the passphrase remotely
when the system boots ? It would be very useful for servers for which physical
access is not easy.

I have done an implementation of this a few years ago. It uses a first non
encrypted base system that sets up the network interface and runs ssh. Then,
when booted, it waits for the administrator to start a script that asks for the
passphrase, mount the crypted disks (including the new root) and calls a
pivot_root to switch to the new system.

If you ever think of distributing this, I suggest to implement this as an
initrd (which I haven't done). Some scripts should be made to update the
content of the initrd (ssh, root password, ssh keys) easily.

Here is the code. There are probably bugs and security issues, so please
consider it alpha. The first program is written in C and should be used instead
of /bin/init. The following are helper scripts that runs in the base
unencrypted root. The "startsys" program should probably be written in C so we
can be sure that the KEY variable is wiped from memory.

Mathieu

----
/* cryptwait.c
 *
 * Daemon that takes PID 1, fork and start a script, and wait for a signal to
 * execute init.
 *
 * Copyright 2005 - Mathieu Desnoyers
 *
 * Licensed under GPLv2.
 */

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>

/* signal handler */
void handler(int signo)
{
	printf("received signal killing all \n");
	kill(-1, SIGKILL);
	wait(NULL);
	printf("all killed exec /sbin/init\n ");
	execl("/sbin/init","init",(char*)NULL);
}

void sigchild_handler(int signo)
{
	wait(NULL);
}


int main(int argc, char ** argv)
{
	pid_t pid;
	static struct sigaction act, child_act;


	pid = fork();

	if(pid == 0) {
		/* child : executes script */
		execl("/bin/sh","sh","/root/waitssh",(char*)NULL);

	} else if( pid > 0) {
		/* parent : wait for signal. */
		act.sa_handler = handler;
		sigemptyset(&(act.sa_mask));
		sigaddset(&(act.sa_mask), SIGUSR1);
		sigaction(SIGUSR1, &act, NULL);

		child_act.sa_handler = sigchild_handler;
		sigemptyset(&(child_act.sa_mask));
		sigaddset(&(child_act.sa_mask), SIGCHLD);
		sigaction(SIGCHLD, &child_act, NULL);
		
		// Wait for signals.. forever...
		while(1) pause();
	} else {
		/* error : exec init directly */
		execl("/sbin/init","init",(char*)NULL);
	}

	return 0;
}
----

#!/bin/sh
#
# waitssh
#
# Script ran in the unencrypted root : starts the network interfaces, ssh and a
# local tty, waits for someone to log in.
#
# Mathieu Desnoyers 11/5/2005 - GPLv2

mount / -o remount,rw
mount /proc
/etc/init.d/hostname.sh

# don't care about /etc/network/ifstate
/etc/init.d/fullduplex
ifup eth0 --force
ifup eth1 --force 

/etc/init.d/ssh start 
while ((1)); do /sbin/getty 38400 tty1; done

----

#!/bin/sh
#
# startsys
#
# Script that asks from the passphrase, maps the dm-crypt partitions, mounts
# them, kills all the running processes, pivots / to the crypted root and
# signals the PID 1 (cryptwait) that the system is ready to execute /bin/init.
#
# Mathieu Desnoyers 11/5/2005 - GPLv2

MAPFROM=/dev/sda4
MAPNAME=_dev_sda4
MAPDEV=/dev/mapper/${MAPNAME}

MAPFROM1=/dev/sda3
MAPNAME1=_dev_sda3
MAPDEV1=/dev/mapper/${MAPNAME1}


#this is the VFS point where the new root must be mounted before the pivot
CRYPTROOT=/mnt/cryptroot
#this is the new VFS location of the old root in the VFS (as seen after pivot)
BASEROOT=/mnt/baseroot

#ask for all passphrases
echo "Please enter the passphrase for all the filesystems"
KEY=`/usr/sbin/hashalot sha256`

#ask for / passphrase
echo "Creating ${MAPFROM} mapping... "
echo "${KEY}" | cryptsetup -c aes-cbc-essiv:sha256 -d /dev/stdin create ${MAPNAME} ${MAPFROM}
echo -n "Mounting ${MAPDEV} filesystem... "
mount ${MAPDEV} ${CRYPTROOT}
if (( $? != 0 )); then
	cryptsetup remove ${MAPNAME}
	echo failed.
	exit -1
else
	echo success.
fi

#setting swap
echo "Setting up swap.. "
cryptsetup -c aes-cbc-essiv:sha256 -d /dev/urandom create ${MAPNAME1} ${MAPFROM1}
mkswap ${MAPDEV1}

#will remount it later...
#umount ${CRYPTROOT}

# stopping all services

#for script in /etc/rc0.d/*
#do
#	if ( [ x"${script}" != x"/etc/rc0.d/S90halt" ] && [ x"${script}" != x"/etc/rc0.d/S50mdadm-raid" ]  && [ x"${script}" != x"/etc/rc0.d/S48cryptdisks" ] )
#	then 
#		#echo $script
#		$script stop
#	fi
#done
#
#umount everything but /
#umount /dev/pts
#umount /sys
ifdown eth0
ifdown eth1
umount /proc
mount / -o remount,ro

#/bin/bash #testing...

#echo -n "Mounting ${MAPDEV} filesystem... "
#mount ${MAPDEV} ${CRYPTROOT}
#if (( $? != 0 )); then
#	echo -n "failed. rebooting..."
#	reboot
#else
#	echo success.
#fi


echo -n "pivot_root to new root filesystem... "
cd ${CRYPTROOT}
pivot_root . ${CRYPTROOT}${BASEROOT}

#remount baseroot rw for depmod -a
mount / -o remount,rw
echo finish.

# starting services
#echo -n "Starting services..."

#for script in /etc/rcS.d/*
#do
#	$script start
#done
#
#for script in /etc/rc2.d/*
#do
#	$script start
#done
#echo "Unmounting ${BASEROOT}"
#exec chroot . sh -c "umount ${BASEROOT}; exec /sbin/init"\
#	< /dev/console >/dev/console 2>&1

#S11remountbase will remount in rcS.d
umount -l ${BASEROOT}
#reset memory for KEY (256 bits)
KEY=0000000000000000000000000000000000000000000000000000000000000000
echo -n "Sending signal to cryptwait"
kill -s USR1 1

----

#!/bin/sh
# mountdrv
#
# Mounts the encrypted drives so they can be accessed from within the running
# base unencrypted system.
#
# Mathieu Desnoyers 11/5/2005 - GPLv2

MAPFROM=/dev/sda4
MAPNAME=_dev_sda4
MAPDEV=/dev/mapper/${MAPNAME}

#this is the VFS point where the new root must be mounted before the pivot
CRYPTROOT=/mnt/cryptroot
#this is the new VFS location of the old root in the VFS (as seen after pivot)
BASEROOT=/mnt/baseroot

#ask for all passphrases
echo "Please enter the passphrase for all the filesystems"
KEY=`/usr/sbin/hashalot sha256`

#ask for / passphrase
echo "Creating ${MAPFROM} mapping... "
echo "${KEY}" | cryptsetup -c aes-cbc-essiv:sha256 -d /dev/stdin create ${MAPNAME} ${MAPFROM}
echo -n "Mounting ${MAPDEV} filesystem... "
mount ${MAPDEV} ${CRYPTROOT}
if (( $? != 0 )); then
	cryptsetup remove ${MAPNAME}
	echo failed.
	exit -1
else
	echo success.
fi

----

-- 
OpenPGP public key:              http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint:     8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68 

---------------------------------------------------------------------
dm-crypt mailing list - http://www.saout.de/misc/dm-crypt/
To unsubscribe, e-mail: dm-crypt-unsubscribe@xxxxxxxx
For additional commands, e-mail: dm-crypt-help@xxxxxxxx


[Index of Archives]     [Device Mapper Devel]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]     [Fedora Docs]

  Powered by Linux