My Awesome Secure and Portable System (2009)

Many people have asked about how my incredibly complex, but awesome personal operating system works. It's so complicated that I can usually only explain it in little bits, and I always forget to mention one of the many things that make it awesome. Instead of coming up with everything on the fly, I'm writing this article to explain, in depth, how my system works, what makes it awesome, and provide the scripts and configurations I've written to make this system work.

For those who aren't as technically inclined, I'll start with a general overview and a neat-o feature list. This isn't something your grandmother will be able to read, it still requires some knowledge of the inner workings of computers. As for the one person who might be able to understand how the technical details work and want to attempt to replicate my system, everything will be laid out in detail after that.
Table of Contents
Rough Overview

Technical Details
  I: Partitioning
    I.a: Primary Partition 2
    I.b: Logical Partition 5
      I.b.i: grml.sh
      I.b.ii: smount
      I.b.iii: .ss
    I.c: Logical Partition 6
  II: Secure Home (/home/sechome/)
    II.a: /home/sechome/addons/
    II.b: /home/sechome/grml/
      II.b.i: /home/sechome/grml/system-work
      II.b.ii: /home/sechome/grml/virtfs-init
  III: Virtual Directories
    III.a: /home/sechome/grml/static-copy
  IV: Backups
  V: Synchronization
    V.a: /home/sechome/grml/sync-os
  VI: Miscellaneous Security
      VI.a: root User
      VI.b: Console Security
      VI.c: /home/sechome/grml/my-grml-x
  VII: Flaws in the System
    VII.a: Remote Attacks
    VII.b: Physical Attacks
    VII.c: Security Upgrades

Appendices
  A1: Password-File Generation

Version Info and Changelog
Rough Overview
I designed this system with both security and portability in mind. My system uses a Linux kernel and the entire thing, applications, personal data, etc, takes up 1GB of space. It is split up into two parts, the operating system, and my personal data. The operating system is a 700MB live-CD, GRML, that generates a completely fresh install every single time I boot up the computer. Doing this means that if my system is ever hacked into, a simple restart of my computer fixes the problem. This also means that any configuration changes made or private information stored by any application, restarting reverts everything to a clean slate.

This leaves 300MB for personal data, which might not sound like much, but when you cut out all multimedia files and store them elsewhere, this is quite a lot. At the time of writing, I currently use 96MB of this, most of which is addon packages to improve functionality of the operating system.

The personal data is encrypted using an AES-256 algorithm. The password I type in actually unlocks a special encrypted file which unlocks the real encryption information, meaning that my actual password is never stored in RAM (more specifically, DRAM). To prevent highly sensitive information from being discovered by remote hackers, which this layer of encryption would not protect against, an extra layer of encryption using either GPG or AES-256 provides two layers of encryption for highly sensitive data.

Because the system is so small, I have a backup script that generates compressed, encrypted backups that can be uploaded and stored anywhere. This only backs up the personal data portion, which contains all of my system configuration and personal data. The operating system can just be redownloaded, so it is unnecessary to backup. This means that my backup files are approximately 30-50MB in size, and are extremely portable.

Also along the lines of portability, since the entire operating system and data is 1GB total, I have a small USB drive that I carry around with me that contains a complete copy of my entire system. By plugging it into any computer which supports USB booting (most computers do), I can use my system anywhere. I wrote a synchronization script to keep the USB drive up to date, so at all times it has all of my most recent data. If I make any changes to it, I can synchronize it back to my main system, so it is fully editable when I'm not on my main system.
Technical Details
Be warned, do NOT try to build this system unless you are prepared to work on it for days. This system is the result of an ongoing two years work, so don't get mad or frustrated if you can't get it to work. Extensive Linux and shell scripting experience is required for getting this working, since this is not a step-by-step tutorial but a detailed system outline and my system is so tightly intertwined. Chances are, even some kernel hackers might have problems getting this working properly, though most should be able to figure it out. This shouldn't be too difficult to follow if you are just reading, though. This is more for my personal reference and curious minds.

I will be describing how my USB drive is set up for most of this technical outline. My main system has so many weird partitions that explaining that would provide tons of unnecessary information. These scripts have been tested with, and assume usage of GRML version 1.1.

DISCLAIMER: I am not responsible if you destroy your computer trying to recreate this system.
I: Partitioning
In the overview, I said the system is divided into two parts: the operating system, and personal data. This is not entirely true. There are actually three partitions associated with this. The remaining space on my USB drive is allocated for standard USB space for transferring data and other general data storage purposes.

Partition Table:
primary partition 1 - FAT32 - ~7GB
primary partition 2 - FAT32 - ~750MB - boot flag
logical partition 5 - FAT32 - ~3MB
logical partition 6 - AES-256 ENCRYPTED ext2 - ~300MB

Primary partition 1 is the extra partition used for standard USB storage.
I.a: Primary Partition 2
This partition is simply a direct copy of the contents of the GRML live-CD, and has the boot flag set so that it is the partition booted.

The Syslinux configuration was modified slightly to take advantage of some boot-options GRML provides. For the startup scripts to work correctly, the partition the scripts are located on needs to be specified with the "myconfig" boot option to GRML. Because of this, there are three different boot options that I have available. The first is for my main system, the second is for booting from USB on a computer that has a SCSI drive, and the third is for booting from USB on a computer that has an ATA/IDE drive or no drive. The reason the difference exists for the second and third options is that the USB device will be detected after any SCSI devices, and will get a different name depending on the system. The second option uses "myconfig=/dev/sdb5", and the third option uses "myconfig=/dev/sda5", both referencing Logical Partition 5 on the USB device.
I.b: Logical Partition 5
This partition is the one unmentioned in the overview. This partition contains startup scripts to initialize the encryption, and stores the encrypted file containing the real password information.

Directory Listing:
-rwxr-xr-x 1 root root     798 2007-09-21 00:17 grml.sh
-rwxr-xr-x 1 root root    1378 2007-09-21 00:17 smount
-rwxr-xr-x 1 root root 1048576 2008-03-10 20:22 .ss
I.b.i: grml.sh
The "myconfig" boot-option is provided by Primary Partition 2, and GRML executes "grml.sh" in the partition specified (this one).

This file mounts the Secure Home directory from .ss using smount, removes the GRML device from the fstab, executes system-work, then disables the grml-quickconfig script which comes up on startup for a normal GRML boot.

system-work is not directly executed. "grml.sh" is called in the middle of the standard GRML startup, so some of the other GRML startup commands are executed after "grml.sh". system-work must be executed after all of these startup commands, so the only way around all of this is to overwrite root's ".zshrc" with a call to system-work. By doing this, GRML will execute all startup commands, start up zsh like normal, then execute system-work at the proper time.

Contents: grml.sh
#!/bin/bash

# get running grml partition
grml_part="`mount | grep " on /mnt/grml " | cut -d ' ' -f1`"
grml_partnum="`echo $grml_part | sed -r "s/.*([0-9]+)/\1/g"`"
grml_dev="`echo $grml_part | sed -r "s/(.*)[0-9]+/\1/g"`"
grml_part="$grml_dev$grml_partnum"

# get the device partition plus X
function grml_devplus(){
	new="$grml_partnum"
	let new+=$1
	echo $grml_dev$new
}

# mount secure home
clear
bash /mnt/grml/smount /mnt/grml/.ss "`grml_devplus 1`" /home/sechome 0

# /etc/fstab fixer
mv /etc/fstab /etc/fstab.old
cat /etc/fstab.old | grep -v "`grml_devplus 0`" > /etc/fstab
rm /etc/fstab.old

# system-work
echo "bash /home/sechome/grml/system-work "`grml_devplus 0` > /root/.zshrc

# disable grml-quickconfig
echo > /usr/sbin/grml-quickconfig
I.b.ii: smount
The "smount" file is used to mount a helper file/partition, then use the files within to mount a secure partition. This, as described earlier, ensures that the real password is not stored in RAM or DRAM, and makes a harder to crack main partition (in theory, anyway). "smount" takes three or four arguments. The first is the helper file, the second is the data partition, and the third is the destination mount point. An optional fourth argument can be specified which tells the script how many times the use has to guess the correct password before failing. The default is 4, and 0 means try forever (0 is passed in from grml.sh).

Contents: smount
#!/bin/bash

# these aren't the values I use
LO_ICK_UNLOCK=1234
LO_ICK_REAL=5678

unlock_source="$1"
data_source="$2"
destination="$3"

# total tries
if [ -z "$4" ]; then tottries="4"; else tottries="$4"; fi
if [ "$4" = "0" ]; then tottries=""; fi

# get new loopback device
function get_loopdev(){
	loop_devs=`ls -d /dev/loop*`
	for loop_dev in $loop_devs; do
		[ ! -b "$loop_dev" ] && continue
		ret="`losetup $loop_dev 2> /dev/null`"
		[ -z "$ret" ] && echo $loop_dev && break
	done
}

# quit cleanly
function quit_clean(){
	umount /tmp/usbtemp &> /dev/null
	losetup -d $unlock_loop &> /dev/null
	rmdir /tmp/usbtemp
	exit
}

# secure home
if [ -e "$unlock_source" ] && [ -e "$data_source" ]; then

	# modules
	modprobe cryptoloop
	modprobe aes_i586

	# home-setup
	unlock_loop="`get_loopdev`"
	mkdir /tmp/usbtemp

	tries=0
	while
		[ ! -e "/tmp/usbtemp/pwfile" ] &&
		([ -z "$tottries" ] || [ "$tottries" -gt "$tries" ])
	do
		losetup -d $unlock_loop &> /dev/null
		losetup -e aes-256 -C $LO_ICK_UNLOCK $unlock_loop $unlock_source
		mount $unlock_loop /tmp/usbtemp &> /dev/null
		let tries+=1
	done

	if [ ! -e "/tmp/usbtemp/pwfile" ]; then quit_clean; fi

	home_loop="`get_loopdev`"
	[ ! -d "$destination" ] && mkdir "$destination"

	cat /tmp/usbtemp/pwfile | \
	losetup -e aes-256 -C $LO_ICK_REAL -p 0 -S "`cat /tmp/usbtemp/seedfile`" \
	$home_loop $data_source

	mount $home_loop "$destination"
	chown root.root "$destination"
	chmod 755 "$destination"

	quit_clean

fi
I.b.iii: .ss
The ".ss" file is the encrypted helper file. grml.sh calls smount with this file as a parameter, using it to mount the actual partition. ".ss" is read using it as an encrypted loopback file (Linux cryptoloop module), then has it's own encrypted FAT32 filesystem within it. This can be seen by examining grml.sh and smount in detail.

Directory Listing:
-rwxr-xr-x 1 root root 73 2006-03-18 16:32 pwfile
-rwxr-xr-x 1 root root 73 2006-03-18 16:34 seedfile

"pwfile" is a file containing the password string for the real encrypted partition, and "seedfile" is a file containing the seed string for the real encrypted partition. These are used by smount.

Contents: pwfile and seedfile
What, do you think I'm stupid?  I'm not giving you this!

These files are intentionally complex to improve the encryption. Because these files are so complex, I developed a system for regenerating them if I ever need to. For more information about my password-file generation method, see A.1: Password-File Generation.
I.c: Logical Partition 6
This partition is mounted through smount, and is an encrypted ext2 filesystem which contains all of the important stuff. The contents of this partition are described in detail later in Secure Home.
II: Secure Home (/home/sechome/)
The secure home directory (/home/sechome/) is where everything important is stored. When Backups are made, this directory is tarred up and encrypted.

Directory Listing of /home/sechome/:
drwxr-xr-x  2 root root 1024 2008-03-09 13:34 addons/
drwx------  5 grml grml 2048 2008-02-04 16:52 docs/
drwxr-xr-x  3 root root 1024 2008-03-09 13:56 grml/
drwxr-xr-t 17 grml grml 1024 2008-01-06 08:39 proj/
drwxr-xr-t  4 grml grml 2048 2007-10-25 11:12 scripts/
drwx------  6 root root 1024 2006-08-06 08:53 .staticfs/
drwx-----T 19 root root 1024 2008-03-10 20:13 .statichome/
drwx-----T  6 root root 1024 2008-03-09 14:24 .staticroot/
drwxr-xr-x 23 grml grml 3072 2008-02-13 18:27 www/

This is not a complete directory listing of this directory. I took some things out that are completely irrelevant, and left some other irrelevant things in for examples of how this could be used.

For instance, "docs" is just a directory to store documents. "proj" is a directory to store GIT repositories of my projects. "scripts" is a ton of scripts that are useful, but I've never taken the time to make full projects out of them. "www" is the document root for apache2, with some symbolic links to other locations such as Surrogafier in "proj". "proj" and "scripts" have the sticky-bit set so that GIT or even I don't create files that are root owned on accident.

Please note, this is NOT the user's home directory. This is a backend directory that stores everything. The user's home directory is dynamically generated, and more information about this as well as the directories ".staticfs", ".statichome", and ".staticroot" can be found later in Virtual Directories.
II.a: /home/sechome/addons/
Used by system-work, this directory contains a cramfs loopback file that contains installed addon Debian packages. This cramfs filesystem is appended to the aufs root filesystem.
II.b: /home/sechome/grml/
The "grml" directory stores scripts that help set up and maintain the system.

Directory Listing of /home/sechome/grml/:
drwx------ 2 root root 16384 1969-12-31 18:00 booter/
-rwx------ 1 root root   167 2008-03-15 12:04 local-startup-after
-rwx------ 1 root root   197 2008-03-15 12:06 local-startup-before
-rwxr-xr-x 1 root root 33478 2008-03-09 14:39 my-grml-x
-rwx------ 1 root root  1227 2008-03-15 14:08 static-copy
-rwx------ 1 root root  2384 2008-03-14 15:32 sync-os
-rwx------ 1 root root   850 2008-03-15 12:06 system-work
-rwx------ 1 root root   282 2008-03-14 15:31 virtfs-init

"booter" is a directory that is bind mounted by system-work to Logical Partition 5. This directory is there for the Backups system to be able to backup all data associated with the system.

"local-startup-after" and "local-startup-before" are files containing other startup commands that only apply to me, so they aren't given in this document. "local-startup-before" is called at the start of system-work, and "local-startup-after" is called at the end.

my-grml-x is described in depth under Miscellaneous Security.

static-copy is described in depth under Virtual Directories.

sync-os is described in depth under Synchronization.
II.b.i: /home/sechome/grml/system-work
This file is called by grml.sh, and initializes the userland part of the system.

This file calls a local startup file, then mounts /dev/sda1 on /vault/. This directory will always contain the main partition of the local drive, or if the drive is ATA/IDE based and I'm booting from my USB drive, primary partition 1 of my USB drive. This is usually the place multimedia and other documents would be stored on the computer I'm working on.

From here, extra Debian addon packages are appended to the aufs root filesystem from /home/sechome/addons/.

virtfs-init is called, then the "booter" directory is mounted for the Backups system. Then some work is done for my-grml-x and more local startup commands are run.

This file ends by killing zsh. The reason for this is that grml.sh initializes this file by calling bash from ".zshrc". After this file is done, virtfs-init will have replaced root's ".zshrc" with the one in ".staticroot", as described in Virtual Directories. Therefore, zsh needs to be restarted so the right configuration file will be used. After this step, the user has control of the system after logging in due to the Console Security. my-grml-x can be called, or whatever the user wants to do.

Contents: /home/sechome/grml/system-work
#!/bin/bash

# local-startup-before
bash /home/sechome/grml/local-startup-before

# /vault
mount /dev/sda1 /mnt/sda1
[ ! -z "`ls /mnt/sda1`" ] && mkdir /vault && mount --bind /mnt/sda1 /vault

# setup addons cramfs, then append to aufs
if [ -e "/home/sechome/addons/addons.cramfs" ]; then
	mkdir /live/addons
	cp /home/sechome/addons/addons.cramfs /live/addons.cramfs
	mount -o loop -t cramfs /live/addons.cramfs /live/addons
	mount -o remount,append:/live/addons=ro /
fi

# initialize virtual filesystem stuff
bash /home/sechome/grml/virtfs-init

# mounts the 'boot' partition to an easily accessed and backed up directory
bootdev="$1"
bootname="`echo "$bootdev" | cut -d '/' -f3`"
mount $bootdev /mnt/$bootname
mount --bind /mnt/$bootname /home/sechome/grml/booter

# my-grml-x
ln -s /home/sechome/grml/my-grml-x /usr/bin/my-grml-x

# local-startup-after
bash /home/sechome/grml/local-startup-after

# teh edn
(sleep 0.5; killall -9 zsh) &
disown
II.b.ii: /home/sechome/grml/virtfs-init
This file creates the process described in Virtual Directories. There is an optional argument, "nofs", which will prevent the script from utilizing ".staticfs". This option is used by sync-os.

Contents: /home/sechome/grml/virtfs-init
#!/bin/bash

# home-work
rm -rf /home/grml
cp -r /home/sechome/.statichome /home/grml
chown -R grml.grml /home/grml

# root-work
rm -rf /root
cp -r /home/sechome/.staticroot /root
chown -R root.root /root

# fs-work
if [ "$1" != "nofs" ]; then
	cp -r /home/sechome/.staticfs/* /
fi
III: Virtual Directories
Any application can store logs, private information, and other random status files in a user's home directory. These files are unnecessary for the most part, and can increase wear on a device such as a USB drive, especially if all of the information is to be encrypted before being stored. To prevent unnecessary wear, and to reduce logging of personal data, I leave the user's home directory as a part of the ramdisk generated by the operating system. The directories ".statichome" and ".staticroot" are copied over to the ramdisk by virtfs-init, then any changes that are made by any application are removed when the system is shut down. The same thing is done for the root filesystem ("/") with the directory ".staticfs".

Examples of what could be in a static home directory are basically anything that would be in a user's home directory, such as various configuration directories and files. The extra directories such as "docs" for storing documents and such as described in Secure Home can be symbolically linked to in ".statichome". That way documents can be organized into logical categories and not be required to be saved like configuration files.

Because some configuration changes might need to be stored permanently, there needs to be a system to store configuration files in the static directories. This functionality is provided by the "save-fs", "save-home", and "save-root" commands.

Since the separation between dynamic and static files exists anyway, another set of commands is provided to revert the files in the dynamic directory back to the static versions. These commands are "revert-fs", "revert-home", and "revert-root".

These commands can only be run as root, and are stored as aliases in root's ".zshrc". These aliases are aliases for different argument calls to the script static-copy.

Alias Definitions:
alias revert-fs="/home/sechome/grml/static-copy revert /home/sechome/.staticfs /"
alias revert-home="/home/sechome/grml/static-copy revert /home/sechome/.statichome /home/grml"
alias revert-root="/home/sechome/grml/static-copy revert /home/sechome/.staticroot /root"
alias save-fs="/home/sechome/grml/static-copy save /home/sechome/.staticfs /"
alias save-home="/home/sechome/grml/static-copy save /home/sechome/.statichome /home/grml"
alias save-root="/home/sechome/grml/static-copy save /home/sechome/.staticroot /root"

The user would type out one of these aliases, and follow it with a file that they wish to save or revert.
III.a: /home/sechome/grml/static-copy
This file saves and reverts files to and from the static directories. This command requires 4 arguments.

The first argument specifies what action is to be taken, "save" or "revert".

The second argument specifies the static directory associated with the action.

The third argument specifies the dynamic directory associated with the action.

The fourth argument specifies the filename of the file to be copied in either direction. In the alias definitions, these are left off and the user specifies which file is to be stored.

NOTE: Be extremely careful with this command, and in fact, I recommend never calling this command directly. Use the aliases provided above, unless you really know what you are doing. The reason for this is that "rm -rf" is called within the file, and if you type in something that I didn't think of preventing, you could destroy your computer. I've attempted to prevent obvious problems such as "/" and "/*", but you could still do damage if you type in the wrong thing.

Contents: /home/sechome/grml/static-copy
#!/bin/bash

command="$1"
staticdir="$2"
dynamicdir="$3"
filename="$4"

if [ -z "$filename" ]; then
	echo Error: No file specified.
	exit
fi

if [ -z "$staticdir" ]; then
	echo Error: No static directory specified.
	exit
fi

if [ -z "$dynamicdir" ]; then
	echo Error: No dynamic directory specified.
	exit
fi

if [ "${filename:0:1}" = "*" ]; then
	echo "Error: That could be dangerous... catastrophe averted."
	exit
fi

if [ "$command" = "revert" ]; then
	origindir="$staticdir"
	destdir="$dynamicdir"
	prompt="Really revert file '$filename' to static directory version? "
	waitmsg="Reverting file to static directory version... "
elif [ "$command" = "save" ]; then
	origindir="$dynamicdir"
	destdir="$staticdir"
	prompt="Really save current file '$filename' to static directory? "
	waitmsg="Saving file to static directory... "
else
	echo Error: Unknown command.
	exit
fi

[ ! -e "$origindir/$filename" ] && \
echo "No such file or directory '$filename' in '$origindir'" && exit

echo -n "$prompt"
choice=`bash -c "read -n 1 choice; echo \\$choice"`
echo

if [ "$choice" = "y" ]; then
	echo -n "$waitmsg"
	rm -rf "$destdir/$filename"
	cp -ar "$origindir/$filename" "$destdir/$filename"
	echo Done
else
	echo Quitting
fi
IV: Backups
The system is set up so that everything is contained within /home/sechome/. The only thing that isn't in this directory is the boot partition, which is why system-work bind mounts this partition to /home/sechome/grml/booter/.

Since everything is contained like this, a simple compressed tar archive can be created, piped through aes-pipe, and stored as a file. Decryption, too, is as simple as piping the contents of a file through aes-pipe, then back through the tar command. Because this is such a simple operation, these commands, "encbkup" and "decbkup", can be expressed as simple functions in ".zshrc".

"encbkup" takes no arguments, and "decbkup" takes one argument, the file to be decrypted and uncompressed. This spits out the contents of the backup into the current directory.

encbkup and decbkup:
# these aren't the values I use
BKUP_ICK=1234
BKUP_SEED=5678

function encbkup(){
	(tar cj /home/sechome | \
	aespipe -e aes256 -C $BKUP_ICK -S $BKUP_SEED -T) \
	> "bkup`date +%Y%m%d`";
}

function decbkup(){
	(aespipe -d -e aes256 -C $BKUP_ICK -S $BKUP_SEED < "$1") | \
	tar xj;
}
V: Synchronization
Synchronization is performed by specifying a direction and device to synchronize the current running instance of the system with. Currently, synchronization is a one way action, so if different changes were made on two different systems, any synchronization actions performed would clear any changes on one of the two systems depending on what is specified.

I have not had any desire to change this since it is much easier and much clearer to know what device is at what state if only one can be edited at a time. Because this is a single user system, this shouldn't be an issue unless the USB device is lost after making changes to something.
V.a: /home/sechome/grml/sync-os
This file is used to perform the actual task of synchronization. This file is called manually by the user, and takes two arguments.

The first argument is the direction the synchronization is to be performed, "to" or "from".

The second argument is the secondary device that is not associated with the currently running system.

For example, running "sync-os to <USB_DEVICE_FILE>" when booted into a hard drive install would copy the hard drive data over to the USB device.

This script unmounts and remounts the booter partition, and synchronizes that separately since the secondary device will not have that device mounted correctly, and I don't trust rsync to traverse that correctly anyway. After synchronizing using rsync, everything is put back into its original place. Sychronizing "from" a device also performs one more step, reinitialization of the Virtual Directories with the exception of the root filesystem directory ".staticfs". This is done by calling virtfs-init with the "nofs" option. I've tried letting it reinitialize the virtual root filesystem directory, but it breaks things and causes crashes, so it's not very safe.

Contents: /home/sechome/grml/sync-os
#!/bin/bash

if [ "$1" != "to" ] && [ "$1" != "from" ]; then
	echo "First argument must be 'to' or 'from'."
	exit
fi

if [ -z "$2" ]; then
	echo "Second argument must point to GRML partition."
	exit
fi

action="$1"
n_booter_dev="$2"

SYNC="rsync -arvuz --delete-before"
SYNC_MSDOS="rsync -rvuz --delete-before"

device="`echo $n_booter_dev | sed -r "s/(.*)[0-9]+/\1/g"`"
partnum="`echo $n_booter_dev | sed -r "s/.*([0-9]+)/\1/g"`"

function devplus(){
	new="$partnum"
	let new+=$1
	echo $device$new
}

function chr(){ echo "print chr($1)" | python; }
function gen_randnum(){ let "rand=$RANDOM%($2-$1+1)+$1"; echo $rand; }
function gen_randstr(){
	cnt="$1"
	newstr=""
	i=0; while let i+=1 && [ "$i" -le "$cnt" ]; do
		rand="`gen_randnum 0 61`"
		let rand+=48
		[ "$rand" -ge "58" ] && let rand+=7 && [ "$rand" -ge "91" ] && let rand+=6
		newstr="$newstr`chr $rand`"
	done
	echo $newstr
}

if
	[ ! -b "$n_booter_dev" ] ||
	[ ! -b "`devplus 1`" ]
then
	echo "Partition requirements not met."
	exit
fi

randstr="`gen_randstr 5`"
TMP="/tmp/$randstr"

# quit cleanly
function quit_clean(){
	if [ ! -z "$1" ]; then echo "Sync-ing booter partition..."; fi
	umount $TMP-n_booter &> /dev/null
	rmdir $TMP-n_booter &> /dev/null

	if [ ! -z "$1" ]; then echo "Sync-ing encrypted partition..."; fi
	umount $TMP-sync-to &> /dev/null
	rmdir $TMP-sync-to
	devplus1="`devplus 1`"
	lodev="`losetup -a | grep $devplus1 | cut -d ':' -f1`"
	if [ -b "$lodev" ]; then losetup -d $lodev; fi

	sync
	exit
}

# get booter mount
booter_mount="`mount | grep booter | cut -d ' ' -f1`"

# prepare/mount booter partition
mkdir $TMP-n_booter
chmod 700 $TMP-n_booter
mount $n_booter_dev $TMP-n_booter

# prepare/mount encrypted partition
mkdir $TMP-sync-to
chmod 700 $TMP-sync-to
bash /home/sechome/grml/booter/smount /home/sechome/grml/booter/.ss `devplus 1` $TMP-sync-to 3

# test mount
if [ -z "`mount | grep $TMP-sync-to`" ]; then
	echo "Mount failed."
	quit_clean
fi

# umount booter partition in sechome
umount /home/sechome/grml/booter

# sync partitions
if [ "$action" = "from" ]; then
	# sync 'from'
	$SYNC_MSDOS $TMP-n_booter/ $booter_mount
	$SYNC $TMP-sync-to/ /home/sechome
	bash /home/sechome/grml/virtfs-init nofs
else
	# sync 'to'
	$SYNC_MSDOS $booter_mount/ $TMP-n_booter
	$SYNC /home/sechome/ $TMP-sync-to
fi

# remount booter partition
mount --bind $booter_mount /home/sechome/grml/booter

quit_clean 1
VI: Miscellaneous Security
This section describes security functions in the system which are not a direct part of setting up the system itself, but are still important security measures within the system.
VI.a: root User
Because GRML is a live-CD, sudo works to gain root access to anything. On top of which, the root user has no password or some default password set by the GRML developers. To fix this, passwd was run as user root and user grml (so that user wasn't using defaults as well), and the resulting shadow file was stored in "/home/sechome/.staticfs/etc/shadow". The sudoers file was truncated, and simple things were added such as /sbin/halt, /sbin/reboot, and my-grml-x.

Contents: /home/sechome/.staticfs/etc/sudoers
grml ALL=NOPASSWD: /usr/bin/my-grml-x, /sbin/halt, /sbin/reboot

system-work creates a symbolic link for /usr/bin/my-grml-x to point to my-grml-x.
VI.b: Console Security
The console screens need to be locked for physical access purposes. If the user were to lock the screen with xlock or similar, any Linux user with enough experience would know to check the other console windows to see if X was running from a console, terminate it, and have access to the system. Not only are all consoles completely open when GRML starts up, but they are also running as root, so this would be very bad.

To fix this, the following is added to "/home/sechome/.statichome/.zshrc" and "/home/sechome/.staticroot/.zshrc".

Snippet: /home/sechome/.statichome/.zshrc and /home/sechome/.staticroot/.zshrc
if [ "$TERM" = "linux" ]; then
	[ "$UID" = "0" ] && su - grml
	clear; vlock
fi

This executes a shell as user grml if the current user is root and we are working in a console. The new shell executes the same thing, which clears the screen and runs vlock. This locks the console down. For added security, both users execute this part of the code so that typing "exit" from the grml shell doesn't drop you to a root shell.
VI.c: /home/sechome/grml/my-grml-x
This file is a modified version of the "grml-x" file provided by GRML to start up the X server. Unfortunately, the "grml-x" script relies on sudo working on certain utilities without a password, and as described in root User, this is no longer possible in my system. To fix this, the entire script is run as root, locations that previously were called using sudo were changed to regular commands, places that assumed user grml were changed, and then finally X is started using a su command to change to user grml before starting X.

Another change made was to make X start up without the TCP port 6000 open for remote connections. This shouldn't be a problem with X's security features, but since code would still be executed to deny a request, it's better to keep it closed if it isn't going to be used. An extra option ("-tcp") was added to allow X to start with the TCP port open since I do use it occasionally.

Also, because of the Console Security features, X is executed in the background and the console is relocked using an alias to "my-grml-x".

Snippet: /home/sechome/.statichome/.zshrc
alias x="(sudo /usr/bin/my-grml-x ion3 &> /dev/null) &; disown; sleep 1; clear; vlock"

Patch: /home/sechome/grml/my-grml-x
--- grml-x	2008-03-14 17:04:11.000000000 -0500
+++ my-grml-x	2008-03-09 14:39:34.000000000 -0500
@@ -44,7 +44,7 @@
   PROGRAMNAME=${0##*/}
   HWINFO='/usr/sbin/hwinfo'
   DATE=$(date)
-  [ -n "$XINITRC" ] || XINITRC="$HOME/.xinitrc"
+  [ -n "$XINITRC" ] || XINITRC="/home/grml/.xinitrc" # bcable
 
   # temporary files
   HWINFO_TMP="/tmp/hwinfo.$$"
@@ -102,18 +102,19 @@
 # }}}
 
 # warn if running as user root {{{
-  if [ -n "$ROOT" ] ; then
-     if [ -r /etc/grml_cd ] ; then
-        print "$bg[black]$fg[red]${bold_color}Warning: Please do not run grml-x as user root.${reset_color}"
-        print "$bg[black]$fg[red]${bold_color}Running grml-x as user root is *not* supported!${reset_color}"
-        print "$bg[black]$fg[red]${bold_color}Switch to user grml or run su - grml -c 'grml-x ...' instead.${reset_color}"
-        print ''
-     else
-        print "$bg[black]$fg[red]${bold_color}Warning: Please do not run X.org as user root!${reset_color}"
-        print "$bg[black]$fg[red]${bold_color}As soon as you have a working $XCONFIG please use startx instead of grml-x.${reset_color}"
-        print ''
-     fi
-  fi
+# commented - bcable
+#  if [ -n "$ROOT" ] ; then
+#     if [ -r /etc/grml_cd ] ; then
+#        print "$bg[black]$fg[red]${bold_color}Warning: Please do not run grml-x as user root.${reset_color}"
+#        print "$bg[black]$fg[red]${bold_color}Running grml-x as user root is *not* supported!${reset_color}"
+#        print "$bg[black]$fg[red]${bold_color}Switch to user grml or run su - grml -c 'grml-x ...' instead.${reset_color}"
+#        print ''
+#     else
+#        print "$bg[black]$fg[red]${bold_color}Warning: Please do not run X.org as user root!${reset_color}"
+#        print "$bg[black]$fg[red]${bold_color}As soon as you have a working $XCONFIG please use startx instead of grml-x.${reset_color}"
+#        print ''
+#     fi
+#  fi
   fstabuser=$(grep ':x:1000:' /etc/passwd)
   fstabuser=${fstabuser%%[:]*}
 # }}}
@@ -153,18 +154,21 @@
 # writehwinfo {{{
 writehwinfo()
 {
-   if [ -n "$ROOT" ] ; then
-     su - $fstabuser -c "$HWINFO > $HWINFO_TMP"
-   else
+   # bcable
+   #if [ -n "$ROOT" ] ; then
+   #  su - $fstabuser -c "$HWINFO > $HWINFO_TMP"
+   #else
      $HWINFO > $HWINFO_TMP
-   fi
+   #fi
 }
 # }}}
 
 # monitor {{{
 monitor()
 {
-  sudo $HWINFO --monitor > $MONITORINFO
+  # bcable
+  $HWINFO --monitor > $MONITORINFO
+  #sudo $HWINFO --monitor > $MONITORINFO
 }
 # }}}
 
@@ -288,7 +292,9 @@
 # mouse {{{
 mouse()
 {
-   sudo $HWINFO --mouse > $MOUSEINFO
+   # bcable
+   $HWINFO --mouse > $MOUSEINFO
+   #sudo $HWINFO --mouse > $MOUSEINFO
 
    # SynPS/2 Synaptics TouchPad
    if grep -q 'Device:.*Synaptics' "$MOUSEINFO" ; then
@@ -457,7 +463,12 @@
                     nostart=o_nostart nodpms=o_nodpms nosynaptics=o_nosynaptics nousb=o_nousb \
                     nops2=o_nops2 genmouse=o_genmouse novref=o_novref nohsync=o_nohsync \
                     fallback=o_fallback usb=o_usb ps2=o_ps2 composite=o_composite \
-		    xinerama=o_xinerama
+		    xinerama=o_xinerama tcp=o_tcp # bcable
+
+   # bcable
+   if [ -z "$o_tcp" ]; then
+      XOPTS="$XOPTS -nolisten tcp"
+   fi
 
    if [[ $# == 0 || "$o_help" != "" || "$1" == '-h' || "$1" == '--help' ]]; then
       usage
@@ -861,10 +872,15 @@
           sed -i 's|InputDevice.*PS/2.*CorePointer|# & # deactivated to avoid two CorePointers|' $XCONFTMP
        fi
     fi
-    [ -f $XCONFIG ] && sudo mv -f $XCONFIG $XCONFIG.old
-    sudo mv $XCONFTMP $XCONFIG
-    sudo chown root.root $XCONFIG
-    sudo chmod 644 $XCONFIG
+    # bcable
+    [ -f $XCONFIG ] && mv -f $XCONFIG $XCONFIG.old
+    #[ -f $XCONFIG ] && sudo mv -f $XCONFIG $XCONFIG.old
+    mv $XCONFTMP $XCONFIG
+    #sudo mv $XCONFTMP $XCONFIG
+    chown root.root $XCONFIG
+    #sudo chown root.root $XCONFIG
+    chmod 644 $XCONFIG
+    #sudo chmod 644 $XCONFIG
 }
 # }}}
 
@@ -910,10 +926,12 @@
     print ""
     if [ -z "$DISPLAY" ] ; then
       print "$bold_color$fg[green]Now trying to run startx.$reset_color"
-      startx $XINITRC -- $XOPTS
+      su - grml -c "startx $XINITRC -- $XOPTS" # bcable
+      #startx $XINITRC -- $XOPTS
     else
       print "$bold_color$fg[green]Now trying to run startx on display $DISPLAY.$reset_color"
-      startx $XINITRC -- :$DISPLAY $XOPTS
+      su - grml -c "startx $XINITRC -- :$DISPLAY $XOPTS" # bcable
+      #startx $XINITRC -- :$DISPLAY $XOPTS
     fi
   else
     print "$bold_color$fg[blue]Not running startx as requested via option.$reset_color"
VII: Flaws in the System
This system is quite awesome, but it is not perfect (no system is). There are a few known flaws with the security of the system, and most cannot be eliminated due to the design of the system. If you think of any more, or think of a plausible solution for any of these, contact me.
VII.a: Remote Attacks
Rebooting does not fix all problems associated with remote attacks. Any automated remote attacks would be completely eliminated by a reboot, but a skilled hacker that broke into this system, and got root access, could easily append commands to any of the startup scripts. An attacker could also remount the live-CD image as read-write ("mount -o remount,rw /live/image"), then modify everything. If that isn't enough, the attacker could create a new cramfs filesystem and throw it into /home/sechome/addons/.
VII.b: Physical Attacks
If someone were to physically gain access to a device with this system installed, such as a hard drive or USB drive, they could easily replace binary files with their own rootkits and other malware since the operating system is not encrypted. However, even with full encryption on the operating system partition, some sort of binary would need to be executed to decrypt that partition, so there will always be an issue with physical security.

It is for this reason that I suggest carrying around some sort of weapon to fight off evil ninjas and samurai that wish to steal your precious data. Richard Stallman is already one step ahead of me here, though.
VII.c: Security Upgrades
If a security flaw were to be discovered in a utility in the operating system used, it would be a pain to upgrade. For the most part, I just wait until the next version of GRML to upgrade my system, but a serious enough security flaw could be fixed by updated the cramfs filesystem in /home/sechome/addons/.

I've also thought about writing a utility to automatically grab any security related packages from the GRML repositories and save them in a special directory under /home/sechome/addons/ called "security". This directory could be cleared out every time GRML releases a new version, and the system would always be up to date.
Appendices
These appendices are reference information for additional concepts that are unrelated to the overall scope of the system.
A1: Password-File Generation
In order to easily generate a password-file and seed-file for .ss, I developed a quick and easy system involving some hashing algorithms in order to generate a long password string easily from a smaller password.

These commands are used to generate these strings. The escaping inside of the arguments to "tr" are intended for zsh, so any other shell might need different escaping. Basically, there is no "\" in the actual character translation.

Command 1:
echo -n "PASS" | md5sum | tr "0-4a-c" "\!@#$%^&*"

Command 1 Output:
7^95&f9#6^!$$$f577!5^e^*!7^$6#^#  -

This command takes the md5-sum of the password, then translates characters 0-4 with "!@#$%", and characters "abc" with "^&*". Because the range of outputs of the md5sum function is hexadecimal (0-9, a-f), this translation gives numerical, lowercase alphabetical, and special characters in its output.

Command 2:
echo -n "PASS" | sha1sum | tr "5-9d-fa-c" ")(*&^%\$#X-Z"

Command 2 Output:
Y%)(4%Y)%)ZZ3)&$Y0$3)23%3$03041*3^#230%)  -

This command takes the sha1-sum of the password, then translates characters 5-9 with ")(*&^", the characters "def" with "%$#", and the characters "abc" with "XYZ". This creates numeric, uppercase alphabetical, and special characters in its output.

These two strings are then combined to form one longer string that contains a range from 0-9, "!@#$%^&*()", and "defXYZ".

From here, I memorized a few characters from the beginning and ending of each output. I will use this string as an integrity checker in the instance I have to regenerate these files. Sometimes when I'm bored or have nothing else to think about, I'll just start repeating this string in my head. I've done this so many times that I'll never forget this integrity string.

This could be better in terms of range (especially in alphabetical characters), but it represents all classes of characters to reduce direct brute force attempts to crack the password. so the resulting 26^72 password possibilities produces, according to Python, this many potential passwords or seeds:

7552331663217214825006745062553074726977155423512707515618786818627900161416446
34546410310899572146176

Both the seed-file and password-file must align perfectly in order to decrypt the data, so square that number to produce the number of possibilities, or:

5703771355123330237019007212917971463727350822126776738571796837795501025273128
0900988612121263585565441806450432685067156764815113982255928204809523985053041
9933797647200292755130496016995295694711422976
Version Info and Changelog
The document you are currently viewing is version 1.1.

20091123: Version 1.4
 - updated location of grml.sh
 - updated grml.sh to erase itself so it doesn't get run twice by accident
 - updated smount to modprobe for "aes" module instead of architecture specific "aes_i586"
 - updated addons directory structure to have separate 64-bit and 32-bit packages
 - updated addons to use squashfs instead of cramfs for faster speeds and bigger allotment for packages
 - updated encbkup to exclude unnecessary files
 - updated all scripts to support the 64-bit structure
 - updated my-grml-x to work with newer GRML images

20090608: Version 1.3
 - updated my-grml-x to work with newest version of GRML (2009.05)
 - updated the make-addons script to support commenting out lines with "#"

20080817: Version 1.2
 - created the script "make-addons" which generates the addon packages cramfs automatically

20080604: Version 1.1
 - better system for addon packages

20080316: Version 1.0