Cover V14, i09

Article

sep2005.tar

The Need for Secure Data

Robert Bernier

All is not well for companies specializing in data management; they are under increasing pressure to ensure the security of personal information. As a result of recent events, there's a movement among many governments to enact new, tough privacy legislation. When these laws take effect (and they are already active in many jurisdictions), they will force companies who collect personal information to be liable if the security of their data-warehouse is breached. Recall the ChoicePoint incident that exposed hundreds of thousands of social security numbers in late 2004.

The legislation that is currently being proposed in California, for example, describes not only who and under what conditions confidential information can be released but also how that information should be stored on the servers. Suppose a hard drive is stolen, or more likely sold off, that contains driver license numbers, credit card numbers, etc. The law requires that those people to whom the information belongs must be informed by the company that compiled that information. The enterprise is held liable for all subsequent issues that may arise from the loss of control of that data. However, if the data has been encrypted, then it is not necessary to inform those individuals because the information cannot be harvested by criminal elements.

The purpose of this article is to introduce a technique that addresses this new climate of security threats and the expectations from both government and public alike. This method is easy and effective. It will work even if you lose control of the hardware. The technology is called "file system encryption", and the tool set is common to all Unix-like operating systems.

The Technical Nitty Gritty

No special hardware requirements are necessary and any relatively recent distribution of your operating system will work (e.g., Linux, FreeBSD, Solaris, even OSX).

For the purposes of this article, all utilities and methods will be made in the context of a Debian-based distribution of Linux using a 2.6 series kernel. Note that Microsoft-oriented people, who have very little experience with Linux, can still take advantage of this article by downloading the latest version of "pg_live", a Linux live CD that includes a replication-enhanced version of PostgreSQL 8.0. All you need to do is put it in the PC and turn it on. Pg_live will boot up and self-configure itself to run on your machine. It doesn't install on the hard drive and runs exclusively in RAM. Pg_live is available through Bit Torrent and is also available for download at the SRA America site at:

http://sraapowergres.com
You can learn more about pg_live and how to use it at:

http://sraapowergres.com/en/newsletter/issue_02/
Creating and Using a Simple File System

Creating a file system will require the following utilities: dd, losetup, mount, and mkfs.

The first step is to create an empty file that will hold the file system. You will want to consider how large you want it to be; otherwise, if it's too small, you will need to resize it later.

Creating a file is accomplished using the utility dd, you don't need to be root to do this. The following command will create a 100-KB empty file made up of the null character:

dd if=/dev/zero of=~/tmp/mysystemfile bs=1k count=100
The "if" switch identifies the input source (/dev/zero) and the "of" switch identifies the name of the output file (mysystemfile).

The "bs" switch defines how many BYTES should be read and inputted into the file at a time. Note that in this example the letter "k" was added to the number "1"; this means that a block of 1,024 bytes is inputted and outputted to the file "mysystemfile". The letter defines the unit of measure (i.e., "b" for bytes, "k" for kilobytes, "M" for megabytes, and "G" for gigabytes).

The count switch defines the number of reads and writes that should take place (i.e., bs=1k and count=100 means 1,000 X 100 or 100 KB).

Avoid making the bs value too large, such as the following, when attempting to create large systems files (e.g., 10 gigabytes):

dd if=/dev/zero of=~/tmp/mysystemfile bs=1G count=10
This command fails if you don't have at least 1 GB of RAM (1.024 GB to be exact). Use a higher count number instead. The following is more reasonable because it inputs/outputs smaller, 1 MB (1.024 MB), chunks:

dd if=/dev/zero of=~/tmp/mysystemfile bs=1M count=10000
Once created, the next step is to associate this file to a loop device using the losetup utility. There are eight loop devices on my own system, the first one being loop0. You'll have to have root privileges to do this:

losetup /dev/loop0 /home/bernier/tmp/mysystemfile
It's time to format the file system, which is accomplished using the standard mkfs utilities. For maximum security DO NOT create a journaled file system such as ext3. Use something like ext2, otherwise you'll have sensitive information in the cache memory:

mkfs /dev/loop0
Loop0 is, of course, where "mysystemfile" has been associated as the device.

Mounting the device is accomplished by using mount as root:

mkdir /home/bernier/mnt
mount -t ext2 /dev/loop0 /home/bernier/mnt
Note that, in most situations, the mount command will recognize the file system automatically, therefore the -t switch is not really necessary under Linux.

Typing mount without using switches returns a listing of all the devices currently mounted.

You can unmount the device with the umount command. Remember not to have any process running inside the file system or you won't be able to unmount it:

umount /home/bernier/mnt
Detaching the file "myfilesystem" from the device loop is the last step and is accomplished using the detach switch -d in the losetup command:

losetup -d /dev/loop0
Now that a file system has been created in "mysystemfile", future mounts and unmounts can be accomplished with a single command:

mount -o loop /home/bernier/tmp/mysystemfile /home/bernier/mnt
Using Encryption in a File System

The encrypted file system is first created, using losetup. The Debian distribution on which I based this article provides a number of different ways to accomplish this. The "loop-aes" package, used in this case, replaces the distribution's default mount, umount, and losetup utilities with encryption-enabled versions. But you must first have the crypto libraries compiled into the machine's kernel.

The type of encryption utilities and libraries available to you largely depends on what part of the world you're located in. Assuming you are downloading from a local Debian server in North America, the install command for the correct packages are:

apt-get install loop-aes
The losetup utility, as demonstrated below, requires that you manually input a password. Some ciphers such as "aes" require a minimum of 20 characters in length; otherwise the command fails and you get an error message.

losetup -e aes /dev /loop0 /home/bernier/mysystemfile
password: XXXX..
mkfs  /dev/loop0
mount /dev/loop /home/bernier/mnt
Verify that the file system is active by typing mount without any options. You can also identify the particular encryption composing losetup -a, which lists all currently configured loop devices.

Once you have created your encrypted file system, you can remount it with a single mount command using the -o option switch:

mount -o loop,encryption=aes /home/bernier/tmp/mysystemfile \
  /home/bernier/mnt
Choosing Your Password

Using the -p0 switch allows for standard input of the password. This lends itself well to a script, thus making the exercise of typing out a long password less painful:

cat mypasswordFile.txt | losetup -e aes -P 0 /dev/loop0
   /home/bernier/mysystemfile
The truly security-minded individual can generate a password of any length and save it to a file on a removable device, such as a floppy disk (or even an iPod). This two-line example uses "openssl" to generate 6,000 ASCII characters and saves it as a password file. It is then piped as standard input to "losetup":

openssl rand -out mypasswordFile.txt -base64 6000
cat mypasswordFile.txt | losetup -e aes -p0 /dev/loop0
   /home/bernier/tmp/mysystemfile
About Permissions

The last step is to create directories in the encrypted file system for the use of users and applications. In this example, I'm creating a "bernier" account for myself so that I can write data into the encrypted file system once it's mounted:

mkdir /home/bernier/mnt/bernier
chown bernier.bernier /home/bernier/mnt/bernier
Mounting the Encrypted File System

Mounting an encrypted file system requires root privileges; however, there are a number of techniques that can be used that will permit an ordinary user this same ability. The method shown here modifies the fstab file, which provides static information about the file systems, located in the etc directory. Add the following line:

/home/bernier/tmp/mysystemfile /home/bernier/mnt ext2
           defaults,user,noauto,loop,encryption=aes 0 0
Here's what the above line says -- the first field is the file containing the encrypted file system. The second field is the mount point. The third field is the file system type. The fourth field consists of a comma-separated list of options that apply to the mount and losetup commands, respectively. The fifth and sixth options relate to the dump and fsck commands, respectively; you can leave them both at "0".

Note that the options in the fourth field are read left to right. Options declared on the left are altered by subsequent commands to the right. The "noauto" option prevents the file system from automatically being loaded at boot time. Refer to the mount man page for further information about these and other options you can use here.

User name "bernier" can now mount the encrypted file system with the following command:

cat mypasswordFile.bin | mount -p0 /home/bernier/mnt
The password option "p0" was intentionally left out of the fstab file because it deprives a potential cracker of important information as to how and where the password is coming from.

There still might be problems with the way the fstab entry has been made if one considers that the "user" option permits anybody to attempt to mount the file system. Even though the attempt would require a password, this setup could lend itself to a brute force attack. At the very least, it could lead to unmounting problems if another user succeeded in mounting it. The issue can be resolved by doing two things:

1. Change the "fstab" option from "user" to "nouser" such that only root can invoke this mount instruction.

2. Create a "sudo" entry permitting user account "bernier" the ability to mount the file system.

Therefore, the "fstab" entry can be rewritten as:

/home/bernier/tmp/mysystemfile /home/bernier/mnt ext2
           defaults,nouser,noauto,loop,encryption=aes 0 0
These entries to the sudoers file permit user name "bernier" the ability to mount the file system via the sudo command:

Cmnd_Alias    MOUNT_ENCRYPT = /bin/mount -p0 /home/bernier/mnt
Cmnd_Alias    UMOUNT_ENCRYPT = /bin/umount /home/bernier/mnt
bernier       ALL = MOUNT_ENCRYPT, UMOUNT_ENCRYPT
The mount and umount commands can now be used by user name "bernier":

cat mypasswordFile.bin | sudo mount -p0 /home/robert/mnt
sudo umount /home/robert/mnt
A Word about Encryption Ciphers

Choosing what to use from the available ciphers depends upon two factors: security and speed. The more secure the data, the slower the processing. The fastest cipher is XOR encryption, but this isn't really much of a cipher because it is an obfuscation technique. On the other hand, AES256 is extremely secure with a 256-bit encryption algorithm, and the password is hashed with SHA-512. The security of a number of the ciphers offered depends on the length of the password. Hence, the longer the password the longer the encryption key length and, of course, the harder it becomes to crack the password using a brute force method.

Note that Debian's mount utility, in the aes package, can use gpg public key encryption (asymmetric ciphers). However, for the purposes of keeping this article from turning into a book, I will refrain from discussing this form of encryption and concentrate rather on the symmetric ciphers.

Being Practical

There are two areas of usage where you can put encrypted file systems to good use -- the first is a laptop that carries sensitive data. The second is a database server that holds sensitive information, such as credit card numbers.

The Laptop

The only thing that I'd like to add here is that a good login script streamlines the mount process for the user account. As a further security measure, you might want to execute the mount command from a shell that doesn't record the keystrokes (i.e., beware of bash's history functionality).

Securing Sensitive Data on a PostgreSQL Database Server

While you can perform row-wise encryption in a PostgreSQL database with the existing modules in the PostgreSQL distribution, column-wise and even table-wise encryption is possible when using the 8.0 table partitioning feature and storing data in an encrypted file system.

The method outlined here involves creating an updatable view that performs INSERTions and SELECTs. The columns are located not only in two separate tables but in two different partitions where one is in the clear/unencrypted (the name of the credit card holder) and the other is encrypted (the credit card number itself). Keep in mind that you want to keep as little information as possible in an encrypted format otherwise your installation is going to suffer a performance hit.

The following instructions assume that you have Postgres 8.0 already running and that the data cluster is located in the directory "/var/lib/pgsql8". Carry out the following instructions in a console as "root":

cd /var/lib/pgsql8
mkdir mnt
dd if=/dev/zero of=encryptedPartition bs=1M count=30
openssl rand -out mypasswordFile.txt -base64 60
cat mypasswordFile.txt | losetup -p0 -e aes256 /dev/loop1 \
  encryptedPartition
mkfs /dev/loop1
mount /dev/loop1 mnt
mkdir mnt/data
chown postgres.postgres mnt/data
You will have noticed that I created a 60-character randomly generated password using "openssl". It's quite easy creating passwords of any length using the openssl command-line utility from the OpenSSL cryptography toolkit.

These SQL commands are executed from the "psql" client as the superuser "postgres":

psql -Upostgres template1
CREATE DATABASE client;
\c client
CREATE TABLE client(id serial,name text);
CREATE TABLESPACE encrypted LOCATION '/var/lib/pgsql8/mnt/data';
CREATE TABLE confidential(id serial,credit_card text) \
  TABLESPACE encrypted;
Here's a little bit of PostgreSQL magic. The two tables "client" and "confidential" can be queried as one table by combining them into a view called "v_client":

CREATE OR REPLACE VIEW v_client (name,credit_card)
    AS SELECT name,credit_card 
        FROM client,confidential 
        WHERE client.id=confidential.id;
The following "rewrite rule" creates an updatedable view that permits data to be inserted transparently to both tables as though they were one:

CREATE OR REPLACE RULE ruleInsert_v_client AS ON INSERT
TO v_client DO INSTEAD
(
    INSERT INTO client (name) VALUES (NEW.name);
    INSERT INTO confidential (credit_card) VALUES (NEW.credit_card)
);
The special table name NEW (i.e., NEW.name, NEW.credit_card) refers to values that are being inserted or updated into a table. The table name OLD can also be used in a rewrite rule when the commands <code>UPDATE<text> or <code>DELETE<text> are used. Please refer to the PostgreSQL reference section under SQL COMMANDS for more information on rewrite rules.

The last series of steps involves testing what you've created by INSERTING and performing SELECT queries. Now we test... and it works:

INSERT INTO v_client(name,credit_card) \
  VALUES('Robert Bernier','23412441');
INSERT INTO v_client(name,credit_card) \
  VALUES('Brian Killer Pat','22345599');
INSERT INTO v_client(name,credit_card) \
  VALUES('Rocky Romantic','97274375');
SELECT * FROM v_client;
Tips

At file system creation time, you can prevent typing mistakes by using the -P switch in the losetup command so that it asks for your password twice:

losetup -P -e aes /dev /loop0 /home/bernier/mysystemfile
Practice everything covered here using xor encryption because it's very fast and doesn't require very long passwords, enabling you to type it out by hand.

Experiment with different encryption algorithms as you create your file system. Their performance will vary according to your security needs as well as your hardware configuration. Remember, you can only use those ciphers that have already been encrypted into your kernel.

Studying the man pages, listed at the end of this article, will offer you many options to increasing file system security.

Consider keeping your password file physically separate from your server/laptop in order to make it much more difficult to gain unauthorized access to the file system.

Make sure that you either manually unmount or install a script that will do it whenever you shut down your machine. Otherwise you run the risk of damaging the file system.

Conclusion

Identity theft has quickly risen to crisis-level proportions. Keeping your information under encryption will save you much grief. The techniques I've described here are straightforward and don't require much more than the standard tool set that is available on today's open source platform. Be proactive and protect your systems.

References

Links

SRA America -- http://sraapowergres.com

Bit Torrent -- http://www.bittorrent.com

PostgreSQL -- http://postgresql.org

Choicepoint identity theft -- http://www.msnbc.msn.com/id/6969799/

Identity theft conviction -- http://www.news10.net/storyfull10.asp?id=9611

New California privacy laws -- http://www.cio.com/archive/011505/california.html

Man Pages

dd

losetup

mke2fs

mkdir

mount

fstab

openssl

sudo

sudoers

visudo

Robert works as a consultant and has written for numerous magazines. He is also a regular writer for O'Reilly's onlamp.com. Currently, Robert is the PostgreSQL Business Intelligence Analyst at the Manhattan offices of SRA, Software Research Associates, which specializes in service and support for BSD and PostgreSQL. SRA (http://sraapowergres.com) was founded in the 1960s and is among the world's oldest software houses. Robert can be contacted at: robertb@sraapowergres.com.