Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
HOWTO Encrypted Backup System Using Bacula and GnuPG
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks
View previous topic :: View next topic  
Author Message
odessit
Apprentice
Apprentice


Joined: 01 Feb 2004
Posts: 180
Location: Current Residency - Server Room - Caution - Frostbite Imminent!

PostPosted: Mon Aug 28, 2006 7:36 pm    Post subject: HOWTO Encrypted Backup System Using Bacula and GnuPG Reply with quote

HOWTO Encrypted Backup System Using Bacula and GnuPG
http://gentoo-wiki.com/HOWTO_Encrypted_Backup_System_Using_Bacula_and_GnuPG

Why do it this way?
Bacula is great backup software, but does not have data encryption just yet (in beta). This particular setup uses two proven software packages to overcome the lack of encryption capability.

Intended Audience
[*]Network Administrators who need to have their backups secured via encryption
[*]Existing users of Bacula who need to have backup volumes encrypted

Why use this setup
[*]Works now and has been tested
[*]Frees up clients' resources by moving encryption process to the server
[*]Uses established and tested mechanisms to secure data
[*]Writes encrypted data to a single file.
[*]Does not leave unencrypted information on the Bacula server

Why NOT use this setup
* Extra overhead on the server to complete backup and restore
* Does not use Bacula's native tape-writing mechanisms to store data
** Use any other tape writing utility
** Transfer file over the network

General Overview of the data flow
The Director will do FULL backup every day for the ease of restoration. Each day it will create a new backup volume.

During the backup process Bacula server (called the Director) requests the files from the client (called File-Daemon or FD for short). During the request Director passes arguments to the FD - Director authentication password, files & folder list, request for compression and MD5/SHA1 sum. The received files being written to the hard drive volume (one large file) and cataloged to the database.

Once the Director is done with all clients, the director calls a script, which will encrypt the backup volume with GnuPG and delete the unencrypted volume. After the encryption is completed, the file will be transferred via FTP or CIFS/SMB for offsite storage. (Optionally it can be written to a tape with a 3rd party utility)

Hardware Configuration
Any sufficiently fast server will do. The requirements vary greatly between different environments. To give you a starting point, here is one example
Dell PowerEdge 2800
[*]Single Xeon 2.8 GHz
[*]1 Gig RAM
[*]36 Gig RAID1 array for the /
[*]169 Gig RAID5 array for the /backups
[*]10/100 switched LAN

This setup backs up and encrypts data for about 50 clients, in my organization it equates to about 40 Gig compressed & encrypted data.

GnuPG Installation
Code:
emerge gnupg


Public / Private Key creation
For a good overview on what GnuPG is all about, please visit our own [http://www.gentoo.org/doc/en/gnupg-user.xml Gentoo GnuPG Guide]
You may or may not follow the suggested values for the key in the guide, but this is a safe setup for a backup system
[*]DSA and ElGamal key pair
[*]Key Size - 4096
[*]Public Key Expiration - 5 years (you will still be able to decrypt after 5 years)
[*]Private Key password or passphrase as complex as you can stand


Please note - you do not need and should NOT store the private key on the backup server. It is a security risk.
The best way is to generate the priv/pub key pairs on a secured workstation. Export the public key only as a text file and import public key only into the backup server. (see [http://www.gentoo.org/doc/en/gnupg-user.xml Gentoo GnuPG Guide] guide on how to do export/import)

Store the following items in a safe place
[*]CD or Flash Drive with Public key, Private key, Passphrase and Revocation Certificate
[*]Paper Printouts with Public key, Private key, Passphrase and Revocation Certificate

If you loose your private key or passphrase - bye-bye data.

Bacula Server Installation
The latest version of Bacula in the portage is outdated (bacula-1.36.3-r3) where the latest version as of writing is 1.38.11. Below is example on how to install Bacula from source.

:1. Download latest bacula source from http://sourceforge.net/projects/bacula
:2. Extract the bacula source
Code:
tar -xvzf bacula-x.xx.xx.tar.gz

:3. Enter the source folder
Code:
cd bacula-x.xx.xx

:4. Run the configure command
Code:
./configure \
 --prefix=/usr \
 --sbindir=/usr/sbin \
 --sysconfdir=/etc/bacula \
 --with-scriptdir=/etc/bacula \
 --enable-smartalloc \
 --with-mysql \
 --with-working-dir=/var/bacula \
 --with-pid-dir=/var/run \
 --with-subsys-dir=/var/lock/subsys \
 --enable-conio \
 --with-openssl \
 --enable-largefile \
 --enable-wx-console \
 --with-python

:5. Compile and Install
Code:
 make
 make install

:6. Setup Database (assuming you have MySQL installed and working)
Code:
 /etc/bacula/create_mysql_database
 /etc/bacula/make_mysql_tables
 /etc/bacula/grant_mysql_privileges

:7 Add bacula to the /etc/conf.d/local.start
Code:
echo /etc/bacula/bacula start >> /etc/conf.d/local.start

:8 add bacula to the /etc/conf.d/local.stop
Code:
echo /etc/bacula/bacula stop >> /etc/conf.d/local.stop


Server (Director) Configuration (bacula-dir.conf)
This is the most confusing part of the whole process. In the following example, just substitute $VARIABLE with your own value.

Code:

#bacula/bacula-dir.conf|<pre>
###################   DEFINE DIRECTOR   #############################
Director                     
{                                     
 Name = backup-dir                               #or whatever name you want
 Description = "Bacula Director - $MY_LOCATION"  # "Bacula Director - Main Office"
 DIRport = 9101                       
 QueryFile = "/etc/bacula/query.sql"
 WorkingDirectory = "/var/bacula"
 PidDirectory = "/var/run"
 Maximum Concurrent Jobs = 2
 FDConnectTimeout = 1min
 SDConnectTimeout = 1min
 Password = "$CONSOLE_PASSWORD"                  # "gsdfgfdsg44"
 Messages = Daemon
}

###################   DEFINE CLIENTS   ##############################

Client {
  Name = $SOME_IMPORTANT_CLIENT-fd              # accountant-fd
  Address = $FQDN_OR_IP                         # accountant.mydomain.local
  FDPort = 9102
  Catalog = GiantCatalog
  Password = "$CLIENT_ACCESS_PASSWORD"          # "strong_password"
  File Retention = 6 days
  Job Retention = 6 days
  AutoPrune = yes
  Maximum Concurrent Jobs = 2
}

Client {
  Name = $LAST_CLIENT-fd                       # mainserver-fd
  Address = $FQDN_OR_IP                        # mainserver.mydomain.local
  FDPort = 9102
  Catalog = GiantCatalog
  Password = "$LAST_CLIENT_ACCESS_PASSWORD"    # "strong_password2"
  File Retention = 6 days
  Job Retention = 6 days
  AutoPrune = yes
  Maximum Concurrent Jobs = 2
}

Client {
  Name = $BACKUP_SERVER-fd                       # the bacula server itself backup-fd
  Address = $FQDN_OR_IP                              # backup.mydomain.lan
  FDPort = 9102
  Catalog = GiantCatalog
  Password = "$BACKUP_SERVER_ACCESS_PASSWORD"    # "strong_password2"
  File Retention = 6 days
  Job Retention = 6 days
  AutoPrune = yes
  Maximum Concurrent Jobs = 2
}

############### DEFINE DEFAULT JOB PARAMETERS #####################

JobDefs                     
 {                               
 Name = "DefaultBackupJob"
 Type = Backup
 Level = Full
 Client = backup-fd
 Schedule = "WeeklyCycle"
 Storage = File
 Pool = Default
 Messages = Standard
 Priority = 10
 Max Start Delay = 18h
}

#######################  DEFINE JOBS  ############################

Job
{
 Name = "$SOME_IMPORTANT_CLIENT_JOB"             # "Accountant Backup Job"
 Client = $SOME_IMPORTANT_CLIENT-fd              # accountant-fd
 JobDefs = "DefaultBackupJob"
 FileSet = "Generic User Fileset"                #it can be reused for many clients
 Write Bootstrap = "/backups/bootstraps/$SOME_IMPORTANT_CLIENT.bsr"
 Maximum Concurrent Jobs = 2
}

#Backup the catalog database (after the nightly save)
Job {
  Name = "BackupCatalog"
  JobDefs = "DefaultBackupJob"
  Client = BACKUP_SERVER-fd
  FileSet="Catalog"
  # This creates an ASCII copy of the catalog
  RunBeforeJob = "/etc/bacula/make_catalog_backup bacula bacula"
  # This deletes the copy of the catalog
  RunAfterJob = "/etc/bacula/delete_catalog_backup"
  Write Bootstrap = "/backups/bootstraps/BackupCatalog.bsr"
  Priority = 10
}

Job
{
 Name = "$LAST_CLIENT_JOB"                      # "Mainserver Backup Job"
 Client = $LAST_CLIENT-fd                       # mainserver-fd
 JobDefs = "DefaultBackupJob"
 FileSet = "Server Fileset"                     #we can define a separate FileSet
 Write Bootstrap = "/backups/bootstraps/$LAST_CLIENT.bsr"
 Maximum Concurrent Jobs = 2
 RunAfterJob = "/backups/encrypted/scripts/EncryptVolume.sh"
## NOTE - we will run the script EncryptVolume.sh after this job completes.   ##
## It will encrypt volume, delete unencrypted volume and transfer it via FTP ##
}

################## Define which files to backup #####################

FileSet
{
  Name = "Generic User Fileset"
  Enable VSS = yes
  Include
  {
        Options
    {
        signature = MD5         #Create MD5 Signature
        compression=GZIP5       #Compress Incoming Data on the client
        Exclude = yes
        IgnoreCase = yes
        # Exclude Mozilla-based programs' file caches
        WildDir = "[A-Z]:/Documents and Settings/*/Application Data/*/Profiles/*/*/Cache"
        WildDir = "[A-Z]:/Documents and Settings/*/Application Data/*/Profiles/*/*/Cache.Trash"

        # Exclude directories full of lots and lots of useless little files
        WildDir = "[A-Z]:/Documents and Settings/*/Cookies"
        WildDir = "[A-Z]:/Documents and Settings/*/Recent"
        WildDir = "[A-Z]:/Documents and Settings/*/Local Settings/History"
        WildDir = "[A-Z]:/Documents and Settings/*/Local Settings/Temp"
        WildDir = "[A-Z]:/Documents and Settings/*/Local Settings/Temporary Internet Files"

        # These are always open and unable to be backed up
        WildFile = "[A-Z]:/Documents and Settings/All Users/Application Data/Microsoft/Network/Downloader/qmgr[01].dat"

        # Temporary directories & files
        WildDir = "[A-Z]:/WINNT/Temp"
        WildDir = "[A-Z]:/temp"
        WildFile = "*.tmp"

        # Recycle bins
        WildDir = "[A-Z]:/RECYCLER"

        # Swap files
        WildFile = "[A-Z]:/pagefile.sys"
   }

    File = "c:/Documents and Settings"          #Define Folders to back up
    File = "d:/SomePath/To Folder/Or/File.txt" 
  }

  Exclude
  {
    File = "c:/test"                            #Define Folders to exclude
  }
}

FileSet
{
  Name = "Server Fileset"
  Enable VSS = yes
  Include
  {
        Options
    {
        signature = MD5         #Create MD5 Signature
        compression=GZIP5       #Compress Incoming Data on the client
        Exclude = yes
        IgnoreCase = yes
        # Swap files
        WildFile = "[A-Z]:/pagefile.sys"
   }
    File = "d:/"          #Back Everything for this SPECIAL_USER
  }

  Exclude
  {
    File = "c:/test"                         #Define Folders to exclude
  }
}

###################   DEFINE SCHEDULE   ################################

Schedule {
  Name = "WeeklyCycle"
  Run = Level=Full Pool=MondayPool Monday at 12:05       #PM That is
  Run = Level=Full Pool=TuesdayPool Tuesday at 02:12     #AM that is
  Run = Level=Full Pool=WednesdayPool Wednesday at 12:05
  Run = Level=Full Pool=ThursdayPool Thursday at 12:05
  Run = Level=Full Pool=FridayPool Friday at 12:05
  Run = Level=Full Pool=SaturdayPool Saturday at 16:00
  Run = Level=Full Pool=SundayPool Sunday at 16:00
}

################# DEFINE STORAGE (file, tape, CDR..) ###################

Storage {
  Name = File                   
  Address = FQDN_OR_IP_OF_DIRECTOR         
  SDPort = 9103
  Password = "$STORAGEPASS"
  Device = FileStorage
  Media Type = File
}

############################ DEFINE CATALOG #############################

Catalog {
  Name = GiantCatalog
  dbname = bacula; user = bacula; password = ""
}

########################## DEFINE MESSAGES #############################

Messages {
  Name = Standard
  console = all, !skipped, !saved
  append = "/var/bacula/log" = all, !skipped
}

Messages {
  Name = Daemon
  console = all, !skipped, !saved
  append = "/var/bacula/log" = all, !skipped
}

#######################   DEFINE POOLS   ################################
Pool {
  Name = MondayPool
  Pool Type = Backup
  AutoPrune = yes               # Prune expired volumes
  Volume Retention = 6 days
  Accept Any Volume = yes       # write on any volume in the pool
  Volume Use Duration = 6 days
  Recycle = yes
  RecycleOldestVolume = yes
  LabelFormat = "BackupMondayVolume"
}

Pool {
  Recycle = yes                 
  Name = TuesdayPool
  Pool Type = Backup
  AutoPrune = yes                   
  Volume Retention = 6 days
  Accept Any Volume = yes             
  Volume Use Duration = 6 days
  Recycle = yes
  RecycleOldestVolume = yes
  LabelFormat= "BackupTuesdayVolume"
}

Pool {
  Recycle = yes               
  Name = WednesdayPool
  Pool Type = Backup
  AutoPrune = yes                     
  Volume Retention = 6 days
  Accept Any Volume = yes             
  Volume Use Duration = 6 days
  Recycle = yes
  RecycleOldestVolume = yes
  LabelFormat="BackupWednesdayVolume"
}

Pool {
  Recycle = yes                 
  Name = ThursdayPool
  Pool Type = Backup
  AutoPrune = yes                     
  Volume Retention = 6 days
  Accept Any Volume = yes             
  Volume Use Duration = 6 days
  Recycle = yes
  RecycleOldestVolume = yes
  LabelFormat="BackupThursdayVolume"
}

Pool {
  Recycle = yes                 
  Name = FridayPool
  Pool Type = Backup
  AutoPrune = yes                   
  Volume Retention = 6 days
  Accept Any Volume = yes           
  Volume Use Duration = 6 days
  Recycle = yes
  RecycleOldestVolume = yes
  LabelFormat="BackupFridayVolume"
}

Pool {
  Recycle = yes                 
  Name = SaturdayPool
  Pool Type = Backup
  AutoPrune = yes                   
  Volume Retention = 6 days
  Accept Any Volume = yes           
  Volume Use Duration = 6 days
  Recycle = yes
  RecycleOldestVolume = yes
  LabelFormat="BackupSaturdayVolume"
}

Pool {
  Recycle = yes               
  Name = SundayPool
  Pool Type = Backup
  AutoPrune = yes                 
  Volume Retention = 6 days
  Accept Any Volume = yes           
  Volume Use Duration = 6 days
  Recycle = yes
  RecycleOldestVolume = yes
  LabelFormat="BackupSundayVolume"
}

# Default pool definition
Pool {
  Name = Default
  Pool Type = Backup
}

# Restricted console used by tray-monitor to get the status of the director
Console {
  Name = backup-mon
  Password = "$RESTRICTED_CONSOLE_PASSWORD"
  CommandACL = status, .status
}


Define Storage Daemon (SD)
Code:

#/etc/bacula/bacula-sd.conf|
Storage {                             
  Name = backup-sd
  SDPort = 9103                 
  WorkingDirectory = "/var/bacula"
  Pid Directory = "/var/run"
  Maximum Concurrent Jobs = 20
}

# List Directors who are permitted to contact Storage daemon
Director {
  Name = backup-dir
  Password = "$STORAGEPASS"
}

#
# Restricted Director, used by tray-monitor to get the
#   status of the storage daemon
#
Director {
  Name = backup-mon
  Password = "$RESTRICTED_DIR_PASS"
  Monitor = yes
}

Device {
  Name = FileStorage
  Media Type = File
  Archive Device = /backups
  LabelMedia = yes;                   # lets Bacula label unlabeled media
  Random Access = Yes;
  AutomaticMount = yes;               # when device opened, read it
  RemovableMedia = no;
  AlwaysOpen = no;
}

Messages {
  Name = Standard
  director = backup-dir = all
}



Define Console
Code:

#/etc/bacula/bacula-sd.conf|
Director {
  Name = backup-dir            #mainofficebackup-dir
  DIRport = 9101
  address = $FQDN_OR_IP
  Password = "$DIRECTOR_CONSOLE_PASSWORD"
}


Create the backup script
This is the script that will encrypt the backup volume and upload it to a different server
This script is to be executed via Bacula's RunAfterJob or Cron. It will encrypt a backup volume with GnuPG using Twofish algorithm. If encryption is to be changed use only encryption with 128-bit BLOCK size. Currently only Twofish, AES, MARS and Serpent have 128bit block.

Ciphers with 64-bit block (3DES, CAST5, BLOWFISH...) are not suitable for encrypting large files. Couple Gig volume is Ok, but as you will approach 64 Gigs, you will increase the risk of leaking decryption information (see http://en.wikipedia.org/wiki/Birthday_attack).

Code:

#/backups/encrypted/scripts/EncryptVolume.sh|
# Remove Yesterday’s encrypted backup from HDD
cd /backups/encrypted/
rm -f *.gpg

# encrypt the file with GPG using Public Key.
# use only --cipher-algo aes|aes192|aes256|twofish
gpg --encrypt --batch -r backup@giantmarkets.com  --cipher-algo twofish \
--bzip2-compress-level 6 --output /backups/encrypted/BakupVolume.gpg /backups/Backup*

# Remove unencrypted backup volume, we encrypted and saved
# encrypted copy in the above step.
cd /backups/
rm Backup*

# transfer encrypted volume via ftp to the server with tape
cd /backups/encrypted/

ftp -ni $FQDN_OR_IP <<SCRIPT
user Anonymous backup_job@backup
cd $SOME_FOLDER
binary
mdelete *.gpg
mput *.gpg
quit


Please note. If the script works manually, but fails to encrypt automatically (trust errors), copy the .gnupg folder in the home directory for the working user (root for example) into the root directory
cp -r /root/.gnupg/ /

Win32 Client Installation and Configuration
Download and install the winbacula.x.x.x.exe
Edit the bacula-fd.conf to let your director to connect to the client
Code:

#c:\bacula\bin\bacula-fd.conf
Director {
  Name = backup-dir         #Director's name as defined on the server
  Password = "$CLIENT_ACCESS_PASSWORD"   #same as in client definition on server
}

FileDaemon {                         
  Name = $SOME_IMPORTANT_CLIENT-fd   
  FDport = 9102                     
  WorkingDirectory = /bacula/working
  Pid Directory = /bacula/working
}

# Send all messages except skipped files back to Director
Messages {
  Name = Standard
  director = backup-dir = all, !skipped
}

(re)Start the Bacula service and you are ready.

*NIX Client Installation and Configuration
:1. Download latest bacula source from http://sourceforge.net/projects/bacula
:2. Extract the bacula source
Code:
tar -xvzf bacula-x.xx.xx.tar.gz

:3. Enter the source folder
Code:
cd bacula-x.xx.xx

:4. Run the configure command
Code:
./configure \
 --prefix=/usr \
 --sbindir=/usr/sbin \
 --sysconfdir=/etc/bacula \
 --with-scriptdir=/etc/bacula \
 --enable-smartalloc \
 --with-mysql \
 --with-working-dir=/var/bacula \
 --with-pid-dir=/var/run \
 --with-subsys-dir=/var/lock/subsys \
 --enable-conio \
 --with-openssl \
 --enable-largefile \
 --enable-wx-console \
 --with-python \
 –-enable-client-only

:5. Compile and Install
Code:
 make
 make install

:6. Add bacula to the /etc/conf.d/local.start
Code:
echo /etc/bacula/bacula start >> /etc/conf.d/local.start

:7. add bacula to the /etc/conf.d/local.stop
Code:
echo /etc/bacula/bacula stop >> /etc/conf.d/local.stop

:8. Edit the bacula-fd.conf
Code:

#\etc\bacula\bacula-fd.conf
<pre>
Director {
  Name = backup-dir                 #Director's name as defined on the server
  Password = "$LAST_CLIENT_ACCESS_PASSWORD"   #same as in client definition on server
}

FileDaemon {                         
  Name = $LAST_CLIENT-fd   
  FDport = 9102                     
  WorkingDirectory = /bacula/working
  Pid Directory = /bacula/working
}

# Send all messages except skipped files back to Director
Messages {
  Name = Standard
  director = backup-dir = all, !skipped
}

(re)Start the Bacula service and you are ready.

Restoration Process

1. Decrypt the file
Code:
gpg BackupVolume.gpg

(Assuming that gpg has your private key)

2. Move the decrypted file to the bacula server (/backups directory in this example)

3a. If Bacula database is intact - Just follow the restoration procedures in the Bacula handbook
http://www.bacula.org/dev-manual/Bacula_Consol_Restor_Comman.html

OR

3b If Bacula database is not intact - Use the bscan utility to recreate the database from your volume.
Code:
cd /etc/bacula/
bscan -V RestoreVolume -v -s -m -c bacula-sd.conf FileStorage

and then follow the restoration procedures in the Bacula handbook
http://www.bacula.org/dev-manual/Bacula_Consol_Restor_Comman.html


Last edited by odessit on Mon Sep 11, 2006 2:36 pm; edited 3 times in total
Back to top
View user's profile Send private message
odessit
Apprentice
Apprentice


Joined: 01 Feb 2004
Posts: 180
Location: Current Residency - Server Room - Caution - Frostbite Imminent!

PostPosted: Mon Aug 28, 2006 7:39 pm    Post subject: Reply with quote

I created this howto based on internal documents that I wrote for my place of employment. It has been sanitized from any proprietary information.
Maybe you can improve on this, so please give suggestions.
Thanks!
Back to top
View user's profile Send private message
jhmartin
Tux's lil' helper
Tux's lil' helper


Joined: 03 Sep 2003
Posts: 95

PostPosted: Thu Aug 31, 2006 4:53 pm    Post subject: Backup the catalog Reply with quote

You may also want to back up the mysql database after executing a series of backups, as losing this database makes it significantly harder to restore from a backup. A hot backup of MySQL is not reliable at all. Instead, have a job that exports the DB then backs up the export file.
Back to top
View user's profile Send private message
odessit
Apprentice
Apprentice


Joined: 01 Feb 2004
Posts: 180
Location: Current Residency - Server Room - Caution - Frostbite Imminent!

PostPosted: Thu Aug 31, 2006 7:52 pm    Post subject: Reply with quote

I actually removed the code to save space (IIRC it is included by default with bacula install), but will add it in a bit incase the config file differs b/n different installs.
Edit - done
Edit - Regarding difficulty to restore w/out database.
Actually it is fairly easy by using bscan utility.
Just decrypt the volume, move it to the bacula server and run
Code:
cd /etc/bacula/
bscan -V /path/to/RestoreVolume -v -s -m -c bacula-sd.conf FileStorage

If complaints about name, rename RestoreVolume to whatever name is displayed and change the above bscan command to accommodate the new name. The whole process takes ~20 minutes on 2.8 Gig Xeon working on ~ 30 Gig file (HD speed is more important here btw.)
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum