Creating encrypted backups of Laravel apps
Backup security is important, especially if you're processing sensitive data. Nobody except you should be able to read your application's backups and you should be confident that you don't loose any data in case of trouble.
You should always encrypt backups of your apps and securely transfer them to one or multiple backup destinations. If you encrypt the backups on your server and transfer only the encrypted version, your backups are stored encrypted at rest in your backup destination. Not even your backup storage provider is able to read them.
I recommend you to choose another storage provider for backups than the infrastructure provider of your production systems. If there are problems with your provider for whatever reason, you're still able to access your backups to recover as fast as possible.
Introducing spatie/laravel-backup
Spatie's laravel-backup package is the perfect starting point for implementing a backup strategy for your app. It creates a snapshot of your database and your app's files and puts them into a ZIP file, which is transferred to specified backup locations. The package is fully configurable, just customize its settings to your needs and make use of Laravel's scheduler to create backups regularly. You can read more about how to setup Spatie's package in the docs.
Encrypt your backups using AES-256
There is one thing the backup package is missing: Encryption. Since the package is firing various events where we can listen to, adding encryption is really easy. The event we're interested in is BackupZipWasCreated
. It is fired as soon as the ZIP file containing the database dumps and files has been created and before it is copied over to the backup destinations. As a result of this, it's the perfect place to perform last minute operations such as encryption on the backup file.
If you're dealing with sensitive files, you should use a secure cipher to encrypt your backup, such as AES-256. Luckily, PHP 7.2 has native support for encryption built into ZipArchive
.
Let's create a listener for the BackupZipWasCreated
event that encrypts the backup, called EncryptBackupZip
.
<?php
namespace App\Listeners;
use ZipArchive;
use Illuminate\Support\Collection;
use Spatie\Backup\Events\BackupZipWasCreated;
class EncryptBackupZip
{
public function handle(BackupZipWasCreated $event)
{
$zip = new ZipArchive;
$zip->open($event->pathToZip);
$zip->setPassword(config('app.backup.password'));
Collection::times($zip->numFiles, function ($i) use ($zip) {
$zip->setEncryptionIndex($i - 1, ZipArchive::EM_AES_256);
});
$zip->close();
}
}
As of Laravel 5.8.9, you can use Event Discovery, so you don't have to register the listener manually in the EventServiceProvider
. Just typehint the event the listener should listen for and Laravel wires everything together.
I have externalized the password for the backup ZIP files in an .env
variable, which is made available through config('app.backup.password')
. Your password is not used for encryption directly. It is passed to a key derivation function that generates a key of 32 bytes required for AES-256 encryption. Only take care you add enough entropy to the password.
As we have everything in place now, we can run php artisan backup:run
. To verify encryption is working properly, try to open a backup file, e.g. using The Unarchiver, and you will be prompted to enter the password before you get access.
Take care to note your backup password and keep it secure. If you loose your password, your backups can not be decrypted anymore and your data is lost forever!
I hope you had fun reading this post. Data protection isn't as much effort as it seems to be, but take it seriously and start small. Tell me what you think, I'm @skollro on Twitter.
Update (03/07/2019): "GDPR for Developers"
If you liked this post and you're interested in data protection, check out what I'm working on next! GDPR for Developers is a short eBook I'm writing. I'm putting together a guide containing actionable advice for developers for implementing more data protection in their apps. I'm sure you'll love it!