Bacula Setup for Roaming Clients

Note: This works for on-campus clients without fixed addresses -- ethernet DHCP or WiFi. It does not work well for remote clients. The bandwidth just isn't there over the VPN to back them up in a reasonable time.

In these examples the client being set up is "eltanin.math.ucsb.edu", so substitute accordingly. Note that this does not have to be a real DNS name, although it won't hurt anything if it is. This can be useful if a client is sometimes on a fixed address and sometimes not.

Director Setup

The director setup is normal, except that we need a restricted console entry for the client, so it can tell us its IP address.

Console {
  Name = eltanin.math.ucsb.edu-fd
  Password = "ClientConsolePassw0rd"
  CommandACL = run, restore, wait, setip, setbandwidth, time, .status, .jobs, .clients, .storages, .pools, .filesets, .defaults, .estimate
  jobacl = eltanin
  poolacl = *all*
  clientacl = eltanin.math.ucsb.edu-fd
  storageacl = *all*
  catalogacl = *all*
  filesetacl = *all*
}

The CommandACLs run, restore, wait; and the JobACL are optional -- they're only necessary if the client needs to be able to initiate its own jobs. This could be useful for intermittently connected clients where starting a job immediately on connection might be useful. setbandwidth is also optional, but useful if it's desirable for the client to be able to limit its own bandwidth usage.

Client Setup

The client needs a bconsole.conf that matches the restricted entry above. The setup for this is a bit peculiar -- a Director entry with a fake password, then a console entry.

Director {
  Name = self-help.math.ucsb.edu-dir
  DIRport = 9101
  address = self-help.math.ucsb.edu
  password = "XXXXXXXX" # Literally this, this is not obfuscated
}
Console {
  Name = eltanin.math.ucsb.edu-fd
  password = "ClientConsolePassw0rd"
}

Test this by running bconsole and making sure it connects.

The client needs a script to periodically tell the director its IP. Here's a sample, to be placed in /usr/local/bin/bacula-setip.sh:

#!/bin/sh
/opt/local/sbin/bconsole >/tmp/bacula-setip.log <<END_OF_DATA
time
setip
END_OF_DATA

Make sure this script is executable. Run it and check the output in /tmp to be sure.

The script could be run from cron, but on macOS it's cleaner to do it from a LaunchDaemon script, to be placed in /Library/LaunchDaemons/edu.ucsb.math.bacula-setup.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <!-- The label should be the same as the filename without the extension -->
    <string>edu.ucsb.math.bacula-setip</string>
    <!-- Specify how to run your program here -->
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/bacula-setip.sh</string>
    </array>
    <!-- Run every 15 minutes -->
    <key>StartInterval</key>
    <integer>900</integer><!-- seconds -->
</dict>
</plist>

Finally, load the daemon:

sudo launchctl load -w /Library/LaunchDaemons/edu.ucsb.math.bacula-setip.plist

Additional details

The server runs two scripts to help make sure roaming clients only back up when it's appropriate.

  • /usr/local/bin/bacula-check-local.sh: Runs on the server. If the job is an incremental, this script always succeeds. If the job is a full backup, it succeeds if the client has an on-campus IP and is not on the VPN, but fails otherwise. This stops large full backups from being attempted over the VPN.
  • /usr/bin/pmset -g batt | grep 'AC Power': Runs on the client (macOS only.) This fails and cancels the job if the client is on battery power.
    • On Linux laptop systems, use this in the client's job block to accomplish the same thing:
       
      # Don't back up if we're on battery                                                                        
        RunScript {
          RunsWhen = Before
          FailJobOnError = Yes
          RunsOnClient = Yes
          Command = "/usr/sbin/on_ac_power"
        }