Howto install a Debian GNU/Linux system onto a USB flash thumb drive with the root partition encrypted (using Yaird & DM-Crypt)

This howto will cover the installation of a base Debian GNU/Linux system onto a USB flash thumb drive with the root partition encrypted. It includes support for Cryptsetup with LUKS, Yaird and Udev.

So open your favorite root login shell and follow these steps!

Notes:
  1. This howto will only work if your device has been detected as /dev/sda because of how Yaird works.
  2. This howto will only work with Debian Sid because that is the only version with a LUKS aware cryptsetup.
$QUOTE$
Updated Howto at: {NODE 94}Howto install Debian GNU/Linux onto a USB thumbdrive with the root partition encrypted (using UUIDs, Initramfs-tools & Dm-Crypt){/NODE}.
$/QUOTE$

I. Load required kernel modules (if necessary)

Load any/all needed kernel modules (this is a partial list, actual list depends on your configuration):

root@hostname# modprobe ehci_hcd
root@hostname# modprobe ohci_hcd 
root@hostname# modprobe usbhid
root@hostname# modprobe usb_storage
root@hostname# modprobe dm-crypt
root@hostname# modprobe aes (or aes_686 or aes_x86_64 as appropriate for your system)

II. Install required applications

Install the necessary applications on the build system:

root@hostname# apt-get install cryptsetup dmsetup fdisk debootstrap

III. Identifying your media

Identify what our system identifies our flash media as. To do this, simply stick the usb thumbdrive into one of the usb ports and then run the tail command:

root@hostname# tail -n 14 /var/log/messages
Jan  1 12:00:00 hostname kernel: ohci_hcd 0000:00:02.1: wakeup
Jan  1 12:00:00 hostname kernel: usb 2-3: new full speed USB device using ohci_hcd 
                                 and address 2
Jan  1 12:00:00 hostname kernel: Initializing USB Mass Storage driver...
Jan  1 12:00:00 hostname kernel: scsi2 : SCSI emulation for USB Mass Storage devices
Jan  1 12:00:00 hostname kernel: usbcore: registered new driver usb-storage
Jan  1 12:00:00 hostname kernel: USB Mass Storage support registered.
Jan  1 12:00:00 hostname kernel:   Vendor:           Model: TS256MJFLASHA     Rev: 1.00
Jan  1 12:00:00 hostname kernel:   Type:   Direct-Access                      ANSI SCSI 
                                   revision: 02
Jan  1 12:00:00 hostname kernel: SCSI device sda: 506400 512-byte hdwr sectors (259 MB)
Jan  1 12:00:00 hostname kernel: sda: Write Protect is off
Jan  1 12:00:00 hostname kernel: SCSI device sda: 506400 512-byte hdwr sectors (259 MB)
Jan  1 12:00:00 hostname kernel: sda: Write Protect is off
Jan  1 12:00:00 hostname kernel:  sda: sda1 sda2
Jan  1 12:00:00 hostname kernel: sd 2:0:0:0: Attached scsi removable disk sda
root@hostname# 

As we can see from this output, the device was detected and assigned to /dev/sda.

IV. Wipe the disk

The first thing we want to do is remove any old data from the drive. To do this, we'll use the shred tool which overwrites the media with progressive cycles of random and nonrandom data to make recovery of any old data near impossible.

Note: Sam (in a comment below) warns us that shredding the root of the device may harm some usb devices. He mentions a bad experience he had with a Sony Memory Vault as one such case. The recommended solution is to partition the drive first and then shred the individual partitions. However this has some risk as well. We will need to track tested and approved media somehow.

root@hostname# shred -n 1 -v /dev/sda
shred: /dev/sda: pass 1/1 (random)...
shred: /dev/sda: pass 1/1 (random)...43MiB/984MiB 4%
shred: /dev/sda: pass 1/1 (random)...97MiB/984MiB 9%
shred: /dev/sda: pass 1/1 (random)...150MiB/984MiB 15%
shred: /dev/sda: pass 1/1 (random)...203MiB/984MiB 20%
shred: /dev/sda: pass 1/1 (random)...256MiB/984MiB 26%
shred: /dev/sda: pass 1/1 (random)...309MiB/984MiB 31%
shred: /dev/sda: pass 1/1 (random)...361MiB/984MiB 36%
shred: /dev/sda: pass 1/1 (random)...406MiB/984MiB 41%
shred: /dev/sda: pass 1/1 (random)...459MiB/984MiB 46%
shred: /dev/sda: pass 1/1 (random)...512MiB/984MiB 52%
shred: /dev/sda: pass 1/1 (random)...565MiB/984MiB 57%
shred: /dev/sda: pass 1/1 (random)...619MiB/984MiB 62%
shred: /dev/sda: pass 1/1 (random)...672MiB/984MiB 68%
shred: /dev/sda: pass 1/1 (random)...725MiB/984MiB 73%
shred: /dev/sda: pass 1/1 (random)...778MiB/984MiB 79%
shred: /dev/sda: pass 1/1 (random)...832MiB/984MiB 84%
shred: /dev/sda: pass 1/1 (random)...885MiB/984MiB 90%
shred: /dev/sda: pass 1/1 (random)...939MiB/984MiB 95%
shred: /dev/sda: pass 1/1 (random)...984MiB/984MiB 100%
root@hostname# 

For this example, shred wil run in verbose mode, and overwrite with one pass of random data (-n 1).

V. Partition, format and mount the media

Next we need to partition the media. For a flash media installation, we will have a boot & a root partition. There will be no swap as this could prematurely age the drive.

For formating, lets use fdisk this time:

root@hostname# fdisk /dev/sda
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that, of course, the previous
content won't be recoverable.

Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-1015, default 1):
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-1015, default 1015): +20M

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 2
First cylinder (22-1015, default 22):
Using default value 22
Last cylinder or +size or +sizeM or +sizeK (22-1015, default 1015):
Using default value 1015

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
root@hostname#

VI. LUKS Format the encrypted partition

root@hostname#cryptsetup luksFormat /dev/sda2

WARNING!
========
This will overwrite data on /dev/sdc2 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase:
Verify passphrase:
Command successful.
root@hostname#

VII. Cryptsetup Mount the Encrypted Partition

root@hostname#cryptsetup luksOpen /dev/sda2 rootfs
Enter LUKS passphrase:
key slot 0 unlocked.
Command successful.
root@hostname#

VIII. Format the encrypted partition

root@hostname# mkfs.ext2 /dev/mapper/rootfs
mke2fs 1.39-WIP (29-Mar-2006)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
123392 inodes, 246383 blocks
12319 blocks (5.00%) reserved for the super user
First data block=0
8 block groups
32768 blocks per group, 32768 fragments per group
15424 inodes per group
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376

Writing inode tables: done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 35 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.

IX. Format the boot partition

root@hostname# mkfs.ext2 /dev/sdc1
mke2fs 1.39-WIP (29-Mar-2006)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
5208 inodes, 20800 blocks
1040 blocks (5.00%) reserved for the super user
First data block=1
3 block groups
8192 blocks per group, 8192 fragments per group
1736 inodes per group
Superblock backups stored on blocks:
        8193

Writing inode tables: done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 35 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
root@hostname#

X. Mount the Partitions

Now that we have our partition, we need to create a temporary mount point and mount our partition to it so we can perform our install.

root@hostname# mkdir /mnt/buildroot
root@hostname# mount -t ext2 /dev/mapper/rootfs /mnt/buildroot
root@hostname# mkdir /mnt/buildroot/boot
root@hostname# mount /dev/sdc1 /mnt/buildroot/boot
root@hostname#

To use cryptsetup within our chroot jail, we need to mount link its /sys and /dev/mapper directories to ours.

root@hostname# mkdir /mnt/buildroot/sys
root@hostname# mount -o bind /sys /mnt/buildroot/sys
root@hostname# mkdir -p /mnt/buildroot/dev/mapper
root@hostname# mount -o bind /dev/mapper /mnt/buildroot/dev/mapper
root@hostname#

Next we need to temporarily copy over the device files

root@hostname# cd /mnt/buildroot/
root@hostname# tar -cv /dev/sda* | tar -x 
root@hostname#

XI. Install base packages

Now that we have our partition mounted, we can install the base Debian system onto it.

root@hostname# debootstrap --arch i386 sid /mnt/buildroot
I: Retrieving Release
I: Retrieving Packages
I: Validating Packages
I: Resolving dependencies of required packages...
I: Resolving dependencies of base packages...
I: Found additional base dependencies: libdb4.2 libgnutls12 libreadline5
   libsigc++-2.0-0c2a openbsd-inetd readline-common
I: Checking component main on http://ftp.debian.org/debian...
I: Retrieving adduser
<SNIP>
I: Configuring gnupg...
I: Configuring sysklogd...
I: Configuring klogd...
I: Configuring netbase...
I: Configuring openbsd-inetd...
I: Base system installed successfully.
root@hostname# 

XII. Chroot Jail

root@hostname# chroot /mnt/buildroot /bin/su -l
hostname:~#

XIII. System Configuration

FILE: /etc/fstab

Use vi to create the /etc/fstab file and add these contents to it:

#/etc/fstab: static file system information.
#
/dev/mapper/rootfs  /          ext2    defaults,errors=remount-ro,noatime 0 1
/dev/sda1       /boot          ext2    defaults,noatime                   0 1
none            /proc          proc    defaults                           0 0
tmpfs           /etc/network/run tmpfs defaults,noatime                   0 0
tmpfs           /tmp           tmpfs   defaults,noatime                   0 0
tmpfs           /var/lock      tmpfs   defaults,noatime                   0 0
tmpfs           /var/log       tmpfs   defaults,noatime                   0 0
tmpfs           /var/run       tmpfs   defaults,noatime                   0 0
tmpfs           /var/tmp       tmpfs   defaults,noatime                   0 0

Then mount all the filesystems:

hostname:~# mount -a
hostname:~# 
Set Hostname

Set the hostname by editing /etc/hostname, and then add the base configuration to /etc/hosts:

127.0.0.1 localhost.localdoman localhost <hostname>
FILE: /etc/apt/sources.list

Next we have to add some sources to the Apt configuration.

deb http://ftp.debian.org/debian sid main non-free contrib
deb-src http://ftp.debian.org/debian sid main non-free contrib
deb http://mirrors.kernel.org/debian/ sid main non-free contrib
deb-src http://mirrors.kernel.org/debian/ sid main non-free contrib

XIV. Install additional packages and kernel

Start by updating the apt databases.

root@hostname# apt-get update
Get:1 http://mirrors.kernel.org sid Release.gpg [189B]
Get:2 http://mirrors.kernel.org sid Release [38.3kB]
Get:3 http://mirrors.kernel.org sid/main Packages [4079kB]
Get:4 http://ftp.debian.org sid Release.gpg [189B]
Hit http://ftp.debian.org sid Release
Hit http://ftp.debian.org sid/main Packages
Get:5 http://ftp.debian.org sid/non-free Packages [74.6kB]
Get:6 http://ftp.debian.org sid/contrib Packages [57.1kB]
Get:7 http://ftp.debian.org sid/main Sources [1559kB]
Get:8 http://ftp.debian.org sid/non-free Sources [30.3kB]
Get:9 http://ftp.debian.org sid/contrib Sources [24.3kB]
Get:10 http://mirrors.kernel.org sid/non-free Packages [74.6kB]
Get:11 http://mirrors.kernel.org sid/contrib Packages [57.1kB]
Get:12 http://mirrors.kernel.org sid/main Sources [1559kB]
Get:13 http://mirrors.kernel.org sid/non-free Sources [30.3kB]
Get:14 http://mirrors.kernel.org sid/contrib Sources [24.3kB]
Fetched 7608kB in 48s (158kB/s)
Reading package lists... Done
root@hostname#

Install Localepurge

The first thing we're going to install is localepurge to help keep the installation size down by removing all documentation in languages other than those you speak. When you install localepurge, it will ask you what locales you would like to keep. As an american english speaker, I select the following locales: en, en_us, and en_us.UTF8. Be careful not to remove too many locales or you may lose some functionality.

root@hostname$ apt-get install localepurge
Reading package lists... Done
Building dependency tree... Done
Suggested packages:
  debfoster deborphan
The following NEW packages will be installed
  localepurge
0 upgraded, 1 newly installed, 0 to remove and 30 not upgraded.
Need to get 35.2kB of archives.
After unpacking 87.0kB of additional disk space will be used.
Get: 1 http://ftp.debian.org sid/main localepurge 0.4.1 [35.2kB]
Fetched 35.2kB in 9s (3780B/s)
Preconfiguring packages ...
Configuring localepurge
-----------------------

localepurge will remove all locale files from your system but the ones for the
language codes you select now. Usually two character locales like "de" or "pt"
rather than "de_DE" or "pt_BR" contain the major portion of localizations. So
please select both for best support of your national language settings.  The
entries from /etc/locale.gen will be preselected if no prior configuration has
been successfully completed.

  1. aa            92. en_SG          183. ja_JP.UTF-8   274. se
  2. aa_DJ         93. en_US          184. ka            275. se_NO
  3. aa_ER         94. en_US.UTF-8    185. ka_GE         276. si
  4. aa_ER@saaho   95. en_ZA          186. kk            277. si_LK
  5. aa_ET         96. en_ZW          187. kk_KZ         278. sk
  <SNIP> 
  77. en           168. hy_AM         259. pt_BR         350. zh_CN
  78. en_AU        169. ia            260. pt_PT         351. zh_CN.GB18030
  79. en@boldquot  170. id            261. pt_PT@euro    352. zh_CN.GB2312
  80. en_BW        171. id_ID         262. rm            353. zh_CN.GBK
  81. en_CA        172. is            263. ro            354. zh_CN.UTF-8
  82. en_DK        173. is_IS         264. ro_RO         355. zh_HK
  83. en_GB        174. it            265. ru            356. zh_HK.UTF-8
  84. en_GB.UTF-8  175. it_CH         266. ru_RU         357. zh_SG
  85. en_HK        176. it_IT         267. ru_RU.KOI8-R  358. zh_TW
  86. en_IE        177. it_IT@euro    268. ru_RU.UTF-8   359. zh_TW.Big5
  87. en_IE@euro   178. iw            269. ru_UA         360. zh_TW.EUC-TW
  88. en_IN        179. iw_IL         270. rw            361. zh_TW.UTF-8
  89. en_NZ        180. ja            271. rw_RW         362. zu
  90. en_PH        181. ja_JP         272. sa            363. zu_ZA
  91. en@quot      182. ja_JP.EUC-JP  273. sa_IN

(Enter the items you want to select, separated by spaces.)

Selecting locale files 77 93 94


localepurge failed to preconfigure, with exit status 10
Selecting previously deselected package localepurge.
(Reading database ... 79926 files and directories currently installed.)
Unpacking localepurge (from .../localepurge_0.4.1_all.deb) ...
Setting up localepurge (0.4.1) ...
Configuring localepurge
-----------------------

Based on the same locale information you chose above, localepurge can also
delete superfluous localized man pages.

Also delete localized man pages? yes


If you are content with the selection of locales you chose to keep and don't
want to care about whether to delete or keep newly found locales, just deselect
this option to automatically remove new locales you probably wouldn't care about
anyway. If you select this option, you will be given the opportunity to decide
whether to keep or delete newly introduced locales.

Inform about new locales? yes
root@hostname# 

NOTE: Locale often adds more locales to the list so do not simply use the same numbers I did. Verify that they correspond to the correct locales for you.

After this, everytime you run apt-get to install or upgrade, it will post-install run localepurge to remove all unwanted documentation.

For now, we have to force it to run for the first time.

hostname:~# localepurge
localepurge: Disk space freed in /usr/share/locale: 25396K
hostname:~#

As space is limited, get in the habit of removing apt's cached files frequently.

root@hostname# apt-get clean

Install Yaird
root@hostname# apt-get install yaird
Reading package lists... Done
Building dependency tree... Done
The following extra packages will be installed:
  dash libdb4.4 libhtml-template-perl libparse-recdescent-perl perl
  perl-modules
Suggested packages:
  libipc-sharedcache-perl libterm-readline-gnu-perl libterm-readline-perl-perl
  doc-base
Recommended packages:
  perl-doc
The following NEW packages will be installed:
  dash libdb4.4 libhtml-template-perl libparse-recdescent-perl perl
  perl-modules yaird
0 upgraded, 7 newly installed, 0 to remove and 0 not upgraded.
Need to get 6774kB of archives.
After unpacking 27.8MB of additional disk space will be used.
Do you want to continue [Y/n]? y
Get:1 http://192.168.107.97 sid/main dash 0.5.3-2 [85.9kB]
Get:2 http://192.168.107.97 sid/main libdb4.4 4.4.20-4 [466kB]
Get:3 http://192.168.107.97 sid/main perl-modules 5.8.8-4 [2319kB]
Get:4 http://192.168.107.97 sid/main perl 5.8.8-4 [3570kB]
Get:5 http://192.168.107.97 sid/main libhtml-template-perl 2.8-1 [64.2kB]
Get:6 http://192.168.107.97 sid/main libparse-recdescent-perl 1.94.free-1 [88.2kB]
Get:7 http://192.168.107.97 sid/main yaird 0.0.12-9 [182kB]
Fetched 6774kB in 2s (2789kB/s)
Preconfiguring packages ...
Selecting previously deselected package dash.
(Reading database ... 8097 files and directories currently installed.)
Unpacking dash (from .../archives/dash_0.5.3-2_i386.deb) ...
Selecting previously deselected package libdb4.4.
Unpacking libdb4.4 (from .../libdb4.4_4.4.20-4_i386.deb) ...
Selecting previously deselected package perl-modules.
Unpacking perl-modules (from .../perl-modules_5.8.8-4_all.deb) ...
Selecting previously deselected package perl.
Unpacking perl (from .../archives/perl_5.8.8-4_i386.deb) ...
Selecting previously deselected package libhtml-template-perl.
Unpacking libhtml-template-perl (from .../libhtml-template-perl_2.8-1_all.deb) ...
Selecting previously deselected package libparse-recdescent-perl.
Unpacking libparse-recdescent-perl (from .../libparse-recdescent-perl_1.94.free-1_all.deb) ...
Selecting previously deselected package yaird.
Unpacking yaird (from .../yaird_0.0.12-9_i386.deb) ...
Setting up dash (0.5.3-2) ...

Setting up libdb4.4 (4.4.20-4) ...
Setting up perl-modules (5.8.8-4) ...
Setting up perl (5.8.8-4) ...

Setting up libhtml-template-perl (2.8-1) ...
Setting up libparse-recdescent-perl (1.94.free-1) ...
Setting up yaird (0.0.12-9) ...
root@hostname# 
Install Cryptsetup
root@hostname#  apt-get install cryptsetup
Reading package lists... Done
Building dependency tree... Done
The following extra packages will be installed:
  dmsetup
The following NEW packages will be installed:
  cryptsetup dmsetup
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 260kB of archives.
After unpacking 741kB of additional disk space will be used.
Do you want to continue [Y/n]? y
Get:1 http://192.168.107.97 sid/main dmsetup 2:1.02.03-1 [24.7kB]
Get:2 http://192.168.107.97 sid/main cryptsetup 2:1.0.2+1.0.3-rc3-1 [235kB]
Fetched 260kB in 0s (1400kB/s)
Selecting previously deselected package dmsetup.
(Reading database ... 10050 files and directories currently installed.)
Unpacking dmsetup (from .../dmsetup_2%3a1.02.03-1_i386.deb) ...
Selecting previously deselected package cryptsetup.
Unpacking cryptsetup (from .../cryptsetup_2%3a1.0.2+1.0.3-rc3-1_i386.deb) ...
Setting up dmsetup (1.02.03-1) ...
Setting up cryptsetup (1.0.2+1.0.3-rc3-1) ...

localepurge: Disk space freed in /usr/share/locale: 4K
root@hostname# 

Now that cryptsetup is installed, add the required mounting information to /etc/crypttab:

# <target name> <source device> <key file> <options>
rootfs /dev/sda2 none luks
Install Udev
root@hostname# apt-get install udev
Reading package lists... Done
Building dependency tree... Done
The following extra packages will be installed:
  libvolume-id0
The following NEW packages will be installed:
  libvolume-id0 udev
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 312kB of archives.
After unpacking 1081kB of additional disk space will be used.
Do you want to continue [Y/n]? y
Get:1 http://192.168.107.97 sid/main libvolume-id0 0.089-1 [54.4kB]
Get:2 http://192.168.107.97 sid/main udev 0.089-1 [258kB]
Fetched 312kB in 0s (382kB/s)
Selecting previously deselected package libvolume-id0.
(Reading database ... 12183 files and directories currently installed.)
Unpacking libvolume-id0 (from .../libvolume-id0_0.089-1_i386.deb) ...
Selecting previously deselected package udev.
Unpacking udev (from .../archives/udev_0.089-1_i386.deb) ...
Setting up libvolume-id0 (0.089-1) ...

Setting up udev (0.089-1) ...
A chroot environment has been detected, udev not started.
root@hostname# 
Install Kernel

Before we can install the kernel, we need to set its configuration. Edit /etc/kernel-img.conf so that it looks like this:

do_symlinks = yes
relative_links = yes
do_bootloader = no
do_bootfloppy = no
do_initrd = yes        ## <--- Verify this line
link_in_boot = yes
postinst_hook = /sbin/update-grub
postrm_hook   = /sbin/update-grub

Next we install the kernel.

hostname:~# apt-get install linux-image-2.6.16-1-686
Reading package lists... Done
Building dependency tree... Done
Suggested packages:
  linux-doc-2.6.16 linux-source-2.6.16 grub lilo
Recommended packages:
  libc6-i686
The following NEW packages will be installed:
  linux-image-2.6.16-1-686
0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
5 not fully installed or removed.
Need to get 0B/15.7MB of archives.
After unpacking 46.8MB of additional disk space will be used.
Preconfiguring packages ...
(Reading database ... 7204 files and directories currently installed.)
Unpacking linux-image-2.6.16-1-686 (from
  .../linux-image-2.6.16-1-686_2.6.16-5_i386.deb) ...
Done.
Setting up busybox (1.01-4) ...
Setting up libklibc (1.3.1-1) ...
Setting up klibc-utils (1.3.1-1) ...
Setting up udev (0.088-2) ...
A chroot environment has been detected, udev not started.

Setting up initramfs-tools (0.59b) ...
wc: /proc/swaps: No such file or directory
tail: cannot open `/proc/swaps' for reading: No such file or directory

Setting up linux-image-2.6.16-1-686 (2.6.16-5) ...

 Hmm. The package shipped with a symbolic link /lib/modules/2.6.16-1-686/source
 However, I can not read it: No such file or directory
 Therefore, I am deleting /lib/modules/2.6.16-1-686/source

Running depmod.
Finding valid ramdisk creators.
Using mkinitramfs-kpkg to build the ramdisk.

Error, do this: mount -t proc none /proc
hostname:~# apt-get clean
hostname:~# 
Install Bootloader (Grub or Lilo) Either:

install the grub binaries:

root@hostname# apt-get install grub
Or:

install the lilo binaries:

root@hostname# apt-get install lilo

XV. Exit the Chroot Jail

At this time, we need to exit the chroot

hostname:~# umount -a
hostname:~# umount /proc
hostname:~# exit
logout
root@hostname #

XVI. Install bootloader

Either: GRUB

To install grub into the bootsector

root@hostname# grub-install --recheck --root-directory=/mnt/buildroot /dev/sda 
Probing devices to guess BIOS drives. This may take a long time.
Installation finished. No error reported.
This is the contents of the device map /mnt/buildroot//boot/grub/device.map.
Check if this is correct or not. If any of the lines is incorrect,
fix it and re-run the script `grub-install'.

(fd0)   /dev/fd0
(hd0)   /dev/hda
(hd1)   /dev/sda
root@hostname# 

Next we need to open /mnt/buildroot/boot/grub/menu.lst and add this configuration.:

# default num
default         0

# timeout sec
timeout         5

# pretty colours
color green/black black/green

title   Debian GNU/Linux-2.6.16-1-686
root    (hd0,0)
kernel  /vmlinuz-2.6.16-1-686 root=/dev/ram0 init=/sbin/init
initrd  /initrd.img-2.6.16-1-686
savedefault
boot

title   Debian GNU/Linux-2.6.16-1-686 (Rescue/Single)
root    (hd0,0)
kernel  /vmlinuz-2.6.16-1-686 root=/dev/ram0 init=/sbin/init single
initrd  /initrd.img-2.6.16-1-686
boot

Then we need to run grub to link it all together

root@hostname# grub
Probing devices to guess BIOS drives. This may take a long time.


    GNU GRUB  version 0.97  (640K lower / 3072K upper memory)

       [ Minimal BASH-like line editing is supported.   For
         the   first   word,  TAB  lists  possible  command
         completions.  Anywhere else TAB lists the possible
         completions of a device/filename. ]
grub> root (hd1,0)
root (hd1,0)
 Filesystem type is ext2fs, partition type 0x83
grub> setup (hd1)
setup (hd1)
 Checking if "/boot/grub/stage1" exists... yes
 Checking if "/boot/grub/stage2" exists... yes
 Checking if "/boot/grub/e2fs_stage1_5" exists... yes
 Running "embed /boot/grub/e2fs_stage1_5 (hd1)"... 
          failed (this is not fatal)
 Running "embed /boot/grub/e2fs_stage1_5 (hd1,0)"... 
          failed (this is not fatal)
 Running "install /boot/grub/stage1 (hd1) /boot/grub/stage2 
          p /boot/grub/menu.lst "... succeeded
Done.
grub> quit 

Or: LILO

Edit /mnt/buildroot/etc/lilo.conf so that it looks similar to this:

boot=/dev/sda
root=/dev/sda2
compact 

bitmap=/boot/sid.bmp
bmp-colors=1,,0,2,,0
bmp-table=120p,173p,1,15,17
bmp-timer=254p,432p,1,0,0
install=bmp

default=sid

# install=menu
map=/boot/map
vga=normal
delay=20
image=/boot/vmlinuz-2.6.16-1-686
label=sid
root=/dev/ram0
read-only
initrd=/boot/initrd.img-2.6.16-1-686

Then load the configuration into the master boot record

root@hostname# lilo -M /dev/sda # install MBR
root@hostname# lilo -b /dev/sda # install lilo 
root@hostname#
Thanks to Rick Bronson for submitting the Lilo configuration on my original howto.

XVII. Add user accounts

Either:

Copy an existing /etc/group, /etc/passwd, and /etc/shadow file over from another system (this has to be done from outside the chroot directory).

root@hostname# cp /etc/passwd /etc/group /etc/shadow /mnt/buildroot/etc/
root@hostname# 

Then chroot in and create their homedirectories

root@hostname# chroot /mnt/buildroot /bin/su -
hostname:~# mkdir /home/<username>
hostname:~# chown <username>.<username> /home/<username>
<Repeat as necessary>
hostname:~# exit
root@hostname# 
Or:

Set root password and add users in the chroot

root@hostname# chroot /mnt/buildroot /bin/su -
hostname:~# passwd
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
hostname:~#adduser test
Adding user `test'...
Adding new group `test' (1001).
Adding new user `test' (1001) with group `test'.
Creating home directory `/home/test'.
Copying files from `/etc/skel'
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for test
Enter the new value, or press ENTER for the default
        Full Name []: test
        Room Number []:
        Work Phone []:
        Home Phone []:
        Other []:
Is the information correct? [y/N] y
hostname:~#
<Repeat as necessary for more users>
hostname:~# exit
root@hostname# 

XVIII. Clean-up

Remove the temporary device files, they will be recreated when udev runs on boot.

root@hostname# rm /mnt/buildroot/dev/sda*
root@hostname#

XIX. Unmount

Time to unmount everything we've mounted and prepare for reboot.

root@hostname# umount /mnt/buildroot/dev/mapper
root@hostname# umount /mnt/buildroot/sys
root@hostname# umount /mnt/buildroot/boot
root@hostname# umount /mnt/buildroot
root@hostname# cryptsetup luksClose rootfs
root@hostname#


And thats it. time to reboot and test.

Comments

Remounting home directory with truecrypt drive

Here is a good solution for remounting home directory with truecrypt drive on session start:
http://ubuntuforums.org/archive/index.php/t-645247.html

it's a bit easy than using dm crypt :)

high, great works but i stumble a bit.

i have an usb stick working with the help from Dave infos. i followed on my pc the same logic:

For fstab, you can use the UUID for /boot but you need to use /dev/mapper/rootfs for / (root).
For grub, you need to add root=/dev/mapper/rootfs to the kernel options.
And in crypttab, you need to use /dev/disk/by-uuid/≶UUID> instead of UUID=.

and the mapper is not found :( any hints to debug this?

re: high, great works but i stumble a bit.

If you want to use UUIDs then this is not the correct howto to follow.

Check out: Howto install Debian Linux onto a USB thumb drive with the root partition encrypted (using UUIDs, Initramfs-tools & Dm-Crypt)

shred command delete

shred command delete everything from my HDD.Any idea to recover my files?

re: shred command delete

As far as I know the only way to recover your files will be from your backups (assuming you have some).

Shred is designed to make the data unrecoverable so there will be no way to recover any data off the hard drive (assuming you don't have an unlimited budge and work for a government institution like the NSA).

Sorry,

sorry I was way off for the "su" needing to be changed to "sh"

I do have a problem under the "XI. Install base packages" section when I run the debootstrap command it looks all good then I get an error:
"W: Failure trying to run: chroot /mnt/buildroot mount -t proc proc /proc"

Any idea?

FIX: chroot

/bin/su needs to be /bin/sh replace the "u" with an "h"

BAD:
root@hostname# chroot /mnt/buildroot /bin/su -l

GOOD:
root@hostname# chroot /mnt/buildroot /bin/sh -l

Any chances you could...

This looks like a great howto. However... i am wondering if you might have the time to "re-write" this guide to fit Ubuntu Edgy 6.10 and make it so that the USB thumbdrive is bootable from every USB bootable machines. Like my USB thumbdrive gets discovered as sdb and not sda. Ubuntu edgy doesnt use devices in config files, but UUID so its possible to make it boot on every system. I have manage to make the USB thumbdrive boot on every system, i then tried to make the crypto thingy with no luck. Every time i got some device-mapper errors after i entered my LUKS password... i was mixing some guides... https://help.ubuntu.com/community/EncryptedFilesystem and http://ubuntuforums.org/showthread.php?t=308027
Any answer would be good.

Re: Any chances you could.... (take 2)

Ok, now that I've thought about it a little more, there is one other thing you can do.

I've been working on a new version of this but its not documented as a howto yet. Its all contained within the Automated Installer script.

If you look at the code (its python + pexpect and is relatively easy to read), you will see that it uses initramfs-tools instead of yaird to create the initrd file. This eliminates the /dev/sda installation requirement. It also makes using a UUID a potential 1 line fix.

Look for the /etc/crypttab configuration (line 945), in it we can replace the /dev/sda2 with the UUID=, and it might work.

To be sure I'll need to read the crypttab documentation and do some testing. Which will probably have to wait until this weekend at the soonest.

re: Re: Any chances you could.... (take 2)

OK, I've been working on the Automated Installer, and I've got the UUIDs working for both encrypted and non-encrypted installs. It was a little more complicated than I initially believed but it works.

For fstab, you can use the UUID for /boot but you need to use /dev/mapper/rootfs for / (root).

For grub, you need to add root=/dev/mapper/rootfs to the kernel options.

And in crypttab, you need to use /dev/disk/by-uuid/≶UUID> instead of UUID=<UUID>.

Also keep in mind that UUIDs will only work for XFS, Ext2/3 and LUKS enabled Dm-Crypt formated partitions. Also, you should use '/lib/udev/vol_id -u <dev>' or 'cryptsetup luksUUID <dev>' to lookup the UUIDs. For some reason, /sbin/blkid doesn't get the right UUID from the LUKS header.

Re: Any chances you could....

OK, I've never seen the trick of using UUIDs for the root= designation, and that is something we should be looking at. However if I'm to do all the research, testing and writeup by MYSELF in my free time, it will take much longer than if a few people join in.

Of course there is a third option, you could pay me to work on it full time.

Since I don't think you'll take me up on the third option, I would suggest that you create a user account here and start documenting what you know already in the developers forums. From there we can both work on making this happen.

Or you can wait until I have time. Your choice.

Another yaird error

Don't know what to do with this message:

# aptitude install linux-image-2.6.18-3-686
Reading package lists... Done
Building dependency tree... Done
Reading extended state information
Initializing package states... Done
Writing extended state information... Done
Reading task descriptions... Done
Building tag database... Done
The following NEW packages will be installed:
linux-image-2.6.18-3-686
0 packages upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 0B/16.7MB of archives. After unpacking 50.8MB will be used.
Writing extended state information... Done
Preconfiguring packages ...
Selecting previously deselected package linux-image-2.6.18-3-686.
(Reading database ... 16366 files and directories currently installed.)
Unpacking linux-image-2.6.18-3-686 (from .../linux-image-2.6.18-3-686_2.6.18-7_i386.deb) ...
Done.
Setting up linux-image-2.6.18-3-686 (2.6.18-7) ...

Hmm. The package shipped with a symbolic link /lib/modules/2.6.18-3-686/source
However, I can not read the target: No such file or directory
Therefore, I am deleting /lib/modules/2.6.18-3-686/source

Running depmod.
Finding valid ramdisk creators.
Using mkinitrd.yaird to build the ramdisk.
yaird error: unsupported device required: dm-0 (fatal)
mkinitrd.yaird failed to create initrd image.
Failed to create initrd image.
dpkg: error processing linux-image-2.6.18-3-686 (--configure):
subprocess post-installation script returned error exit status 9
Errors were encountered while processing:
linux-image-2.6.18-3-686
E: Sub-process /usr/bin/dpkg returned an error code (1)
A package failed to install. Trying to recover:
Setting up linux-image-2.6.18-3-686 (2.6.18-7) ...
Running depmod.
Finding valid ramdisk creators.
Using mkinitrd.yaird to build the ramdisk.
yaird error: unsupported device required: dm-0 (fatal)
mkinitrd.yaird failed to create initrd image.
Failed to create initrd image.
dpkg: error processing linux-image-2.6.18-3-686 (--configure):
subprocess post-installation script returned error exit status 9
Errors were encountered while processing:
linux-image-2.6.18-3-686

re: Another yaird error

Yaird is very sensitive about what devices you are installing to and I only see dm-o mentioned in the error. What actual device are you installing to? /dev/sda?

I'm about half way done with a howto that uses mkinitramfs, its a little more complicated to configure but not nearly as device sensitive as yaird.

If you'd like to see it before its finished, just check out the Automated Installer. Even if you dont read python, just read through the main function and its pretty clear how it works.

Another yaird error

Yes, /dev/sda is an external usb harddisk.

Removing yaird and using mkinitrd from initramfs-tools the kernel packages get installed.

So what's necessary to tweak mkinitrd to be able to boot from an encrypted usb device?
(Maybe a few hints to google are enough...)

Peter

re: Another yaird error

Ok, well the best example I can think of is embedded in the Automated Installer code. Download it, read the code and you will see within it how mkinitramfs is configured. It's a rather simple config file to copy into place.

partition label

Great article. I've noticed the similarity to the one at http://www.debian-administration.org/articles/179, but I like your methods a little better.

You mention that it can only work if the USB drive mounts as /dev/sda, but I was wondering if you think it would still work using the LABEL method like the debian-administration article. I followed that article but could not get my drive mounted using a partition LABEL.

I'll probably just give this article a try, but thought I'd ask if you, or anyone else, has attempted to use the partition LABEL.

Thanks.

partition label

You can't use LABEL because the filesystem doesn't exist until you've decrypted the partition.
You can only do that if it knows the device to decrypt.

It's not strictly essential to use /dev/sda - yaird gets the root device from /etc/fstab and further information about root from /etc/crypttab. To get it to work with names different from the running system you alter these files to match the target system before running yaird (and alter them back afterwards).

However yaird also works out which drivers/modules to use from the devices you specify so the target needs to have the same driver requirements as the system you run yaird on. If that's not the case then you need to tell yaird (/etc/yaird/Templates.cfg) which modules it should include so they can be added to the initrd.

You can output the initrd to a directory and have a look at what it's done before committing to an initrd file and reboot.
This can save considerable hair loss :-)

hdc1, spam & losetup, various paranoia

nice howto. I didn't catch a couple of things, though:

1. you mention sdc1 as /boot device.. why? Just a typo?

2. is there any way to remove the *huge* spam comment just before mine? It triples the size of your howto. and the sites don't work, even! :)

3. just for reference, I've got some issues with a USB-drive watch; I can luksFormat the partition but cannot luksOpen it. To fix this I had to mount the partition via losetup:

losetup /dev/loop0 /dev/sda2
# then format it with luks
cryptsetup luksFormat /dev/loop0
# now I can open it
cryptsetup luksOpen /dev/loop0 rootfs
# close it
cryptsetup luksClose /dev/loop0
# and now I can even use cryptsetup with /dev/sda2
cryptsetup luksOpen /dev/sda2 rootfs

4. being the paranoid I am, I prefer to have a "clean" debian on my usb stick and make a fake swap partition as the encrypted one. Something like (in a /etc/fstab):
#/dev/sda2 none swap sw 0 0
the /dev/sda2 partition should be formatted with luksFormat. So I can boot via the usb stick, show a clean debian system, then use that system to open the /dev/sda2 encrypted/fake swap partition.
In case it get seized, it's just a usb stick with a linux version on it, and some garbage data on /dev/sda2 :)

..will try it and report it somewhere. cheers.

re: hdc1, spam & losetup, various paranoia

1. Probably a typo. Devices change depending on what system I was testing on when I wrote it.

2. Done. That spammer gets past the captka every so often and then gets filtered.

3. Never seen a situation like that. Might be specific to that media.

4. If you are going to do this, do not use LUKS for the "hidden" partition. LUKS has known headers and anyone to do a disk level examination will see it for what it is. On the other hand, if you don't use LUKS then it will appear as all random data end-to-end. Of course it will throw an error when swap tries to mount but you can probably ignore that and if questioned just say it corrupted itself somehow.

Thanks for the input and the compliment. Hope it works for you.

Any chance you could

Any chance you could describe the steps necessary to start this process from a Windows PC (XP or similar)? I assume it is only a few additional steps but have no clue where to start.

RE: Any chance you could....

Ok, the easiest way to do that will be to install the free VMWare Player and select a Debian GNU/Linux image file to run from their library.

Once you have the player installed, start it and select the Debian VMX file to load. Once Debian has loaded, you can follow the steps as documented in the howto.

Enjoy!

OK. I followed your

OK. I followed your procedure but have hit a problem during the testing phase.

The grub menu loads and everything goes smoothly until I enter the password for my encrypted partition. Moments after that, I get dozens of "Rejected I/O to dead device" errors. They come in groups of five or so, broken by messages about failures to start getty, id 3 and other parts of the boot process.

I probably made a mistake at some point during the configuration, but I haven't been able to track it down. Any ideas would be welcome.

One final note: like one of the other commentors here, I have a FAT32 sda1 partition on the USB key. (ie boot is sda2 and root is sda3). Perhaps the system is looking for sbin on sda1? But if so, why is it that it requested a password for sda3?

Error on boot up

I'm having the same problems. Grub starts the system, it asks me for the luks password, and then starts to boot, but somewhere in the process, I get the "Rejected I/O to dead device" errors (there's so many that I can't see where it's having the problem). I've redone the whole process twice, but on boot up

For info: I set this up using the most recent build of the debian testing release under VMware. The only thing that I did different was use the newest kernel image (linux-image-2.6.18-3-686).

any help would be appreciated!

Help with mkinitrd.yaird

I have followed this how-to step by step, but when started installing kernel i have stumbled this kind of errors:

Setting up linux-image-2.6.17-2-686 (2.6.17-6) ...
Running depmod.
Finding valid ramdisk creators.
Using mkinitrd.yaird to build the ramdisk.
yaird error: can't open directory /sys/block (fatal)
mkinitrd.yaird failed to create initrd image.
Failed to create initrd image.
dpkg: error processing linux-image-2.6.17-2-686 (--configure):
subprocess post-installation script returned error exit status 9
Errors were encountered while processing:
linux-image-2.6.17-2-686
E: Sub-process /usr/bin/dpkg returned an error code (1)

What can I do to get going with this?

Also, there is problem with localepurge v. 0.5.5, which is current version of it. It won't finish it's install, but I got it working with tiny workaround: Downloading older version from packages.debian.org, installing that, then installing newest version, and it works.

Despite that I was unable to get kernel, I wanted to try bootloaders, and I like grub more than lilo, so give that first shot. I exited chroot, and tried to install grub, but alas, it doesn't go into there. Then I removed grup and installed lilo in chroot, exited again and noticed that I don't have lilo installed at all outside of chroot. Is it planned to be installed outside too, or used just in chroot? (There was problems within chroot, it complained about /dev/hda there for some reason).

But I wish to get some help with that initrd problem, as output looks a bit different from this how-to...

re: Help with mkinitrd.yaird

OK.

1. For the /sys/block issue, from outside the chroot jail, mount /sys so that its bound to the external systems /sys. Like so:

mount -o bind /sys /mnt/buildroot/sys

2. Thanks for the heads up on localepurge, I'll keep it in mind if others have trouble.

3. Yes, whatever bootloader you choose to use, needs to have it binaries installed inside and outside the chroot jail. Most people prefer to use what they normally use so thats normally not an issue. And the rest of us can just install the deb package for the other in our base system. Additionally, some problems with /dev can be worked around by temp mounting /dev/ like we did /sys above. Try that.

Good Luck,

Dave

One more partition

Great HowTo !!!

My 2 cents : I add a fat32 partition so the "regular user" see the drive as a 32 Mb regular one with some regular files.

Thanks again for this howto !!!

Problem

replace this :

root@hostname# cd /mnt/buildroot/dev/
root@hostname# tar -cv /dev/sda* | tar -x

by this :

root@hostname# cd /mnt/buildroot/
root@hostname# tar -cv /dev/sda* | tar -x

due to some yaird problem

re: Problem

Fixed. Nice catch.

Thanks

Use loop-aes instead

This is not meant to be a flame or trollbait, so please don't take it as such.

While it's great to see guides of this ilk, I'd rather see people encouraged to use v.3+ loop-aes instead of cryptsetup and dmcrypt.

Why? Because it's better, and in actual fact is no more difficult to use, once set up. I'm no expert, but a bit of searching on the linux-crypto maillist will provide plenty of heated debate on this if you're curious The upshot is that loop-aes author Jari Rassu has been campaigning for years to get (eg) vulnerabilities fixed (he now outright calls dmcrypt "backdoored"), however these have been ignored. The dmcrypt people have responded in a rather ugly fashion imho - but when cornered they nevertheless admit he is correct but that the vulnerability is not significant enough to warrant fixing, or rather strange words to that effect.

It's a great pity that Fedora etc have seen fit to go with dmcrypt instead of loop-aes. However you can find recent versions of loop-aes in a number of livecds, including some of the leading security-oriented ones (eg INSERT, knoppix-STD).

re: Use loop-aes instead

Better? You should provide evidence of that because searching the linux-crypto mailinglist and other sites doesn't show it.

As for the "backdoor" issue that was blown way out of proportion by Jari Ruusu and was fixed back in the 2.6.10 kernel. I addressed this in my first howto on Debian-Administration.org. So the issue was not ignored.

As for plain-text attacks on the password, that is addressed by the Linux Unified Key Setup (LUKS) patches (more info: LUKS).

Also Mr. Ruusu is guilty of ignoring "theoretical" vulnerabilities when it suits him (see: http://mail.nl.linux.org/linux-crypto/2005-10/msg00024.html), and uses pretty much the same argument that its not significant enough to warrant fixing.

The reasons I choose to use dm-crypt over loop-aes are:

  1. Dm-crypt is included by default in the kernel. Loop-aes is not.
  2. Loop-aes requires that standard utilities like mount be patched, Dm-crypt does not.
  3. Yaird has hooks for automatic initrd creation, and initramfs will be adding them soon. Loop-aes requires that you use its build-initrd.sh script.

Now, this website is about exploring the configuration options so that the user can decide for themselves what is best for them. This is why I've written two howtos so far, this one and one for unencrypted devices. And it would be great if we had another howto for those that wanted to use Loop-aes, but it hasn't been submitted yet...(hint!).

Parameter does not match description

Correction: In "II. Wipe the Disk", you have parameter -v, but the description mentions -z.

(delete this comment when corrected or addressed)

Re: Parameter does not match description.

In this case it was the description that was wrong. I had cut and pasted it from my unencrypted howto. For an encrypted partition its better to leave the random data than to zero it, so we remove the zeroing step.

Nice catch though, thanks.

Long but Detail

The steps may be seemingly long, but it is written in great detail. It will be truly fun to install Linux on portable drives. As a mattar of fact, there are quite a number of devices which can be installed on portable drives nowadays, especially those portable applications.

will trash some thumbdrives

Blanking the top-level /dev/sda device like that will trash some thumb drives and make them un-recognizable as storage devices to usb.

I trashed my SONY memory vault that way, and all the various recovery tools to fix against such trashing could not recover it.

As an alternative try just re-partitioning the thumb drive and trash each partition, but be warned writing the partition table may also cause the same problem.

Sam

Did you recovered you pen

Did you recovered you pen drive? If yes, how ?

Under development

"This howto is undergoing current development and is subject to change."

Don't put it on Digg until it's ready.

Great

This is a great tutorial, had no problems following it whatsoever.

Great tutorial

Great tutorial, it is one really useful tutorial for newbie, I have some network software to make these steps more easy, Thanks for this info.

It is good. But I need to

It is good. But I need to the most easy method for that