Using eCryptfs on the B3

From BubbaWiki
Revision as of 12:20, 14 January 2011 by Asad (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

This article is taken from splitbrain.org and is written by Andreas Gohr. Updated to include the respective comments/changes.

There are several file encryption tools for Linux available. The one I like most currently is eCryptfs. Unlike other methods it works on top of an existing file system encrypting each file separately. This has many advantages:

  • you don't need to reserve space for encryption (like with creating a partition or a container file).
  • you can access the encrypted files and backup them to an untrusted location (like a cheap webhost).
  • if something breaks (think bitflip) only a single file is affected, not all your files (not sure if this is true for other systems too)

It also has some disadvantages:

  • eCryptfs systems can't be exported via NFS currently.
  • if you have many small files, you have some space overhead as each file has an encryption header.
  • maybe more

Anyway, I wanted to use it on my new B3 server. Here is how. Installing the Kernel Module

The B3 does not have the needed Kernel module, so we need to compile it ourselves. You could probably setup some cross-compile environment for that, but I found it much easier to just compile it on the B3 itself. It takes a while though ;-).

Login via SSH and become root, then install the build tools first:

#aptitude install devscripts build-essential lsb-release libncurses-dev

Now you need to fetch the kernel sources matching your running kernel.

# uname -a
Linux b3 2.6.35.4 #5 Tue Sep 7 16:06:15 CEST 2010 armv5tel GNU/Linux
# wget http://download.excito.net/kernel/Excito_B3/2.6.35.4/linux-2.6.35.4-excito.tar.bz2

Unpack it and get the current Kernel config from /proc:

# tar -xjvf linux-2.6.35.4-excito.tar.bz2
# cd linux*

Now run the config tool

# make bubba3_defconfig

The thing we're missing is

File systems --->
Miscellaneous filesystems --->
<M> eCrypt filesystem layer support (EXPERIMENTAL)

Be sure to select module (M), we don't want to build a completely new kernel here.

Now get a coffee and compile the modules.

# make modules

Once the compile succeeds you can copy the new module to the right place and load it:

# cp -r fs/ecryptfs /lib/modules/2.6.35.4/kernel/fs/
# depmod -a
# modprobe ecryptfs

Now you just need to add the user space utilities:

# aptitude install ecryptfs-utils

Setting up the Mountpoints

To have an encrypted directory, you specify a directory where the encrypted files should be stored (called lower directory) and then mount a virtual directory to where you want to access the decrypted files (the mount point).

Let's assume we want to encrypt the /home/storage/pictures directory (our mount point) and use /home/storage/.pictures as the lower directory. You have to decide if you want eCryptfs to encrypt the file names as well or just the file contents. Let's say we want the file names encrypted as well.

So let's start with creating the lower directory:

# mkdir /home/storage/.pictures

To actually setup the encryption you simply mount the directories using the ecryptfs file system type. The mount helper will ask you for the needed options:

# mount -t ecryptfs /home/storage/.pictures /home/storage/pictures
Passphrase: My secret passphrase!
Select cipher:
1) aes: blocksize = 16; min keysize = 16; max keysize = 32 (loaded)
2) blowfish: blocksize = 16; min keysize = 16; max keysize = 56 (not loaded)
3) des3_ede: blocksize = 8; min keysize = 24; max keysize = 24 (loaded)
4) twofish: blocksize = 16; min keysize = 16; max keysize = 32 (not loaded)
5) cast6: blocksize = 16; min keysize = 16; max keysize = 32 (not loaded)
6) cast5: blocksize = 8; min keysize = 5; max keysize = 16 (not loaded)
Selection [aes]: 1
Select key bytes:
1) 16
2) 32
3) 24
Selection [16]: 1
Enable plaintext passthrough (y/n) [n]: n
Enable filename encryption (y/n) [n]: y
Filename Encryption Key (FNEK) Signature [0123456789abcdef]:
Attempting to mount with the following options:
ecryptfs_unlink_sigs
ecryptfs_fnek_sig=0123456789abcdef
ecryptfs_key_bytes=16
ecryptfs_cipher=aes
ecryptfs_sig=0123456789abcdef
Mounted eCryptfs
WARNING: Based on the contents of [/root/.ecryptfs/sig-cache.txt],
it looks like you have never mounted with this key
before. This could mean that you have typed your
passphrase wrong.

Would you like to proceed with the mount (yes/no)? : yes
Would you like to append sig [0123456789abcdef] to
[/root/.ecryptfs/sig-cache.txt]
in order to avoid this warning in the future (yes/no)? : yes
Successfully appended new sig to user sig cache file
Mounted eCryptfs

If you don't want filename encryption, just say no when asked.

You now have setup the encryption and can start putting files in /home/storage/pictures.

To be able to easily remount the directories later, you should adjust your /etc/fstab:

/etc/fstab
/home/.crypt/hard /home/crypt/hard ecryptfs noauto,rw,ecryptfs_sig=0123456789abcdef,ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_fnek_sig=0123456789abcdef,ecryptfs_unlink_sigs,ecryptfs_passthrough=n 0 0

The needed signatures in these lines were displayed after your mount command above, but can also be seen by just calling mount on the command line. If you said no to filename encryption just skip the ecryptfs_fnek_sig parameter.

Be sure to add the noauto option or your B3 will not boot anymore (because it will wait for a passphrase)!

The directories can now be unmounted and mounted again by simply calling

# umount /home/storage/pictures
# mount /home/storage/pictures

Webinterface for Mounting

To have an easy way for mounting your encrypted directories, I wrote a PHP script that can be integrated into the B3 web interface. Install it to /usr/share/web-admin/admin/controllers/ecryptfs.php.

/usr/share/web-admin/admin/controllers/ecryptfs.php

<?php

class Ecryptfs extends Controller{

function __construct(){
parent::Controller();

require_once(APPPATH."/legacy/defines.php");
require_once(ADMINFUNCS);

$this->Auth_model->enforce_policy('web_admin','administer', 'admin');
load_lang("bubba",THEME.'/i18n/'.LANGUAGE);
}


function _renderfull($content, $head = '/disk/disk_head_view', $data = ''){
$navdata["menu"] = $this->menu->retrieve($this->session->userdata('user'),$this->uri->uri_string());

$mdata["navbar"]=$this->load->view(THEME.'/nav_view',$navdata,true);
$mdata["dialog_menu"] = $this->load->view(THEME.'/menu_view',$this->menu->get_dialog_menu(),true);
$mdata["head"] = $this->load->view(THEME.$head,$data,true);
$mdata["content"]=$content;
$this->load->view(THEME.'/main_view',$mdata);
}

function _list_mounts($haspass){
$fstab = file('/etc/fstab');
$fstab = preg_grep ('/^\s*#/',$fstab,PREG_GREP_INVERT);
$fstab = preg_grep ('/\secryptfs\s/',$fstab);
sort($fstab);

$mtab = file('/etc/mtab');
$mtab = preg_grep ('/^\s*#/',$mtab,PREG_GREP_INVERT);
$mtab = preg_grep ('/\secryptfs\s/',$mtab);
sort($mtab);

echo '<table class="ui-table-outline">';
echo '<thead>';
echo '<tr>';
echo '<th colspan="3" class="ui-state-default ui-widget-header">eCryptfs Mount Points</th>';
echo '</tr>';
echo '<tr class="ui-header">';
echo '<th width="50%">Mountpoint</th>';
echo '<th width="50%">Mounted</th>';
echo '</tr>';
echo '</thead>';
echo '<tbody>';
foreach($fstab as $num => $line){
$fields = preg_split('/\s+/',$line);

$ck = preg_quote($fields[0],'/');
$is_mounted = count(preg_grep("/^$ck\s/",$mtab));

echo '<tr>';
echo '<td>'.htmlspecialchars($fields[1]).'</td>';
if($is_mounted){
echo '<td style="color: green">mounted</td>';
}else{
if($haspass && $this->_mount($fields[1])){
echo '<td style="color: green">now mounted</td>';
}else{
echo '<td style="color: red">not mounted</td>';
}
}
echo '</tr>';
}
echo '<tbody>';
echo '</table>';

echo '<form action="" method="POST">';
echo '<fieldset>';
echo '<legend>Provide passphrase</legend>';
echo '<input type="password" name="pass" style="display:inline" />';
echo '<input type="submit" value="mount" style="display:inline" />';
echo '</fieldset>';
echo '</form>';
}

function _passadd($pass){
$fstab = file('/etc/fstab');
$fstab = preg_grep ('/^\s*#/',$fstab,PREG_GREP_INVERT);
$fstab = preg_grep ('/\secryptfs\s/',$fstab);
sort($fstab);

$mtab = file('/etc/mtab');
$mtab = preg_grep ('/^\s*#/',$mtab,PREG_GREP_INVERT);
$mtab = preg_grep ('/\secryptfs\s/',$mtab);
sort($mtab);

$fh = popen('/usr/bin/ecryptfs-add-passphrase --fnek -','w');
if(!$fh) {
echo '<p class="err">Failed to run the <code>ecryptfs-add-passphrase</code> command.</p>';
return false;
}
fwrite($fh,$pass);
$ok = pclose($fh);

if($ok !== 0){
echo '<p class="err">Something went wrong during passphrase add.</p>';
return false;
}

echo '<p class="err">Passphrase added to kernel keyring.</p>';
return true;
}

function _mount($mp){
$ok  = 0;
$out = array();
exec('/bin/mount -i '.escapeshellarg($mp),$out,$ok);
if($ok == 0){
return true;
}else{
return false;
}
}

function index(){
ob_start();

if(!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != 'on'){
echo '<p class="err">Please access this page via <a href="https://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'].'">HTTPS</a> only</p>';
}else{
$haspass = false;
if(isset($_POST['pass']) && $_POST['pass']){
$haspass = $this->_passadd($_POST['pass']);
}
$this->_list_mounts($haspass);
}
$content = ob_get_contents();
ob_end_clean();

$this->_renderfull($content);
}
}

Once installed, you can access it at https://b3/admin/ecryptfs.php 1). It lists all eCryptfs mount points from /etc/fstab and lets you mount them by providing the needed passphrase. If all your mounts use the same passphrase they will be mounted all at once. If you used different passphrases you need to supply them one by one.

Source: http://www.splitbrain.org/blog/2010-11/02-using_ecryptfs_on_the_b3