Cryptography

Data Backups with Bacula: Backup Encryption

Dejan Lukan
September 2, 2014 by
Dejan Lukan

Introduction

Bacula supports file encryption on the file daemon, which sends encrypted data to the storage daemon for storage. Since the file daemon encrypts the data prior to sending it to the storage daemon, the storage daemon only sees the encrypted data. It's important to realize that file contents are encrypted, while the metadata is not – therefore the file names, permissions and ownership information are visible.

Setting up File Daemon Encryption

To encrypt/decrypt the information, each file daemon uses a private/public key pair, where the private key is used to decrypt the data, while the public key encrypts the data. The clients must not share the private key among themselves, because that would enable each client to decrypt the files of another client; therefore each client must have its own private/public key pair. Each client should be given the following keys:

Learn Applied Cryptography

Learn Applied Cryptography

Build your applied cryptography and cryptanalysis skills with 13 courses covering hashing, PKI, SSL/TLS, full disk encryption and more.
  • File Daemon Public Key: a unique public key used for data encryption.
  • File Daemon Private Key: a unique private key used for data decryption.
  • Master Key Public Key: the master key is used to decrypt the backup if file daemon keys are lost. Remember that only the public master key needs to be copied to the client, which is used for data encryption, but the private master key must be kept secret, because it is used to decrypt the files.

The master as well as file daemon key pairs can be generated normally with the openssl command. Openssl is a cryptographic library that can be used to create PKI keys, where public and private keys are created. First we have to create the RSA private key by using the command presented below. Note that we also want to specify one of the -des|-des3|-idea|-aes128|-aes256 parameters, because we want to encrypt the private key. If private key is encrypted, we need to specify a pass phrase prior to using it, which prevents Bacula from using the private key, since it doesn't have an option to provide its pass phrase on the fly. This is why we'll keep private keys encrypted when storing them on the remote machine, which enhances security, because the keys cannot be used directly, but an additional pass phrase is needed to use them. Remember that we need to copy the unencrypted version of private key (as well as public key) to the Bacula file daemon, since Bacula won't be able to use it otherwise.

The following command will create the RSA private key.

[plain]

# openssl genrsa -aes256 -out client.key 4096

Generating RSA private key, 4096 bit long modulus

..............................................++

...........................................................................................................................++

e is 65537 (0x10001)

Enter pass phrase for client.key:

Verifying - Enter pass phrase for client.key:

[/plain]

Once the private key is created, we have to generate the CSR (Certificate Signing Request), which is normally sent to a CA (Certificate Authority) to be verified. On the other hand, we can also self-sign a certificate with the command below, which will ask us to provide the password of the private key (the command won't ask us to provide the pass phrase of a private key if we didn't supply one of the parameters -des|-des3|-idea|-aes128|-aes256 when creating the key).

[plain]

# openssl req -new -key client.key -x509 -out client.cert -days 3650

[/plain]

Next, we have to decrypt the private key to be copied on the Bacula client machine. We can use the below command to use the encrypted private key client.key and store the unencrypted version to client-clear.key; obviously we need to provide a password when decrypting it.

[plain]

# openssl rsa -in client.key -out client-clear.key

Enter pass phrase for client.key:

writing RSA key

[/plain]

So far, we have created the encrypted version of private key client.key, the unencrypted version of private key client-clear.key and the certificate client.cert. We can bundle the private and certificate together into a PKI keypair (.pem file) by using the concatenation command below:

[plain]

# cat client-clear.key client.cert > client.pem

[/plain]

The client.pem public/private key pair contains the file daemon private/public key, which needs to be copied to the file daemon server. But we still need to create the master key private/public key, where the private key is kept secret and the public key is also copied to the file daemon server. Basically we have to follow the same steps to create the master key as we did previously for the file daemon key, except that we can leave the private key encrypted and we don't have to create the .pem bundle. The commands we need to run are as follows:

[plain]

# openssl genrsa -aes256 -out master.key 4096

# openssl req -new -key master.key -x509 -out master.cert -days 3650

[/plain]

The client.pem private/public key pair as well as master.cert public key need to be copied to the file daemon. Remember to only keep the decrypted version of private key on the file daemon's machine and delete them anywhere else. We should only keep the encrypted version of private keys in a backup.

[plain]

# scp client.pem mysqlclient:/etc/bacula/

# scp master.cert mysqlclient:/etc/bacula/

[/plain]

We should also change the owner and permissions of the uploaded keys to restrict access to them. The read+write permission is given to the root user, the Bacula user only has read permission, while the rest of the users don't have any permission to view or change the keys.

[plain]

# cd /etc/bacula/

# chown root:bacula master.cert client.pem

# chmod 640 master.cert client.pem

[/plain]

To encrypt the files with newly created public keys, we have to change the bacula-fd.conf on the client file daemon. The PKI configuration lines need to be added to the FileDaemon configuration like presented below. The "PKI Signatures" enabled the data signing, the "PKI Encryption" enables the data encryption, the "PKI Keypair" points to the file daemon's public/private key pair, while the "PKI Master Key" points to the master public key.

[plain]

FileDaemon {

Name = mysqlclient-fd

WorkingDirectory = /var/lib/bacula

Pid Directory = /var/run/bacula

Maximum Concurrent Jobs = 20

FDAddress = 0.0.0.0

FDport = 9102

PKI Signatures = Yes

PKI Encryption = Yes

PKI Keypair = "/etc/bacula/client.pem"

PKI Master Key = "/etc/bacula/master.cert"

}

[/plain]

Changing the configuration file requires the restart of a file daemon, but from that moment on, all the files sent to storage daemon will be encrypted. Next, we'll create two files: the encrypted as well as unencrypted backup of the same file and compare the backup file version to see whether encryption has been used and how secure the data really is. First, let's create a file we'll be backing up: we can use a simple echo command to save a string "AAAABBBBCCCCDDDD" into a file abcd.txt; we used simple letters in order to easily grep them in a hex dump.

[plain]

# echo "AAAABBBBCCCCDDDD" > /abcd.txt

[/plain]

Unencrypted Backup

The first step in creating an unencrypted backup version without affecting the rest of the backup process is creating a separate Pool definition, since only a pool can be referenced by a Bacula job, not the volume. In order to do that, we can edit the bacula-dir.conf configuration file on Bacula server and add the definitions presented below. The Pool declaration defines the file-unenc label format, which will be used when backing up the MysqlUnenc job (the job storing the unencrypted version of the file). The FileSet definition defines that we want to backup only the /abcd.txt file, which will work fine for our testing.

[plain]

Pool {

Name = FileUnenc

Pool Type = Backup

Label Format = file-unenc

}

Job {

Name = "MysqlUnenc"

Type = Backup

Level = Incremental

Storage = File

Messages = Standard

Client = mysqlclient-fd

Pool = FileUnenc

FileSet = "FilesTest"

}

FileSet {

Name = "FilesTest"

Include {

File = "/abcd.txt"

}

}

[/plain]

Next we need to run the jobs simply by using the run command in bconsole. Note that at this time, the file daemon on Bacula client must have the PKI instructions disabled, since we don't want to encrypt the files. Below we've run the command "run job=MysqlUnenc yes" to specify all the parameters in the same line to avoid configuration dialogs and run the job all at once.

[plain]

*run job=MysqlUnenc yes

[/plain]

After the job has been processed and the file has been backed up, the following will be printed to screen as part of a successful job run. The process backed up 1 file that was saved to the volume file-unenc0005 with encryption disabled.

[plain]

FD Files Written: 1

SD Files Written: 1

FD Bytes Written: 17 (17 B)

SD Bytes Written: 87 (87 B)

Rate: 0.0 KB/s

Software Compression: None

VSS: no

Encryption: no

Accurate: no

Volume name(s): file-unenc0005

[/plain]

If we look at contents of the newly created file file-unenc0005 by using a hex editor like xxd, we can observe the string "AAAABBBBCCCCDDDD", which is clearly visible. That verifies that the contents of the file are unencrypted and can be read without much difficulty.

Encrypted Backup

Next, let's setup the encryption in Bacula in order to encrypt the files to protect them against prying eyes. First we have to enable the PKI lines in bacula-fd.conf and restart file daemon. We also need to add additional entries to the bacula-dir.conf on the Bacula server to reference another pool that uses the file-enc label format.

[plain]

Pool {

Name = FileEnc

Pool Type = Backup

Label Format = file-enc

}

Job {

Name = "MysqlEnc"

Type = Backup

Level = Incremental

Storage = File

Messages = Standard

Client = mysqlclient-fd

Pool = FileEnc

FileSet = "FilesTest"

}

FileSet {

Name = "FilesTest"

Include {

File = "/abcd.txt"

}

}

[/plain]

Upon starting the MysqlEnc job, the following will be presented in a successful job run. The process backed up 1 file that was saved to the volume file-enc0006 with encryption enabled.

[plain]

FD Files Written: 1

SD Files Written: 1

FD Bytes Written: 1,184 (1.184 KB)

SD Bytes Written: 1,832 (1.832 KB)

Rate: 0.0 KB/s

Software Compression: None

VSS: no

Encryption: yes

Accurate: no

Volume name(s): file-enc0006

[/plain]

If we display the contents of the file with the xxd command, we can verify that contents are indeed encrypted, since no "AAAABBBBCCCCDDDD" string can be found in the output. Also notice that the file contents are considerably larger than before, which is because encryption was used. If you closely look at the file contents, you can see that /abcd.txt filename is still visible in the output, which states that metadata is not encrypted, but only the data is.

Conclusion

In this article we've presented a process of creating the PKI private/public key pairs to use in data encryption with Bacula. Encrypting the data backups directly on the Bacula file daemon prior to sending it to the Bacula storage daemon ensures that data is encrypted at all times and only the Bacula file daemon is able to decrypt it.

We've created a simple file by storing a string "AAAABBBBCCCCDDDD" into the file and backed it up by using normal backup as well as encrypted backup. The contents of the file were encrypted when the encryption was used, while the metadata is still visible in order for encryption process to function properly.

I advice you to use data encryption whenever possible. It takes a little more time to setup, but once you've figured it out, it's easy to use and configure, but the data is significantly more secure than it would be otherwise.

References

[1] Solid-state drive, https://en.wikipedia.org/wiki/Solid-state_drive.

[2] Tape drive https://en.wikipedia.org/wiki/Tape_drive.

[3] List of backup software https://en.wikipedia.org/wiki/List_of_backup_software.

[4] Bacula-Web, http://www.bacula-web.org/.

[5] The Bootstrap File, http://www.bacula.org/5.2.x-manuals/en/main/main/Bootstrap_File.html.

[6] ESXi 5.1: Using Raw Device Mappings (RDM) on an HP Microserver,
http://forza-it.co.uk/esxi-5-1-using-raw-device-mappings-rdm-on-an-hp-microserver/.

[7] Bacula Installation and Configuration Guide, https://access.redhat.com/site/sites/default/files/attachments/install_1.pdf.

[8] Overview on modifying the Synology Server, bootstrap, ipkg etc, http://forum.synology.com/wiki/index.php/Overview_on_modifying_the_Synology_Server,_bootstrap,_ipkg_etc.

[9] Data Encryption, http://www.bacula.org/5.2.x-manuals/en/main/main/Data_Encryption.html.

Learn Applied Cryptography

Learn Applied Cryptography

Build your applied cryptography and cryptanalysis skills with 13 courses covering hashing, PKI, SSL/TLS, full disk encryption and more.

[10] Messages Resource, http://www.bacula.org/5.2.x-manuals/en/main/main/Messages_Resource.html.

Dejan Lukan
Dejan Lukan

Dejan Lukan is a security researcher for InfoSec Institute and penetration tester from Slovenia. He is very interested in finding new bugs in real world software products with source code analysis, fuzzing and reverse engineering. He also has a great passion for developing his own simple scripts for security related problems and learning about new hacking techniques. He knows a great deal about programming languages, as he can write in couple of dozen of them. His passion is also Antivirus bypassing techniques, malware research and operating systems, mainly Linux, Windows and BSD. He also has his own blog available here: http://www.proteansec.com/.