Encrypting Devices
A variety of methods can be used at the OS level to encrypt a device or volume on which to locate a PostgreSQL cluster instance. At the database level,PostgreSQL will need to be
configured to use that location.
Cryptmount
Cryptmount has been tested under Debian (discussion at
GNUmed developer thread).
you can use cryptmount ( a debian package) and read the man pages on how to setup a cryptmount directory.
the idea is to map a block of disc space onto a device e.g. in a directory /dev/mapper/ , if the block device is named "opaque" then the mapping would be /dev/mapper/opaque.
Then setup opaque by first mounting it with cryptmount and customize the cryptmount configuration file in /etc/cryptmount/cmtab ; an example mapping is given in the cryptmount man pages, which can be cut-pasted in and altered. Basically, this associates the device with a key ; the key encrypts a secret key, which decrypts the the mounted device.
the idea is to generate the key, mount the raw device using the option --prepare, make a new filesystem on the mounted device, then unmount the device.
there after using , cryptmount opaque ( which is the name referring to the block which will be mounted on /dev/devmapper/opaque) , will prompt for a password, and if successful, mount the drive.
Example:
1. use dd to create a large empty file
dd if=/dev/zero of=/var/local/opaque.fs bs=100MB count=50
explanation : "if=" input file, here the zero emitting device is used, "of=" output file, here "opaque.fs" is a new file ,
"bs=100MB", blocksize will be 100MB, "count=50" 50 x 100MB = 5G of blockspace will be created;
additionally, if there is enough room left on the filesystem, and one has not allocated enough space,
opaque.fs can be expanded using, "dd if=/dev/zero of=/var/local/opaque.fs bs=100MB count=10 seek=50" , where seek=50 will skip the first 50 blocks; the new size will then be (50+10 ) x 100MB = 6000MB .
Of course, any data needs to be backed up first if it is not dispensable, as there is probably room to accidently overwrite the old file.
2. then create the entry for the /etc/cryptmount/cmtab for the file .
e.g.
opaque {
dev=/var/local/opaque.fs dir=/home/crypt
fstype=ext3 cipher=twofish
keyfile=/etc/cryptmount/opaque.key
keyhash=md5 keycipher=bf-cbc
}
I have tried fstype=xfs, cipher = aes, keycipher = aes-128-cbc , and so far these have worked.
3. then generate the key using "cryptmount --generate-key opaque" , which will generate the keyfile /etc/cryptmount/opaque.key
and encrypt the key using the keycipher method . A password will be asked for.
4. then , do " cryptmount --prepare opaque " ; this sort of "premounts" the encrypted partition in /var/local/opaque.fs, so that
a filesystem can be added to it . A password will be asked for.
5. mkfs.ext3 /dev/mapper/opaque , ( mkfs.xfs /dev/mapper/opaque if the fstype=xfs ), will create the filesystem in opaque ,
6. "cryptmount --release opaque" ; this releases the the encrypted filesystem.
7. "cryptmount opaque" will mount the encrypted drive, and a password will be asked for.
NB. the files system will be where the "dir=" shows, e.g. /home/crypt .
"cryptmount -u opaque" unmounts the filesystem.
Creating the gnumed database on the mounted encrypted filesystem.
Some lazy people will just then do "initdb -D /home/crypt/pg_gnumed_v2" , or something like that, but this
is not recommended. A better way is to use
initlocation, or if using a later version of postgresql > 7.4 ,
create tablespace,
Using initlocation ( pg <= 7.4)
In postgresql 7.4,
initlocation is a command-line postgres program which makes an environment variable visible to a backend,
for the purpose of copying a database template onto an alternate location , separate from the cluster location defined
when initdb was initially run.
initdb is often run during installation of postgres as a binary package of whatever
distribution is being used . e.g. a linux flavour, windows ; so it a little inconvenient to , and a book-keeping problem,
when alternate clusters with separate postmaster processes are created with initdb being run manually, just to use
a single postgres database on a separate encrypted filesystem.
a)
su ;
mkdir /home/crypt/pg_gnumed_v2;
chown postgres.postgres /home/crypt/pg_gnumed_v2
b)
su postgres; CRYPT_GNUMED_V2=/home/crypt/pg_gnumed_v2;
export CRYPT_GNUMED_V2
c)
initlocation CRYPT_GNUMED_V2;
createdb -D CRYPT_GNUMED_V2 gnumed_v2
explanation:
a) although cryptmount can be run as a script run by postgres user, assume that cryptmount has been
run by superuser, so do 'su'; mkdir in the crypt filesystem a directory for the gnumed_v2 database to be stored 'pg_gnumed_v2'.
then make postgres the owner of that directory, otherwise the postmaster , which is usually run as the postgres user, will not
be able to use it easily.
b) then become postgres to make sure the shell variables are with the right user; create the environment variable
that points to the crypt filesystem gnumed_v2 database directory ; export it , so that initlocation can use it.
c) do
initlocation {ENV_NAME} without the $ prefix .
The difference here, is that the template database template0 and template1 and postgres will all stay with the original
location of the original installation of postgres, but the gnumed_v2 database will have a template copied to
the crypt filesystem , as a secondary alternate storage location for that particular database of the original cluster.
Using TABLESPACE
Later versions of postgresql ( >7.4) do the above alternate database location problem , a little differently :
the steps would be
a) the same as above, ( create a postgres-owned database directory in the encrypted file system )
b) create a sql script with the lines:
create tablespace crypt_tablespace
location '/home/crypt/pg_gnumed_v2';
create database gnumed_v2
with tablespace crypt_tablespace;
c) then run it through 'psql -f template1' as postgres user.
After managing to create an alternate database directory on the encrypted filesystem ,
which will be accessible by postgres as the database "gnumed_v2", the rest of the bootup procedure,
should be the same for a new database ( unless of course the bootstrap script deletes the database
and doesn't run createdb with the right parameters).
What is probably more failsafe is to create the database in an unencrypted filesystem, and then transfer
it with one of 2 methods:
1) pg_dumpall -g -h source_host -U gm-dbo | psql -f -U gm-dbo template1 ;
pg_dump -h source_host -U gm-dbo gnumed_v2 | psql -f -U gm-dbo gnumed_v2
the above transfers the globals ( users) from the source host's cluster to the local cluster, and then transfers
gnumed_v2 from the source host to the local host.
2) another possibility , with clusters, is to use scp to copy one cluster directory on a host
to the local cluster directory, after destroying the local cluster directory.
This will work, but is a bit tricky if the gnumed_v2 database is existing in a separate tablespace
directory .
What can be done is to figure out which of the base/ directories in the source cluster is
the gnumed database , usually be examining it's size with du -sH .
scp the largest base/ subdirectory to the alternate tablespace directory on the filesystem.
Next, an entry is needed in pg_database in the psql, for the new database.
This can be done by inserting all the values (including the oid) from pg_database corresponding to the
copied base/ subdirectory , except the dattablespace value, which should be
the value of the alternate tablespace row's oid in the local pg_tablespace table.
At least, this is doable for a destructive copy of the source cluster of databases,
and should be doable even if just copying one database of the source cluster.
What really is needed, is a script for migrating databases around, between machines, and between tablespaces,
using scp, and automagically altering the pg_database table to match the migration.
WARNING : this is reckless messing around with postgesql 's data directory structure, and might
be good to backup before trying it.
Using an encrypted suspend image, e.g. for a laptop.
this of course , can still be a problem if you use hibernate or s2disk on your laptop, as anyone can resume the hibernated session,
and the cryptmount filesystem , may be already mounted ; so it's a good idea to use the uswsusp package which provides s2disk , with a encrypted suspend image , so resuming always begins will a prompt for a password , and the suspended session image is also
cryptographically stored .
To use uswsusp ( remember u swiss user space ?, I can never spell this ), debian requires a linux kernel image >= 2.17 ,
a good sized swap file ( I've got about 500MB , which sometimes isn't enough if I 've got too much open) ;
For some reason , the kernel image version is not checked before uswsusp is installed.
To make sure the current kernel you are using is configured to use uswsusp,
run
/usr/sbin/configure-debian , select admin, and then configure uswsusp, which will take you
through the configuration of uswsusp. Note, it regenerates the initrd image,
and writes some scripts to the /premount scripts, so that
during boot, a check is made for a uswsusp image on the resume device,
(usually the swap partition). It's a good idea to regenerate the initrd image, if the
uswsusp is not working, and then use gparted to reformat any defunct swap partition ( do this at the
start of the session). The swap partition has a fixed size (created during the debian
installation process , a long time ago ) , and if it is listed as unknown in gparted,
then it has been corrupted, and needs to be formatted again as a linux-swap partition, the format applied,
and then activated with "swapon", also in the gparted right-click menu.
What follows below is the manual way of configuring uswsusp.
of course, everything is as weak as the password(s) used. even though cryptmount can be configure to use AES encryption; at least cryptmount gives you the option easily of changing the password ;
for s2disk , this can be done using ,
"suspend-keygen /etc/uswsusp.key"; the encryption involves generating a RSA public-private key
where uswsusp.key is the keyfile in the uswsusp conf file.
an example /etc/uswsusp.conf file:
resume device = /dev/hda5 # this is the swap partition
encrypt = y
compress = y
early writeout = y
RSA key file = /etc/uswsusp.key # this points to the key file generated with suspend-keygen
shutdown method = platform
Occasionally, the suspend process is broken, especially if the swap partition is
smaller than the suspend image.
To fix it , re make the swap partition, and then remount it using swapon
e.g.
swapoff /dev/hda5
mkswap /dev/hda5
swapon /dev/hda5
gparted can do this for you , using a gui interface.
Thereafter, closing a few windows , or terminating anothe switched user session, will often fix the
too large suspend image problem.
HOWTO Encrypt All Data On Your Hard Drive(s) (except for “/boot” and “/”) Or Any Storage Block Device (Both Logical And Physical) With Truecrypt In Linux
original works is availbale from
here
Any storage device where you keep private stuff is worth considering if you should encrypt it or not. If you are running a business and keep your back up on a remote media such as an USB connected hard drive, or if someone who you don’t trust lurks around in your server room, beware that whoever has physical access to your hard drives are able to steal your information without you ever noticing it.
Thats where truecrypt comes in handy. Truecrypt enables you to encrypt block devices on the fly by mapping up your devices in /dev/mapper, enabling you to access them from there. It is very simple to use, and installing it is also simple. It comes with a kernel module and a binary. I will discuss how to encrypt USB connected storage media, the /home directory, and the swap. Don’t forget to encrypt your swap.
But firstly I will discuss the general way of encrypting devices. The procedure is the same no matter if you choose a physical or a logical device, in this example it is the physical disk /dev/sda1 that is to be encrypted:
# truecrypt -c /dev/sda1
This command creates an encrypted device. Wipes it. And fills it with lots of random nonsense so that you cant tell how much of the disk that is used. This is also a clever way to erase old deleted data from disks. You will be prompted for all options, Password first. Remember that if you choose a weak password you might as well not encrypt your device at all. Information about strong passwords can be found here.
Then there will be questions about whether you’d like an hidden volume or not. Having a hidden volume is necessary only if you suspect someone wants your encrypted data really badly, such as a Mafioso. The law of your country may also force you to give your passwords or key files in some cases. I will not discuss how you manage a hidden volume, but there is information about it here.
You will also be prompted for encryption algorithms. Confronted with all of those options, keep in mind that they’re all good. Choosing a really bad ass algorithm such as “Serpent-Twofish-AES” will take more CPU to handle, and will also take more time to initially encrypt than other algorithms.
There is information about the alghorithms here. Information about hash algorithms can be found here.
You will also be able to choose if you’d like to initially write a FAT file system to your device or not. I wouldn’t. Using Linux, there are far better file systems IMHO, such as ext3 or the mighty reiserFS.
Then you will be asked if your mouse is directly connected to the computer your using if not, you will have to type 350 or so random characters.
Once created, the encrypted device will be accessible if you invoke the following command.
# truecrypt /dev/sda1
This maps the device into /dev/mapper. The logic of the encrypted devices name is that it will be named truecryptX where X is the first available number. In other words, if this is the first device you map, then it will be /dev/mapper/truecrypt0. This is only the case if you do not use the -N flag. In that case you may specify which ever unused device number you like.
Now write a file system of your choice to your encrypted device.
# mkfs.reiserfs /dev/mapper/truecrypt0
Remember not to write the file system to /dev/sda1, as you will have to re-encrypt it if you do.
Now you can mount it as usual with # mount -t reiserfs /dev/mapper/truecrypt0 /mnt/pnt, or you could mount it with truecrypt instead.
# truecrypt –filesystem reiserfs /dev/sda1 /mnt/pnt
# truecrypt -l lists mapped, encrypted devices.
1. Howto encrypt USB connected storage media (or whatever storage media for that matter)
Now I choose to encrypt the whole device, which in my case is /dev/sda, whitout partitioning it. If you’d like to write a partition table to your device before encrypting it, go ahead.
# truecrypt -c /dev/sda
I anwer all of them questions, creating a visible partition with no FAT file system. If you think you’ll ever use the device in a windows environment, then you may consider letting truecrypt prepare a FAT file system for you.
Then I map it, write a file system to it and mount it
# truecrypt /dev/hda
# mkfs.reiserfs /dev/mapper/truecrypt0
# truecrypt /dev/hda /mnt/pnt
Done!
2. Encrypting /home
The initial way to do this is the same as in the prior example. /dev/sda should be replaced with the device corresponding with the drive you’re about to encrypt and finally mount into /home. If you intend to use the same device as your current /home is mounted from then
- /home must be on a separate partition/device
- you must have somewhere to temporarily store everything in /home.
2.1 moving /home
While it is possible to do this in multi user mode I advice against it. Files may change while they’re being copied and you risk corrupting files if you do. The safest way to proceed is to enter single user mode. Save all open files, and invoke
# init 1
make a tar archive of your /home
# tar -cvspf /mnt/tmphome/home_direcytory.tar /home
Or copy the /home
# cp -rp /home /mnt/temphome
No matter which alternative you choose, remember that you will need to preserve the files permissions and ownerships. or else you probably wont be able to startx nor do a lot of other things. using tar or cp with the -p is a great way to preserve those things.
2.2 moving back /home
Now you do the same thing as you did when you encrypted the “Howto encrypt USB connected storage media” in step 1. Except that you under no circumstances make a FAT file system.
When you’ve encrypted the file system, mount it.
# truecrypt /dev/sda1 /home
Copy /home files to your newly mounted, encrypted device:
With cp:
# cp -rp /mnt/temphome /home
Or tar:
# tar -xf /mnt/tmphome/home_direcytory.tar /home
Now try it out. Switch into multi user mode with init 3 (the actual runlevel may vary depending on which dist you are using). su into your normal user and do som random, normal stuff to ensure that it works fine.
2.3 making the encrypted /home mount on boot
Edit your /etc/fstab file and comment the line that makes /home mount.
Now edit /etc/rc.local. The commands that are written into this file is usually executed after all other stuff during boot.
truecrypt /dev/hda5 /home
From now on, during boot time, you will be prompted for password each time you boot your computer. Note that you can use /etc/rc.local to have truecrypt mounting any encrypted device.
3. encrypting the swap
Many people forget the importance of encrypting the swap file. The swap is used to store data, and it may potentially contain pieces of sensitive information which a “black hat” hacker may use to obtain your sensitive information.
First use swapoff to stop swapping on your swap device. If you swap on /dev/hda1, then you use swapoff like this
swapoff /dev/hda1
Now encrypt the device with truecrypt. Do not write a file system on it. Then map it.
# truecrypt /dev/hda1
# truecrypt -N 242 /dev/hda1
I had truecrypt naming the device truecrypt242 because it makes it easier for you to keep track of which device you’re supposed to swap on.
Now make swap and swapon the device:
mkswap /dev/mapper/truecrypt242
swapon /dev/mapper/truecrypt242
Your swap is now encrypted. To do this at boot time from now on, you can add:
truecrypt -N 242 /dev/hda1
mkswap /dev/mapper/truecrypt242
swapon /dev/mapper/truecrypt242
And your Done.
Other methods can be added thus