Benutzerspezifische Werkzeuge

Sektionen
Encrypt your Plone Database

Direkt zum Inhalt | Direkt zur Navigation

Encrypt your Plone Database

03.05.2016 in PlanetPlone
Detailed explanation on how to use cipher.encryptingstorage to encrypt your Data.fs and blobstorage directory.

Encrypt your Plone Database

wikicommons/Hk kng

It all began with a customer that needed his database and blobs encrypted on our server so the sysadmin or a hacker isn't able to read database records or blobs without additional efforts.

We thought about how to implement that and found cipher.encryptingstorage but it didn't encrypt blobs, so we asked for existing solutions on stackoverflow - without success. So we had some work to do...

cipher.encryptingstorage uses keas.kmi as encryption key manager, so you can have your encryption keys stored on another server. In this example, however we use a local keystore.

Tell buildout to create the dek-storage directory

Add the following to your buildout:

[buildout]
parts +=
    dek-storage_directory
    blobstorage-enc

# Creates the directory var/dek-storage for keas.kmi
[dek-storage_directory]
recipe = z3c.recipe.mkdir
paths = ${buildout:directory}/var/dek-storage/

# Creates the encrypted blobstorage directory
[blobstorage-enc]
recipe = z3c.recipe.mkdir
paths = ${buildout:directory}/var/blobstorage-enc/

Add an encryption.conf

Create the file production/encryption.conf.template:

[encryptingstorage:encryption]
enabled = true
kek-path = ${buildout:directory}/var/kek.key
dek-storage-path = ${buildout:directory}/var/dek-storage/

Add the following to your buildout:

[buildout]
parts += encryption.conf

# Creates the encryption.conf for keas.kmi
[encryption.conf]
recipe = collective.recipe.template
input = ${buildout:directory}/production/encryption.conf.template
output = ${buildout:directory}/encryption.conf

Add relstorage to your eggs and create a zodbconvert.conf

(This is only needed if you need to encrypt an existing database and blobstorage)

We use zodbconvert from relstorage to encrypt our "old" unencrypted Database.

Add it to your eggs:

[instance]
eggs =
    ...
    relstorage

Create a zodbconvert.conf.template:

%import cipher.encryptingstorage
<filestorage source>
    path ${buildout:directory}/var/filestorage/Data.fs
    blob-dir ${buildout:directory}/var/blobstorage/
</filestorage>

<encryptingstorage destination>
  config ${buildout:directory}/encryption.conf
  # FileStorage database
  <filestorage>
    path ${buildout:directory}/var/filestorage/encrypted.fs
    blob-dir ${buildout:directory}/var/blobstorage-enc/
  </filestorage>
</encryptingstorage>

Let buildout generate the template:

[buildout]
parts += zodbconvert.conf

# For converting a unencrypted Data.fs to a encrytped.fs
# with the help of relstorage.zodbconvert
[zodbconvert.conf]
recipe = collective.recipe.template
input = ${buildout:directory}/production/zodbconvert.conf.template
output = ${buildout:directory}/zodbconvert.conf

Add an /enc mountpoint to your ZEO and Instance(s)

We can't replace the main mountpoint in plone.recipe.zope2instance so we sadly need to add another mountpoint.

Add this to your plone.recipe.zeoserver:

# cipher.encryptingstorage
eggs =
    zope.component
    cipher.encryptingstorage

zeo-conf-additional =
  %import cipher.encryptingstorage
  <serverencryptingstorage enc>
    config ${buildout:directory}/encryption.conf
    # FileStorage database
    <filestorage>
      path ${:zeo-var}/filestorage/encrypted.fs
      blob-dir ${:blob-storage-enc}
    </filestorage>
  </serverencryptingstorage>

And this to your instance(s):

zope-conf-imports =
    cipher.encryptingstorage
zope-conf-additional =

    <zodb_db enc>
        # Main database
        cache-size 30000
    # Blob-enabled ZEOStorage database
        <encryptingstorage>
          config ${buildout:directory}/encryption.conf

          <zeoclient>
            blob-dir ${zeoserver:blob-storage-enc}
            shared-blob-dir on
            server ${zeoserver:zeo-address}
            storage enc
            name enc_zeostorage
            var ${zeoserver:zeo-var}
            cache-size 128MB
          </zeoclient>
        </encryptingstorage>
        mount-point /enc/Plone:/Plone
    </zodb_db>

Add a cronjob to remove decrypted blobs

Files in blobstorage need to be files on the filesystem so the application can access them. Due to this technical limitation, we need to save decrypted files to a temporary directory. To not end up with a decrypted copy of the whole blobstorage directory we are deleting all files older than 5 minutes that are currently not accessed by any user via a cronjob. See cipher.encryptingstorage pull #1.

Add this to your buildout:

[buildout]
parts += remove_plain_blobs

[remove_plain_blobs]
recipe = z3c.recipe.usercrontab
# Run every 5 minutes.
times = */5 * * * *
command = /usr/bin/find ${buildout:directory}/var/tmp -type f -amin +5 -exec sh -c "fuser -s {} || rm -f {}" \;
comment = Remove old decrypted blobs.

Now stop any instances and the zeo server

and run ./bin/buildout -c <your-conf>

Convert your existing Data.fs

run:

$ ./bin/zodbconvert zodbconvert.conf

This script will copy AND encrypt your var/filestorage/Data.fs into var/filestorage/encrypted.fs AND all blobs from var/blobstorage/ to var/blobstorage-enc/

It also creates a file var/kek.key - This is the encryption key for your encstorage!

Attention!

keep var/kek.key and var/dek-storage - both is needed to encrypt and decrypt your data! (you'll also need those keys to use the storage in another buildout.)

Move the old Data.fs and blobstorage

run:

$ mv var/filestorage/Data.fs var/filestorage/Data.fs.unencrypted
$ mv var/blobstorage var/blobstorage.unencrypted

(can/will be removed later)

Start your site.

run:

$ ./bin/zeoserver start
$ ./bin/instance fg

Connect somehow to your site

If running locally it's http://localhost:8461/manage

Create a new "ZODB Mount point"

In the ZMI choose add / "ZODB Mount point"

select "/enc" and click "Create selected mount points"

This will allow you to mount your Plonesite (previously located under /Plone) to enc/Plone (which is using the encrypted database created in step 3.

Rebuild the catalog

click on /enc/Plone then portal_catalog then the tab "advanced"

next click on "Clear and Rebuild".

Enable ZOPE users for Plone

Somehow you need to create a Plone site in / so that the Login as ZOPE User works in /enc/Plone.

Go to the ZMI and add a Plone site.

Done

Your site is now available through /enc/Plone.

Cleanup

If you feel save remove unencpryted data:

rm -rf var/filestorage/Data.fs.unencrypted
rm -rf var/blobstorage.unencrypted

Kommentare unterstützt durch Disqus

Webmeisterei GmbH, Bildgasse 10d, 6850 Dornbirn, AT, Telefon +43 5572 908000, Fax +43 5572 908000-15, office@webmeisterei.com