At work we have a client who has an important requirements about the work we do: at the end of the project, all artifacts will be transferred to them and we will not retain a copy. This is important to them in order to protect intellectual their property. If we do not have a copy, we cannot leak their data. When the project concludes, we give them all their data and delete it.
While isolating their data isn’t too difficult, how does one deal with backups? Running without backups isn’t a good idea so backups are needed, but there is the risk of those backup being compromised by an attacker. And the requirements state we need to remove all IP from our systems on the conclusion of the project. Erasing backups goes against the purpose of making the backups. So what is the alternative.
The solution is EncFS running in reverse mode. This will allow a directory to be mirror in encrypted form. The backup service can then run on this ciphered mirror. When the project finishes, the key to the ciphered mirror is discarded. Thus, while the data exists in backups, it is moot as there is no way to access use it.
For our setup, I generate a random encryption key and store it on a USB drive. Should backups be needed, this USB drive will allow the backups to be deciphered. Once the encrypted volume is mounted, the drive can be taken to a secure location until the project ends. After that, the drive can either be securely erased, destroyed or given to the client.
Here are the steps needed to setup such a system on a Debian server:
sudo apt install encfs
Create random password. This should be stored on an external drive such as a USB disk. Note this file must be kept secure. The following will create a 512-bit random key, saved in base-64.
dd if=/dev/urandom bs=64 count=1 | base64 -w 0 > /mnt/usb/password.b64.txt
For this example we use two paths: /srv/project contains the data we need to have backed up. /srv/backup is the mount point where the encrypted data will appear and what the backup services uses.
Now to create an encrypted mount for this:
encfs --public --reverse --extpass="cat /mnt/usb/password.b64.txt | base64 -d" /srv/project/ /srv/backup/
Note that the public option allows other users to have access to the backup directory. This is useful as the backup service will likely have a dedicated backup user who will need this access. By default this mount is read-only. Granting global read access won’t be a problem as the encrypted data is safe by its nature. The extpass parameter tells encfs to type the password file and decode the base64. The output from this command will be used as the password.
After the command runs it will create a configuration file in the /srv/project directory. This configuration file is needed to decipher the backups and should be moved onto the USB drive.
mv /srv/project/.encfs6.xml /mnt/usb/encfs6.xml
Note that although the configuration file is absolutely required to decrypt the data, it does not contain the key. Thus it is safe to allow this file to be created locally and moved. The key, if truly desiring no traces, must remain on the USB drive and nowhere else.
Now everything in /srv/backup is encrypted and safe to allow a backup program to duplicate.
sudo umount /srv/backup
To mount in the future, use:
sudo encfs -c /mnt/usb/encfs6.xml --public --reverse --extpass="cat /mnt/usb/password.b64.txt | base64 -d" /srv/project /srv/backup
The key file will not be needed again unless the ciphered directory is unmounted. It should be moved to a secure location.
Should the backups be needed, they can be restored to some location like any backups. Then the encrypted directory needs to be mounted to see the plaintext.
Mount the encrypted backup to restore:
encfs -c /mnt/usb/encfs6.xml --extpass="cat /mnt/usb/password.b64.txt | base64 -d" /srv/restoredCipher /srv/restorePlaintext
This command assume the backup has been restored to a directory called /srv/restoredCipher and there is an empty mount point called /srv/restorePlaintext.
The plaintext directory should have a perfect copy of the original data. To verify a copy correctly matches the original, run this command in both /srv/project and /srv/restorePlaintext:
find . -type f | sort | xargs sha256sum - | sha256sum -
Note: you must be in the directory for this to work or the path names will show up and the sums will not match.
The command will get a list of all files, sort the list, generate an SHA-256 sum for each file, and then sum the list of sums. It is effectively the SHA-256 sum of all files. If the two match, the two trees are the same.
How well this works remains to be seen. Although the project will be designed and build in a Linux environment, the backups will be done with a Window computer. Thus the file names are limited to 255 characters and are not case sensitive. This should be alright as long as none of the project files do not have long names.