Benutzerspezifische Werkzeuge

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:

parts +=

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

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

Add an encryption.conf

Create the file production/encryption.conf.template:

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

Add the following to your buildout:

parts += encryption.conf

# Creates the encryption.conf for keas.kmi
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:

eggs =

Create a zodbconvert.conf.template:

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

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

Let buildout generate the template:

parts += zodbconvert.conf

# For converting a unencrypted Data.fs to a encrytped.fs
# with the help of relstorage.zodbconvert
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 =

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

And this to your instance(s):

zope-conf-imports =
zope-conf-additional =

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

            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
        mount-point /enc/Plone:/Plone

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:

parts += 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


$ ./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!


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


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

(can/will be removed later)

Start your site.


$ ./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.


Your site is now available through /enc/Plone.


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, Beim Gräble 2, 6800 Feldkirch, AT, Telefon +43 5572 908000, Fax +43 5572 908000-15,