Single passphrase to boot Devuan GNU/Linux with multiple encrypted partitions

These days, considering the amount of data are stored on an average computer and how easy is it to get access to it once you get physical access, running such computer without any form of encryption seem unsound. Especially since it is reasonably easy to set up a en encrypted system and does not seems to imply much overhead.

When you have an old setup you are fine with, using numerous partitions or systems, it can be inconvenient, though. For instance  if you have to type a long specific passphrase 5 times when booting your computer.

There are a few things I found useful to make my life easier. Obviously, any shortcut security wise means less security. It is help to you to decide whether the risk is worth it or not depending on what kind of data you carry, what kind of attackers you expect, etc. This is part 1.

Single passphrase to boot GNU/Linux with multiple encrypted partitions

One obviously approach to type a single passphrase to boot a system is to have the boot loader files on a regular partition and the rest on a single encrypted partition. In GNU/Linux case, you would have /boot on a specific non-encrypted partition. Fact is anyone with access to your computer can easily replace your kernel or initramfs with a malicious one and you would not notice.

So I think non-encrypted /boot is as much of the table as would be a non-encrypted swap partition.

So for the boot manager grub to load, /boot need to be readable: the passphrase will be required here. The idea is that from this moment on, a keyfile will be used instead of passphrase to load any other partition.

I guess there is not much point to describe in detail the crypt setup itself (I followed the many guides out there). For each partition you want:

# 1. you create the partition with parted/fdisk

# 2. you format it as encrypted
cryptsetup luksFormat /dev/sdX1

# 2b. you record it in crypttab
# <target name> <source device> <key file> <options>
echo "Name1 UUID=`blkid -s UUID -o value /dev/sdX1` /boot/k/ka luks,tries=3" >> /etc/crypttab

# 3. you open the encrypt-formatted partition
cryptsetup luksOpen /dev/sdX1 Name1

# 4. you format the resulting /dev/mapper... to a regular filesystem
mkfs.ext4 /dev/mapper/Name1 -L Name1

# 4b. you record it in fstab (adjusting the mount point!)
# <file system> <mount point> <type> <options> <dump> <pass> 
echo "/dev/mapper/Name1 / ext4 errors=remount-ro 0 1" >> /etc/fstab

# you are set, you can mount the partition, 
#  and install the system/copy the system there

The swap  require specific treatment. Provided you know one with partition is the current  unencrypted swap is (here sdX?), this is enough:

# update crypttab
echo "SW `find -L /dev/disk -samefile /dev/sdX? | grep by-id | tail -1` /dev/urandom swap" >> /etc/crypttab

# update fstab
echo "/dev/mapper/SW  none   swap sw 0 0" >> /etc/fstab

Noticed the /boot/k/ka? That’s the unlocking key. You can use whatever other filename, just be consistent.

# generate some
dd if=/dev/urandom of=/boot/k/ka bs=1024 count=4
chmod 400 /boot/k/ka

# and obviously, add it to any luks formatted partition:
for part in `blkid | grep crypto_LUKS | awk {'print $1 '} | tr -d :$`; do cryptsetup -v luksAddKey $part /boot/k/ka; done

Then, you need a proper initramfs:

# dracut works almost out of the box
apt install dracut

# set up a few things
echo 'omit_dracutmodules+="systemd systemd-initrd dracut-system"' > /etc/dracut.conf.d/00-systemd.conf
echo 'add_dracutmodules+="crypt lvm"
install_items+="/sbin/e2fsck /sbin/cryptsetup /boot/k/ka"' > /etc/dracut.conf.d/99-luks.conf

# (re)build ramfs
dracut --force

# make sure there are no old initrd leftovers, that would confuse grub
rm /boot/initrd* -f

 

Then, you need to edit grub (version 2!) config:

# first obtain the UUID of crypted partition (not the /dev/mapper/... one) 
# that hold the /boot partition. 
# (it was Name1 earlier but obviously it depends to the real name you gave)
grep Name1 /etc/crypttab

# now edit /etc/default, with XXXXXXXXXXXX being the UUID value
# you just found.
GRUB_CMDLINE_LINUX="rd.luks.key=/boot/k/ka:UUID=XXXXXXXXXXXX"
GRUB_ENABLE_CRYPTODISK=y
GRUB_PRELOAD_MODULES="luks cryptodisk lvm"

# and now update-grub (install grub if not done yet)
update-grub

It took me a while to find the proper rd.luks.key value, no docs I read were clear about it. Many give the impression that putting rd.luks.key=/keyfile or rd.luks.key=/keyfile:/ would be enough since the key is actually on the same partition as grub.cfg. But no.

That is all. Rebooting now, you should be asked for the passphrase before getting the grub menu. And then boot process should be uninterrupted.

Advertisements

Using networked filesystems hosted by LXC containers with Samba

For more than a decade, I used NFS on my home server to share files. I did not consider using Samba for anything but to provide Windows access to shares. NFSv3 then NFSv4 suited me, allowing per host/IP write access policy. The only main drawback was very crude handling of NFS server downtime: X sessions would be half-frozen, requiring restart to be usable once again.

However, I moved recently my servers to LXC (which I’ll probably document a bit later) and NFS server on Debian, as you can guess from nfs-kernel-server package’s name, is kernel-based: not only it apparently defeats the purpose of LXC containers to actually have a server within a container tied to the kernel, but it does not seems to really work reliably. I managed to get it running, but it had to be run on both the master host and within the container. Even then, depending which started first could make the shares unavailable to hosts.

I checked a few articles over the web (https://superuser.com/questions/515080/alternative-to-nfs-or-better-configuration-instable-network-simple-to-set-up, http://serverfault.com/questions/372151/nas-performance-nfs-vs-samba-vs-glusterfs etc) and it looked that, as of today, you can expect decent performances from Samba, as much as of NFS. That could possibly be proven wrong if I was using massively NFS, writing a lot through networked file systems, opening a big number of files simultaneously, moving big files around a lot, but I have really simple requirements: no latency when browsing directories, no latency when playing 720p/1080p videos and that’s about it.

I had already a restricted write access directory per user, via Samba, but I use it only on lame systems as temporary area: on proper systems, I use SSH/scp/rsync/git to manipulate/save files.

Dropping NFS, I have now quite a simple setup, here are relevant parts of my /etc/samba/smb.conf:

[global]

## Browsing/Identification ###

# What naming service and in what order should we use to resolve host names
# to IP addresses
 name resolve order = lmhosts host wins bcast


#### Networking ####

# The specific set of interfaces / networks to bind to
# This can be either the interface name or an IP address/netmask;
# interface names are normally preferred
 interfaces = eth0

# Only bind to the named interfaces and/or networks; you must use the
# 'interfaces' option above to use this.
# It is recommended that you enable this feature if your Samba machine is
# not protected by a firewall or is a firewall itself. However, this
# option cannot handle dynamic or non-broadcast interfaces correctly.
 bind interfaces only = true


#### File names ####

# remove characters forbidden on Windows
mangled names = no

# charsets
dos charset = iso8859-15
unix charset = UTF8


####### Authentication #######

# "security = user" is always a good idea. This will require a Unix account
# in this server for every user accessing the server. See
# /usr/share/doc/samba-doc/htmldocs/Samba3-HOWTO/ServerType.html
# in the samba-doc package for details.
 security = user

# Private network
 hosts allow = 192.168.1.


# You may wish to use password encryption. See the section on
# 'encrypt passwords' in the smb.conf(5) manpage before enabling.
 encrypt passwords = true

# If you are using encrypted passwords, Samba will need to know what
# password database type you are using. 
 passdb backend = tdbsam

obey pam restrictions = yes

guest account = nobody
 invalid users = root bin daemon adm sync shutdown halt mail news uucp operator www-data sshd Debian-exim debian-transmission
 map to guest = bad user

# This boolean parameter controls whether Samba attempts to sync the Unix
# password with the SMB password when the encrypted SMB password in the
# passdb is changed.
 unix password sync = yes


#======================= Share Definitions =======================


realm = ...


[commun]
comment = Commun
path = /srv/common
browseable = yes
writable = yes
public = yes
guest ok = yes
valid users = @smbusers
force group = smbusers
create mode = 0660
directory mode = 0770
force create mode = 0660
force directory mode = 0770

[tmpthisuser]
comment = Données protégées
path = /srv/users/thisuser
browseable = yes
writable = yes
public = yes
valid users = thisuser
create mode = 0600
directory mode = 0700
force create mode = 0600
force directory mode = 0700
guest ok = no

 

I installed package libpam-smbpass and edited /etc/pam.d/samba as follow:

@include common-auth
@include common-account
@include common-session-noninteractive
@include common-password

For this setup to work, you need every user allowed to connect:

  • to be member of group smbusers – including nobody (or whatever the guest account is) ;
  • to have a unix password set ;
  • to be known to samba (smbpasswd -e thisuser or option -a).

If you are not interested in per user access restricted area, only nobody account will need to be taken care of.

And, obviously, files and directories ownership and modes must be set accordingly:

cd /srv/common
# (0770/drwxrwx---) GID : (nnnnn/smbusers)
find . -type d -print0 | xargs -0 chmod 770 -v
find . -type f -print0 | xargs -0 chmod 660 -v
cd /srv/users
# (0700/drwx------) UID : ( nnnn/ thisuser) GID : ( nnnn/ thisuser)
find . -type d -print0 | xargs -0 chmod 700 -v
find . -type f -print0 | xargs -0 chmod 600 -v
# main directories, in addition, need sticky bit some future directory get proper modes
chmod 2770 /srv/common/*
chmod 2700 /srv/users/*

To access this transparently over GNU/Linux systems, just add in /etc/fstab:

//servername/commun /mountpoint cifs guest,uid=nobody,gid=users,iocharset=utf8 0 0

This assumes that any users entitled to access files belongs to users group. If not, update accordingly.

With this setup, there is no longer any IP based specific write access set but, over years, I found out it was quite useless for my setup.

The only issue I have is with files with colon within  (“:”). Due to MS Windows limitations, CIFS list these files but access is made impossible. The easier fix I found was to actually rename these files (not a problem due to the nature of the files served) through a cronjob /etc/cron.hourly/uncolon :

#!/bin/bash
# a permanent cifs based fix would be welcomed
find "/srv" -name '*:*' -exec rename 's/://g' {} +

but I’d be interested in better options.

 

 

Switching from NFSv3 to NFSv4

Today, I switched over NFSv4. I guess there published it for some reason and people claim it could increase file transfert rate by 20%.

In my case, to get it working properly, I…

Modified /etc/default/nfs-kernel-server on server side to have

NEED_SVCGSSD=no

Modified /etc/default/nfs-common on both clients and server side to have

NEED_STATD=no
NEED_IDMAPD=yes
NEED_GSSD=no

Modified /etc/exports on server side to have something starting by


/server 192.168.1.1/24(ro,fsid=0,no_subtree_check,async)

/server/temp 192.168.1.1/24(rw,nohide,no_subtree_check,async,all_squash,anonuid=65534,anongid=65534)

[...]

It forces you to set a root for the NFS server, in my case /server (which I had already in my NFSv3 scenario, so…), aka fsid=0.
You also need to specify nohide for any exports.

Modified /etc/fstab on clients side to set mount type to nfs4 and to remove the /server part from the paths, no longer necessary as path are relatives to fsid=0 which is /server. It gives entries like:

[...]
gate:/temp /stockage/temp nfs4 nolock 0 0
[...]

I had an export which was a symlink to somewhere in /home. NFSv4 is stricter than NFSv3 and there is no way to export something outside from fsid=0. So I made a bind, adding to /etc/fstab on server side:

[...]
/home/torrent/watch /server/torrent/watch none bind 0 0
[...]

After restarting nfs-kernel-server on the server side and nfs-common on both sides, umount NFS partitions and doing a mount -a on the client side, everything seems fine.

Using partitions labels

Recent linux versions (yes, I’m talking kernel here – linux is not an operating system) introduce new IDE drivers. It implies a device naming convention change. Instead of hda, hdb, etc, you get sda, sdb, etc, just like SCSI drives.

I have three hard disks on my main workstation – plenty of partitions. So in my case, it makes sense to use a unique identifier for each partition so nothing breaks up whenever I add/remove a drive or boot on an older kernel with the previous IDE drivers.

There are already uniques ids for each partition available using the command blkid. It returns unbearables and meaningless, but very uniques, ids like af8485cf-de97-4daa-b3d9-d23aff685638.

So it is best, for me at least, to label partitions properly according to their content and physical disposition, which makes for uniques id too in the end.

For ext3 partitions, I just did:

e2label /dev/sda2 sg250debian64
e2label /dev/sda3 sg250home

For the swap, e2label cannot help, so we set the label with mkswap, recreating it:

swapoff /dev/sda1
mkswap -L sg250swap /dev/sda1
swapon -L sg250swap

For ntfs partitions, I did:

apt-get install ntfsprogs
ntfslabel /dev/sdb1 hi150suxor
ntfslabel /dev/sdb2 hi150suxor2

Then, /etc/fstab must be edited as:


LABEL=sg250swap none swap sw 0 0

LABEL=sg250debian64 / ext3 errors=remount-ro 0 1
LABEL=sg250home /home ext3 defaults 1 2

LABEL=hi150suxor /mnt/suxor ntfs-3g defaults,user,noauto 0 0
LABEL=hi150suxor2 /mnt/suxor2 ntfs-3g defaults,user,noauto 0 0

Finally, grub (or any other boot loader) config should be updated to reflect that. However, unless I’m mistaken, with grub2 as shipped by debian, everything is generated usings scripts that does not seem to handle labels 😦