HOWTO: Quick GELI encryption guide

There are many ways to do this, as presented on forum, but this is the simplest method I've used.

This assumes you are using UFS for your disks. I will encrypt my AsusEEE which I carry with me everywhere and holds sensitive data.
This guide will encrypt whole disk, while using another small partition to /boot system.


1. Boot installation CD/USB, go to "Live CD".
2. Destroy previous partitioning
Code:
dd if=/dev/zero of=/dev/ada0 bs=512 count=1

Note: If you previously used GPT scheme on this disk, destroy it with
Code:
gpart destroy -F ada0

3. Use gpart to create partitions/bsdlabels
Code:
gpart create -s mbr ada0
gpart add -t freebsd -a 4k -s 768m ada0  # This is [FILE][B]/boot[/B][/FILE], enough to hold two full kernels
gpart add -t freebsd -a 4k         ada0  # This will be encrypted

gpart create -s bsd ada0s1
gpart add -t freebsd-ufs -a 4k ada0s1

gpart bootcode -b /boot/mbr ada0
gpart bootcode -b /boot/boot ada0s1
gpart set -a active -i 1 ada0

4. Label second partition
Code:
glabel label -v eee /dev/ada0s2

5. Init/attach geli
Code:
geli init -b -s4096 -l256 /dev/label/eee
geli attach /dev/label/eee
Note: speed difference between AES128 and AES256 is minimal at best, use AES256.

6. Now create bsdlabels for that second partition:
Code:
gpart create -s bsd /dev/label/eee.eli
gpart add -t freebsd-ufs  -s 768m /dev/label/eee.eli # /
gpart add -t freebsd-swap -s 512m /dev/label/eee.eli # swap
gpart add -t freebsd-ufs  -s 512m /dev/label/eee.eli # /var
gpart add -t freebsd-ufs  -s 512m /dev/label/eee.eli # /tmp
gpart add -t freebsd-ufs  -s 10g  /dev/label/eee.eli # /usr
gpart add -t freebsd-ufs          /dev/label/eee.eli # /home
Note: YMMV.

7. newfs everything you created so far:
Code:
newfs /dev/ada0s1a
newfs -j /dev/label/eee.elia
newfs -j /dev/label/eee.elid
newfs -j /dev/label/eee.elie
newfs -j /dev/label/eee.elif
newfs -j /dev/label/eee.elig

8. Mount your base system:
Code:
mount /dev/label/eee.elia /mnt
mkdir /mnt/var
mkdir /mnt/usr
mkdir /mnt/home
mount /dev/label/eee.elid /mnt/var
mount /dev/label/eee.elif /mnt/usr

9. Install:
Code:
sh
cd /usr/freebsd-dist
export DESTDIR=/mnt
for file in base.txz kernel.txz doc.txz src.txz
do
cat $file | tar --unlink -xpJf - -C ${DESTDIR:-/}
done

10. Add stuff to loader.conf:
Code:
echo 'geom_eli_load="YES"' > /mnt/boot/loader.conf
echo 'vfs.root.mountfrom="ufs:/dev/label/eee.elia"' >> /mnt/boot/loader.conf

11. And to fstab:
Code:
cat > /mnt/etc/fstab << __EOF__
/dev/label/eee.elia /     ufs    rw               1 1
/dev/label/eee.elib none  swap   sw               0 0
/dev/label/eee.elid /var  ufs    rw               2 2
/dev/label/eee.elie /tmp  ufs    rw,noatime,async 2 2
/dev/label/eee.elif /usr  ufs    rw               2 2
/dev/label/eee.elig /home ufs    rw               2 2
proc                /proc procfs rw               0 0
__EOF__

Note: YMMV.

12. Finally, copy boot contents to first partition you'll be booting from:
Code:
mount /dev/ada0s1a /tmp
cp -Rvp /mnt/boot /tmp/

13. reboot

Additional notes:

- Remember that your /boot that gets read at boot time is sitting on separate unencrypted partition, which was the whole point of creating it. This means that every change you make on encrypted partition which holds /boot should be copied to encrypted partition (such as building a new kernel, OR adding new nvidia.ko file, etc).
You could have your separate /boot partition mounted whole time, but I prefer not to.
You could also have /boot on small USB that you can plug in at boot time and then plug out after booting is done.
Pointed out by @fonz, thank you.


- If you have separate /tmp partition, don't forget to change its permissions like so:
# chmod 1777 /mnt/tmp
(or wherever is your /tmp). I figured this is a given 'housekeeping', so didn't mention it originally. Thanks for remind.

- If you get to part where geli can't mount correctly (mountfrom... error), change (in loader.conf):
Code:
vfs.root.mountfrom=ufs:/dev/label/eee.elia
to
Code:
vfs.root.mountfrom=ufs:/dev/ada0s2.elia
(or wherever is your encrypted root partition).
 
ryu said:
Doesn't work for me.
Care to elaborate? We're not mind readers you know. Why doesn't it work for you?

Do you get error messages? Does it cause the system to freeze up? Does it cause the kernel to crash? Does it fail to give you a cookie? Did it ruin your soup? Just saying "doesn't work for me" is not particularly helpful.

Fonz

P.S. Try it with spaces in the arguments like this (the red underscores are spaces):
Code:
geli init -b -s[red]_[/red]4096 -l[red]_[/red]256 /dev/label/eee
 
fonz said:
Care to elaborate?
P.S. Try it with spaces in the arguments like this (the red underscores are spaces):
Code:
geli init -b -s[red]_[/red]4096 -l[red]_[/red]256 /dev/label/eee

I got just a syntax error. I've mistken the "-l 256" as "-1 256". Sorry. ;)

But I have problems with another step now.

OP is saying:

newfs everything you created so far:

But you don't newfs the /dev/label/eee.elib, the swap space. Is this correct?

Also I don't understand this step:

And to fstab:

How to do this? I can't open it with vi or something. Should I just type the commands like all the other in the shell?

Code:
cat > /mnt/etc/fstab << __EOF__
/dev/label/eee.elia /     ufs    rw               1 1
/dev/label/eee.elib none  swap   sw               0 0
/dev/label/eee.elid /var  ufs    rw               2 2
/dev/label/eee.elie /tmp  ufs    rw,noatime,async 2 2
/dev/label/eee.elif /usr  ufs    rw               2 2
/dev/label/eee.elig /home ufs    rw               2 2
proc                /proc procfs rw               0 0
__EOF__
 
ryu said:
But you don't newfs the "/dev/label/eee.elib", the swap space. Is this correct?

Yes.

Should i just type the commands like all the other in the shell?

Code:
cat > /mnt/etc/fstab << __EOF__
/dev/label/eee.elia /     ufs    rw               1 1
/dev/label/eee.elib none  swap   sw               0 0
/dev/label/eee.elid /var  ufs    rw               2 2
/dev/label/eee.elie /tmp  ufs    rw,noatime,async 2 2
/dev/label/eee.elif /usr  ufs    rw               2 2
/dev/label/eee.elig /home ufs    rw               2 2
proc                /proc procfs rw               0 0
__EOF__

I made it convenient to just copy/paste this. Or you could type it manually.
 
bbzz said:
Or you could type it manually.

All right. I would type it manually directly in the shell, yes? Or should I open /mnt/etc/fstab with an editor (which?) and type it there?
 
The construct you see at point 11. is called a "here document". It basically inserts what's between the markers __EOF__ into the input stream as if it was typed at that point (the << signs) manually. Try it by changing the file name on the first for example to /tmp/fstab.
 
Oh well. I just want to type this all manually. How exectly can I do this? Sorry for all the questions, but I don't get it.

I understand step 11 like this:

Open /mnt/etc/fstab, type in this code and save.
Code:
/dev/label/eee.elia /     ufs    rw               1 1
/dev/label/eee.elib none  swap   sw               0 0
/dev/label/eee.elid /var  ufs    rw               2 2
/dev/label/eee.elie /tmp  ufs    rw,noatime,async 2 2
/dev/label/eee.elif /usr  ufs    rw               2 2
/dev/label/eee.elig /home ufs    rw               2 2
proc                /proc procfs rw               0 0

I just want to know how I can do this, directly from the shell. I can't open it with vi.
 
ryu said:
But you don't newfs the "/dev/label/eee.elib", the swap space. Is this correct?
More or less. Actually, it doesn't matter. You can newfs(8) the swap partition, it doesn't do any harm. But there's no point either because the filesystem will simply be overwritten (i.e. destroyed) the first time the swap partition is being used.

In other words: you don't need to newfs the swap partition, but it's not a problem if you accidentally do.

ryu said:
Should i just type the commands like all the other in the shell?

Code:
[red]cat > /mnt/etc/fstab << __EOF__[/red]
/dev/label/eee.elia /     ufs    rw               1 1
/dev/label/eee.elib none  swap   sw               0 0
/dev/label/eee.elid /var  ufs    rw               2 2
/dev/label/eee.elie /tmp  ufs    rw,noatime,async 2 2
/dev/label/eee.elif /usr  ufs    rw               2 2
/dev/label/eee.elig /home ufs    rw               2 2
proc                /proc procfs rw               0 0
[red]__EOF__[/red]
In the end, you need to somehow place the above lines minus the red ones into the file /mnt/etc/fstab. Exactly how you do that is entirely up to you. If you have copy-paste available, you can just copy-paste the entire thing (including the red lines) as one single command. You can also type it manually. Alternatively, you could use seperate echo commands: type something like
# echo "/dev/label/eee.elia / ufs rw 1 1" >> /mnt/etc/fstab
for every line except the red ones (don't forget to use >> and not >). And lastly, if you use FreeBSD 9.0 and choose "Live CD" in bsdinstall(8), vi(1) should be available.

Not to invalidate anything kpa said, on the contrary. But perhaps this clarifies things a bit further.

Fonz
 
Great. Thanks for the info. I will try this out.

Another question, why is it neccessary to create swap, /var, /tmp, /usr, /home in this guide manually? I found this tutorial http://namor.userpage.fu-berlin.de/howto_fbsd9_encrypted_ufs.html and it looks way more simple. (not only from the manually typing-side ;) ) What exactly is the difference between this two methods? Is one more secure? I just want to encrypt my whole HDD and don't know which method I should use.
 
The method I used is better [1].

Other method uses GPT. With GPT you can only create partitions. That means for every partition you need, /, /var, /usr, etc, you need another geli encrypted partition. This is quite a hassle when you boot a system, and puts quite a bit of additional resource penalty because now you have many encrypted partitions.

This tutorial uses MBR, which allows you to create bsdlabes inside slices, thereby allowing you to geli encrypt only one slice, and add all mentioned bsdlabels inside that one slice.

If you want only / partition, then it doesn't matter.

Also, there are examples which put swap on different slice and use one-time geli encryption upon boot. In this method you don't do that since swap is just another bsdlabel, making it overall simpler.

As for taking it longer to configure, I don't see how that would matter. Configuration is pretty straightforward and you are suppose to only do this once [2].


[1] What I would consider better might not be necessarily better for you. However, I would consider this method objectively better.
[2] Unless this is your first time and you are likely to blow up something and try it again.
 
bbzz said:
Other method uses GPT. With GPT you can only create partitions.

On the contrary, you can do the same with GPT:

Code:
foxi:(~)# gpart create -s gpt md0
md0 created
foxi:(~)# gpart show md0
=>     34  1048509  md0  GPT  (512M)
       34  1048509       - free -  (512M)

foxi:(~)# gpart add -t freebsd-zfs -s 128M md0
md0p1 added
foxi:(~)# gpart add -t freebsd md0
md0s2 added
foxi:(~)# gpart create -s bsd /dev/md0s2
md0s2 created
foxi:(~)# gpart add -t freebsd-ufs -s 64M /dev/md0s2
md0s2a added
foxi:(~)# gpart add -t freebsd-ufs -s 64M /dev/md0s2
md0s2b added
foxi:(~)#

You can check the label:

Code:
foxi:(~)# bsdlabel /dev/md0s2
# /dev/md0s2:
8 partitions:
#          size     offset    fstype   [fsize bsize bps/cpg]
  a:     131072          0    4.2BSD        0     0     0
  b:     131072     131072    4.2BSD        0     0     0
  c:     786365          0    unused        0     0     # "raw" part, don't edit
foxi:(~)#

# gpart show
Code:
=>     34  1048509  md0  GPT  (512M)
       34   262144    1  freebsd-zfs  (128M)
   262178   786365    2  freebsd  (384M)

=>     0  786365  md0s2  BSD  (384M)
       0  131072      1  freebsd-ufs  (64M)
  131072  131072      2  freebsd-ufs  (64M)
  262144  524221         - free -  (256M)

IMHO BSD slices are just pain .. pure pain .. specially when filesystem needs to be extended.
 
The latter is true. It is perfectly possible to first encrypt the "raw" disk with geli and then GPT-partition that one "container". In fact, I did exactly that mere days ago on my netbook. However, if for whatever reason you need to put the (always required) unencrypted boot partition on the same disk (instead of, say, a USB flash drive), you're forced to partition before encrypting and then you'll probably have to either use several containers indeed or use MBR+disklabel (one container per slice).

Just for completeness and/or clarity: if you do need to use several containers, it's possible to configure things such that "unlocking" (for lack of a better word) encryption only requires keyfiles rather than a whole bunch of passwords.

Perhaps I (or someone else) should write a complete encryption guide covering all sorts of setups. In fact I've already started just that but unfortunately I'm kinda busy (researching model checking for the Large Hadron Collider, among other things) and don't have a whole lot of free time to work on it.

Fonz
 
Is there a noticeable impact with encrypting the OS partitions vs just running plain UFS? I am running an AMD FX6100 with 6GB of RAM. I don't do as much disk i/o since half my time is spend ssh'd into other systems, but am wondering if I will notice the difference?
 
redw0lfx said:
Is there a noticeable impact with encrypting the OS partitions vs just running plain UFS?
I haven't done any benchmarking nor am I aware of others having done any, but my experience is that the performance penalty is not significant.

Fonz
 
Ah, that's nice, I didn't even thought GPT and bsdlabels.

In the end both methods work, I really don't see any difference. If anything, I found out that my Toshiba laptop won't boot GPT without BIOS hack, unfortunately.
 
fonz said:
Perhaps I (or someone else) should write a complete encryption guide covering all sorts of setups. In fact I've already started just that but unfortunately I'm kinda busy (researching model checking for the Large Hadron Collider, among other things) and don't have a whole lot of free time to work on it.

I would really appreciate it. ;)
 
Yes, I have managed to get it working on virtualbox at least. I've done the steps 10 and 11 with ee though. I will try it again on a physical drive later. Thanks for all the help and the nice guide.

I would like to know how to configure my LAN/DHCP settings to install GNOME etc. It was done automatically by sysinstall, but I don't know how to do it manually.
 
Many thanks as well. Configured FreeBSD on HP Mini-210 netbook using this guide, and I did not notice any difference in speed or disk i/o during write operations. I found it just a bit simpler setup than using LVM on CryptFS drive on ArchLinux (LVM on top of encrypted container).
 
I found an installer script for FreeBSD 9.0 and was wondering if it would be possible to implement the encryption part in this script?

I'm not asking for someone doing it, just wondering if it would be possible at all, for example with a preconfigured passphrase in the script.

Code:
#!/bin/sh
####
### Autor: hoschi@anukis.de
####

### Config
scriptversion="1.0"
freebsdversion="9.0"
sourcedir="/usb/FreeBSD_install"
destinationdir="/mnt/install"
installdir="/mnt"
prg_gpart="/sbin/gpart"

### Program (DONT TOUCH)
DONE="\033[80C\033[11D\033[1;34m -= OK =-\033[m"
i386pkg="base.txz doc.txz games.txz kernel.txz ports.txz src.txz"
amd64pkg="base.txz doc.txz games.txz kernel.txz lib32.txz ports.txz src.txz"
freebsdurl="http://ftp2.de.freebsd.org/pub/FreeBSD/releases"
usage="usage: $0 ad|da|ada[0123456789] i386|amd64

i386 or amd64 is optional

Example:
$0 ada0 
or
$0 da2 amd64 
"
clear
echo "starting installer version ${scriptversion} for FreeBSD ${freebsdversion}"
case "${1}" in
  ad[0-9]|da[0-9]|ada[0-9])
  echo " --> installing FreeBSD on ${1}"
  echo -n "  --> destroy all partitions on ${1}"
  ${prg_gpart} destroy -F ${1} >/dev/null 2>&1
  echo -e "${DONE}"
  echo -n "  --> create GPT on ${1}"
  ${prg_gpart} create -s gpt ${1} >/dev/null 2>&1
  echo -e "${DONE}"
  echo -n "  --> create boot partition on ${1}"
  ${prg_gpart} add -s 128k -t freebsd-boot -l boot -i 1 ${1} >/dev/null 2>&1
  echo -e "${DONE}"
  echo -n "   --> insert bootcode on ${1}"
  ${prg_gpart} bootcode -b /boot/pmbr -p /boot/gptboot -i 1 ${1} >/dev/null 2>&1
  echo -e "${DONE}"
  echo -n "  --> create 2GB swap partition on ${1}"
  ${prg_gpart} add -s 2G -t freebsd-swap -i 2 ${1} >/dev/null 2>&1
  echo -e "${DONE}"
  echo -n "  --> create 1GB root partition on ${1}"
  ${prg_gpart} add -s 1G -t freebsd-ufs -l root -i 3 ${1} >/dev/null 2>&1
  echo -e "${DONE}"
  echo -n "  --> create 1GB tmp partition on ${1}"
  ${prg_gpart} add -s 1G -t freebsd-ufs -l tmp -i 4 ${1} >/dev/null 2>&1
  echo -e "${DONE}"
  echo -n "  --> create 2GB var partition on ${1}"
  ${prg_gpart} add -s 2G -t freebsd-ufs -l var -i 5 ${1} >/dev/null 2>&1
  echo -e "${DONE}"
  echo -n "  --> create usr partition on ${1}"
  ${prg_gpart} add -t freebsd-ufs -l usr -i 6 ${1} >/dev/null 2>&1
  echo -e "${DONE}"
  echo -n "  --> UFS format all partitions "
  for i in ${1}p3 ${1}p4 ${1}p5 ${1}p6; do
    if [ "${i}" = "${1}p3" ]; then
      newfs -O1 "/dev/${1}p3" >/dev/null 2>&1  
    else
      newfs -O2 -U "/dev/${i}" >/dev/null 2>&1  
    fi
  done
  echo -e "${DONE}"
  echo -n "  --> mount all partitions "
  if [ ! -d "${installdir}" ]; then
    mkdir "${installdir}"
  fi
  mount "/dev/${1}p3" "${installdir}" 
  mkdir "${destinationdir}"
  mkdir "${installdir}/tmp" "${installdir}/var" "${installdir}/usr"
  mount "/dev/${1}p4" "${installdir}/tmp" 
  mount "/dev/${1}p5" "${installdir}/var" 
  mount "/dev/${1}p6" "${installdir}/usr" 
  echo -e "${DONE}"
 
 
  ####
  ### Part2 Download and install Software
  ####


  if [ -z "${2}"]; then
    v="`uname -m`"
  else
    v="${2}"
  fi
  echo " --> install FreeBSD ${freebsdversion} ${v}"
  case "${v}" in
    i386)
      if [ -d "${sourcedir}/${freebsdversion}/${v}" ]; then
        echo  "  --> found local install files"
        for i in ${i386pkg}; do
          echo -n "  --> copy file ${i} to ${destinationdir}"
          cp "${sourcedir}/${freebsdversion}/${v}/${i}" "${destinationdir}"
          echo -e "${DONE}"
        done
      else
        echo "  --> download install files"
        for i in ${i386pkg}; do
          echo -n "   --> download file ${i} to ${destinationdir}"
          cd ${destinationdir}
          fetch "${freebsdurl}/${v}/${v}/${freebsdversion}-RELEASE/${i}" >/dev/null 2>&1
          echo -e "${DONE}"
        done
      fi
    ;;
    amd64)
      if [ -d "${sourcedir}/${freebsdversion}/${v}" ]; then
        echo "  --> found local install files"
        for i in ${amd64pkg}; do
          echo -n "  --> copy file ${i} to ${destinationdir}"
          cp "${sourcedir}/${freebsdversion}/${v}/${i}" "${destinationdir}"
          echo -e "${DONE}"
        done
      else
        echo "  --> download install files"
        for i in ${i386pkg}; do
          echo -n "   --> download file ${i} to ${destinationdir}"
          cd ${destinationdir}
          fetch "${freebsdurl}/${v}/${v}/${freebsdversion}-RELEASE/${i}" >/dev/null 2>&1
          echo -e "${DONE}"
        done
      fi
    ;;
  *)
    echo "${usage}"
    exit 0
  ;;
  esac
  cd "${installdir}" 
  for i in `ls -1 ${destinationdir}/*.txz`; do
    echo -n "   --> install file ${i} to ${installdir}"
    tar -xzpf "${i}"
    echo -e "${DONE}"
  done
  echo -n " --> create ${installdir}/etc/fstab"
  echo "/dev/${1}p2	none	swap	sw	0	0
/dev/${1}p3	/	ufs	rw	1	1
/dev/${1}p4	/tmp	ufs	rw	2	2
/dev/${1}p5	/var	ufs	rw	2	2
/dev/${1}p6	/usr	ufs	rw	2	2
" > "${installdir}/etc/fstab"
  echo -e "${DONE}"
  echo -n " --> create ${installdir}/etc/rc.conf"
  all_interfaces="`ifconfig | egrep "^[a-z][a-z]?[a-z]?[a-z][0-9]" | cut -f1 -d':'`"
  echo 'hostname="beastie.freebsd.local"' > "${installdir}/etc/rc.conf" 
  for i in ${all_interfaces}; do
    if [ "${i}" != "lo0" ] ; then
      echo "ifconfig_${i}=\"DHCP\"" >> "${installdir}/etc/rc.conf" 
    fi
  done
echo '
keymap="german.iso"
keyrate="fast"
font8x8="NO"
font8x14="NO"
font8x16="NO"
scrnmap="NO"
' >> "${installdir}/etc/rc.conf" 
  echo -e "${DONE}"
  echo -n " --> create ${installdir}/boot/loader.conf"
  echo 'loader_color="YES"
loader_logo="beastie"
' > "${installdir}/boot/loader.conf"
  echo -e "${DONE}"
  ;;
  *)
    echo "${usage}"
    exit 0
  ;;
esac

exit 0
 
Back
Top