SUSE Conversations


Encrypting Container Files in SLES 10 and SLES 11

mfaris01

By: mfaris01

January 20, 2011 4:40 pm

Reads:911

Comments:0

Rating:0

There are endless documents, articles, editorials and such, on data security and encryption. Views and opinions fly over which methods are better than others and why. AES, DES, Sha1, twoFish256, Blowfish, TripleDogDareYouFish192. File encryption, Partition encryption, Full disk encryption and the popular, No encryption.

This article is just concerned with showing you how to encrypt a small portion of data called a Container File. A container file is a file that has been created and converted to represent a partition. It is configured, formatted and mounted just like any traditional storage device, except it is still technically, a file.

In the title of this article I specify both SLES 10 and SLES 11, instead of just SLES. That is because with the release of SLES 11, encrypting a file system was changed. I am including SLES 10, as it is still widely used. We’ll walk through both of them in version order.

Why do I want to encrypt a container file and not just individual files or the entire disk? I do incorporate partition encryption, including SWAP, on my SLES 11 servers. I do not encrypt individual files because I have several I use, and keeping up with passphrases would cause me, to make a whole new encrypted file with the passwords to all of the other files. I’d rather make one container file and place the files I want to encrypt in it. All I have to do is mount the container file, do what I need to do, then dismount it.

One caveat to this approach is that while the container file is mounted, root will also have access to the data within that container file. But, once the container file has been dismounted, no one can mount it without the passphrase…Not even root.

There are other ways at getting to the data, probing SWAP or RAM, but those measures of security are beyond the scope of this article.

We’ll make some assumptions before we begin.

Ensure you have “root” access and a good working knowledge of Linux partitioning.

Encrypted Container Files – SLES 10

Creating a container file is fairly simple, and the basics pertain to either SLES 10 or SLES 11. Encrypting them is where the difference lies. Let’s start by creating a simple container file and mounting it. Then we’ll create another one and encrypt it.

Login as root, and if you’re not at the command prompt, open a gnome terminal.

First, we have to create the container file and specify the size we want. We’ll use “dd” for this. Create a 10MB file. You can put the file where ever you wish, I’m using /root/.

# dd if=/dev/zero of=/root/newfile.img bs=1k count=10000 
10000+0 records in
10000+0 records out
#

We tell “dd” to use “/dev/zero” to fill “newfile.img” with zeros using 1k blocks, for a count of 10,000.

# ll newfile.img 
-rw-r--r--  1 root root 10240000 Jan 14 19:21 newfile.img
#

We can see it has been created. Since this is not a true disk device, we have to set it up as a “loop” device. Linux provides 8 loop devices, by default. /dev/loop0-7. If you use loop devices for other purposes, you can determine which devices are already in use with the command “losetup –a”. We will use /dev/loop0 for our purposes.

Use the utility “losetup” to assign the new container file to loop0.

# losetup /dev/loop0 /root/newfile.img 
#

To see if the assignment was successful, use “losetup –a”.

# losetup –a
/dev/loop0: [0802]:68867 (/root/newfile.img)
#

Now that the container file is ready for a file system. We’ll format it with EXT2 using “mke2fs”

# mke2fs -c /dev/loop0 10000
mke2fs 1.38 (30-Jun-2005)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
2512 inodes, 10000 blocks
500 blocks (5.00%) reserved for the super user
First data block=1
2 block groups
8192 blocks per group, 8192 fragments per group
1256 inodes per group
Superblock backups stored on blocks: 
        8193

Checking for bad blocks (read-only test): done                        000
Writing inode tables: done                            
Writing superblocks and filesystem accounting information: done

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

#

Create a mount point for the new device. You can create this where ever you need to. We’re using /mnt/.

# mkdir /mnt/newfs
#

And then mount the device.

# mount -v -t ext2 /dev/loop0 /mnt/newfs
/dev/loop0 on /mnt/newfs type ext2 (rw)
#

Get a listing of the new mounted container file.

#
# ll /mnt/newfs/
total 13
drwxr-xr-x  3 root root  1024 Jan 14 19:25 .
drwxr-xr-x  4 root root    96 Jan 14 19:26 ..
drwx------  2 root root 12288 Jan 14 19:25 lost+found
#

Let’s check with a “mount” and a “df” command.

# mount
/dev/sda2 on / type reiserfs (rw,acl,user_xattr)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
tmpfs on /dev/shm type tmpfs (rw)
devpts on /dev/pts type devpts (rw,mode=0620,gid=5)
/dev/loop0 on /mnt/newfs type ext2 (rw)
# 
# df –h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda2              19G   14G  5.3G  73% /
tmpfs                1013M   12K 1013M   1% /dev/shm
/dev/loop0            9.5M   13K  9.0M   1% /mnt/newfs
#

If you want to make it easier to mount on boot up, place an entry similar to this in your /etc/fstab file.

/root/newfile.img     /mnt/newfs    ext2      noauto,exec,loop=/dev/loop0     0 0

We use the “noauto” option to prevent it from mounting on boot, but we can mount it easily with mount /mnt/newfs

Before we continue and since we want to use the same loop device, let’s clean up a bit.

Unmount the device

# umount /mnt/newfs
#

Remove the loop device assignment.

# losetup –d /dev/loop0
#

Now let’s do the same thing, but we’ll encrypt the container file.

In this scenario, we want to create an encrypted container file that is only usable by a certain user. The container file will reside in their /home/user01/ directory and we’ll name it with a preceding “.” so it is normally hidden from directory listings. We’ll be using AES 128 bit encryption, which means we need to add it to the kernel first. AES isn’t loaded into the kernel by default.

To verify if the AES module is loaded, use “lsmod”

# lsmod | grep aes
aes                    27200  0
#

If you do not see it, use “modprobe –list | grep –e aes” to find the module and load it with “modprobe [aes_module_name]”

Again, we create the container file using “dd”, but we’re going to make the parameters a little different.

# dd if=/dev/urandom of=/home/user01/.cryptfile bs=4k count=10000
10000+0 records in
10000+0 records out
40960000 bytes (41 MB) copied, 0.339379 s, 121 MB/s
#

This time, we used “/dev/urandom”, which fills the file with random data, instead of all zeros. We also created the file in a user’s home directory and put a “.” as the first character in the filename. We stated 4k blocks * 10000 and you’ll see that the container file is 41 MB in size.

We’ll encrypt the file with “losetup” using the “-e” option and specify the type of encryption, “aes”.

# losetup -e aes -T /dev/loop0 /home/user01/.cryptfile
Password: 
Error: Password must be at least 20 characters.
#

It failed because our Password MUST be a minimum of 20 characters. The “-T” option makes us enter the password twice to verify. In SLES 11, the option was changed to “-y” and the “-T” was dropped, so you’ll get an error.

# losetup -e aes -T /dev/loop0 /home/user01/.cryptfile 
Password: 
Retype password: 
#

Not real verbose, is it. Let’s see if it worked using “losetup –a”

# losetup –a
/dev/loop0: [0802]:68867 (/home/user01/.cryptfile) encryption=aes
#

There it is. Now, like before, we have to format it.

# mke2fs  -t ext2 /dev/loop0
mke2fs 1.38 (30-Jun-2005)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
10000 inodes, 40000 blocks
2000 blocks (5.00%) reserved for the super user
First data block=1
5 block groups
8192 blocks per group, 8192 fragments per group
2000 inodes per group
Superblock backups stored on blocks: 
        8193, 24577

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

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

We’re not going to mount it yet. We want “user01” to be able to use this container file, exclusively. Remove the loop0 assignment first.

# losetup –d /dev/loop0
#

Create a mount point and change the owner to “user01” to this space. To keep regular users out of this directory, when mounted, assign the group as “root” and change the POSIX for “Other” to 0.

# mkdir /mnt/crypt
# cd /mnt/crypt/
# chown user01.root .
# cd ..
# chown user01.root crypt
# chmod -R 640 crypt
#
# ll
drw-r----- 2 user01 root 6 Jan 15 17:13 crypt
#

Add the following or similar to the /etc/fstab.

/home/user01/.cryptfile    /mnt/crypt    ext2     noauto,users,loop=/dev/loop0,encryption=AES    0 0

Again, “noauto”, so it must me manually mounted and we added, “users” so “user01” can mount it without “sudo”.

Let’s try it out as user, “User01”.

$ mount /mnt/crypt
Password:
$

Notice it prompted for the Password we assigned? If you enter it incorrectly, you will receive a mount error about superblocks.

We’ll take a look at mounts and “df” also.

$ ll /mnt/crypt/
drw--r----  2 user01 root 12288 Jan 14 19:25 lost+found
$
$ mount
/dev/sda2 on / type reiserfs (rw,acl,user_xattr)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
tmpfs on /dev/shm type tmpfs (rw)
devpts on /dev/pts type devpts (rw,mode=0620,gid=5)
/dev/loop0 on /mnt/crypt type ext2 (rw)
$ 
$ df –h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda2              19G   14G  5.3G  73% /
tmpfs                1013M   12K 1013M   1% /dev/shm
/dev/loop0             41M   13K   41M   1% /mnt/crypt
$

Pretty Sweet, huh! Now User01 is done with whatever they do with that space and unmounts it.

$ umount /mnt/crypt
$

That’s pretty much it for SLES 10.
There are a few things to point out.

  • The most important is that you nor anyone else cannot change the password on the container file. The encryption of the container file is based on that password. There is a way to change it, but basically, you create a new container file and move the files from one to the other and then remove the old one. Not really a password change.
  • If you move the file to another location, remember to change the /etc/fstab file our you’ll get a call.
  • I haven’t tried symlinks either to or from, with this method.

Encrypted Container Files – SLES 11

In SLES 11, they brought the ability for hard disk encryption and integrating it into YaST, especially during installation. They changed from standard looping devices to “cryptoloop” and handling encrypted partitions using a device mapper “dm-crypt”. In addition, LUKS, Linux Unified Key Setup, was added because it is a special format for encrypted volumes and it is integrated on top of “dm-crypt”. “dm-crypt” has no limit on the number of encrypted partitions as there are only 8 loop devices.

I’ll explain more features and cool stuff as we build an encrypted container file in SLES 11. I want to point out that all of the steps listed in this section are also available within YaST.

Let’s start by creating the container file for User01, as we did earlier.

#  dd if=/dev/urandom of=/home/user01/.cryptfile bs=4k count=10000    
10000+0 records in
10000+0 records out
40960000 bytes (41 MB) copied, 8.41466 s, 4.9 MB/s
#

Now here’s where it becomes different. We want to assign the file to a loop device, but we omit the encryption option.

# losetup -v /dev/loop0 /home/user01/.cryptfile 
Loop device is /dev/loop0
#

Using the utility, “cryptsetup”, we’ll encrypt the container file. We pass luksFormat as this is a new partition.

# cryptsetup -v --key-size 256 luksFormat /dev/loop0

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

Are you sure? (Type uppercase yes): YES
Note: make sure keyboard layout and encoding here matches
the intended environment for unlocking the volume
Enter LUKS passphrase: 
Verify passphrase: 
Command successful.
#

Unlike “losetup” that required a 20 character minimum on the passphrase, “cryptsetup” will take 1 character. I haven’t seen anything yet that can force this to require a higher minimum.

One thing LUKS allows for is multiple passphrases. This can be helpful as a fallback should the primary get lost or simply forgotten. See man page for cryptsetup.

Let’s take a look at our work. Using “cryptsetup”, we can perform a luksDump to display the details of the container file.

# cryptsetup -v luksDump /dev/loop0
LUKS header information for /dev/loop0

Version:        	1
Cipher name:    	aes
Cipher mode:    	cbc-essiv:sha256
Hash spec:      	sha1
Payload offset: 	2056
MK bits:        	256
MK digest:      	42 4e c1 28 b7 3c df 16 de d0 53 4f 64 8b bc 4a 9e 97 7d 92 
MK salt:        	a5 5a 52 b3 ae 62 cd c8 0c 58 3e 37 08 13 da 11 
                	4a 0c 5e 7f b4 ba 99 c5 13 ad 80 d3 0b 9d 4e 3d 
MK iterations:  	10
UUID:           	d51ace66-d295-41f2-a47e-f95b5ee667f4

Key Slot 0: ENABLED
        	Iterations:             	224473
        	Salt:                   	b9 a0 cb 0b de ba ac 51 94 8b ad b8 99 90 40 d1 
             	                   	3a ad ad ba 38 ce dd a0 38 4c c1 8a 90 c8 77 55 
        	Key material offset:    	8
        	AF stripes:             	4000
Key Slot 1: DISABLED
Key Slot 2: DISABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: DISABLED
#

Now we will open the container file using luksOpen option.

# cryptsetup -v luksOpen /dev/loop0 cryptfs
Enter LUKS passphrase: 
key slot 0 unlocked.
Command successful.
#

This command should have created the device under /dev/mapper/. Let’s list the entries in that directory.

# ll /dev/mapper/
total 0
lrwxrwxrwx 1 root root     16 Nov 26 13:14 control -> ../device-mapper
brw-r----- 1 root disk 253, 4 Jan 15 20:35 cryptfs
brw-r----- 1 root disk 253, 0 Nov 26 13:14 root-opt
brw-r----- 1 root disk 253, 1 Nov 26 13:14 root-root
brw-r----- 1 root disk 253, 2 Nov 26 13:14 root-tmp
brw-r----- 1 root disk 253, 3 Nov 26 13:14 root-var
#

And there it is, “cryptfs”.

Next, we put a file system on it. Here, we’ll use EXT3.

# /sbin/mkfs.ext3 -O dir_index,resize_inode /dev/mapper/cryptfs 
mke2fs 1.41.9 (22-Aug-2009)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
9760 inodes, 38972 blocks
1948 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=40108032
5 block groups
8192 blocks per group, 8192 fragments per group
1952 inodes per group
Superblock backups stored on blocks: 
        8193, 24577

Writing inode tables: done                            
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done

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

Before we can mount it, we need to make an entry in both /etc/fstab and /etc/crypttab

/etc/fstab

/dev/mapper/cryptfs    /mnt/crypt    ext3    noauto,user     0 0

/etc/crypttab

crypt /home/user01/.cryptfile none luks

Mount the new container file.

# mount /dev/mapper/cryptfs /mnt/crypt
#

Copy some files to it and let’s see if they are there.

# ll /mnt/crypt/            
total 595
-rw-r--r-- 1 root root 351048 Jan 15 20:41 compat-2009.1.19-2.1.i586.rpm
drwx------ 2 root root  12288 Jan 15 20:37 lost+found
-rw-r--r-- 1 root root 241551 Jan 15 20:42 rkhunter-1.3.8.tar.gz
#

Once again, umount the container file when you are done using it to prevent others, namely, “root” from accessing your files.

With previous versions, “/etc/init.d/boot.crypto” was started at boot. In SLES 11, it is “off”, you will need to run “chkconfig boot.crypto on” to enable cryptoloop for your devices.

Conclusion

The SLES 11 Security Guide, in the documentation offers little more than a couple of paragraphs on File System Encryption. I found a lot more information in the man pages and few very old encryption rants and trying it myself. I admit I prefer the SLES 11 methods as they are cleaner, and with LUKS, the encryption options are much more robust than previous versions.

Enjoy!

VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Tags: , ,
Categories: SUSE Linux Enterprise Server, Technical Solutions

Disclaimer: As with everything else at SUSE Conversations, this content is definitely not supported by SUSE (so don't even think of calling Support if you try something and it blows up).  It was contributed by a community member and is published "as is." It seems to have worked for at least one person, and might work for you. But please be sure to test, test, test before you do anything drastic with it.

Comment

RSS