source: box/trunk/bin/bbackupd/bbackupd-config.in @ 2870

Revision 2870, 16.2 KB checked in by chris, 14 months ago (diff)

Fix errors reported by default Unix notify script on backup-ok events,
thanks to Steve Haeck for the bug report.

  • Property svn:eol-style set to native
Line 
1#!@PERL@
2use strict;
3
4# should be running as root
5if($> != 0)
6{
7        printf "\nWARNING: this should be run as root\n\n"
8}
9
10sub error_print_usage
11{
12        print <<__E;
13
14Setup bbackupd config utility.
15
16Bad command line parameters.
17Usage:
18    bbackupd-config config-dir backup-mode account-num server-hostname
19        working-dir [backup directories]
20
21Parameters:
22    config-dir          is usually @sysconfdir_expanded@/boxbackup
23    backup-mode         is lazy or snapshot:
24        lazy mode       runs continously, uploading files over a specified age
25        snapshot mode   uploads a snapshot of the filesystem when instructed
26                        explicitly, using bbackupctl sync
27    account-num (hexdecimal) and server-hostname
28                        are supplied by the server administrator
29    working-dir         is usually @localstatedir_expanded@/bbackupd
30    backup directories  is list of directories to back up
31
32__E
33        print "=========\nERROR:\n",$_[0],"\n\n" if $_[0] ne '';
34        exit(1);
35}
36
37# check and get command line parameters
38if($#ARGV < 4)
39{
40        error_print_usage();
41}
42
43# check for OPENSSL_CONF environment var being set
44if(exists $ENV{'OPENSSL_CONF'})
45{
46        print <<__E;
47
48---------------------------------------
49
50WARNING:
51    You have the OPENSSL_CONF environment variable set.
52    Use of non-standard openssl configs may cause problems.
53
54---------------------------------------
55
56__E
57}
58
59# default locations
60my $default_config_location = '@sysconfdir_expanded@/boxbackup/bbackupd.conf';
61
62# command line parameters
63my ($config_dir,$backup_mode,$account_num,$server,$working_dir,@tobackup) = @ARGV;
64
65# check backup mode is valid
66if($backup_mode ne 'lazy' && $backup_mode ne 'snapshot')
67{
68        error_print_usage("ERROR: backup mode must be 'lazy' or 'snapshot'");
69}
70
71# check server exists
72{
73        my @r = gethostbyname($server);
74        if($#r < 0)
75        {
76                error_print_usage("Backup server specified as '$server', but it could not found.\n(A test DNS lookup failed -- check arguments)");
77        }
78}
79
80if($working_dir !~ m~\A/~)
81{
82        error_print_usage("Working directory $working_dir is not specified as an absolute path");
83}
84
85# ssl stuff
86my $private_key = "$config_dir/bbackupd/$account_num-key.pem";
87my $certificate_request = "$config_dir/bbackupd/$account_num-csr.pem";
88my $certificate = "$config_dir/bbackupd/$account_num-cert.pem";
89my $ca_root_cert = "$config_dir/bbackupd/serverCA.pem";
90
91# encryption keys
92my $enc_key_file = "$config_dir/bbackupd/$account_num-FileEncKeys.raw";
93
94# other files
95my $config_file = "$config_dir/bbackupd.conf";
96my $notify_script = "$config_dir/bbackupd/NotifySysadmin.sh";
97
98# check that the directories are allowable
99for(@tobackup)
100{
101        if($_ eq '/')
102        {
103                die "It is not recommended that you backup the root directory of your disc";
104        }
105        if($_ !~ m/\A\//)
106        {
107                die "Directory $_ is not specified as an absolute path";
108        }
109        if(!-d $_)
110        {
111                die "$_ is not a directory";
112        }
113}
114
115# summarise configuration
116
117print <<__E;
118
119Setup bbackupd config utility.
120
121Configuration:
122   Writing configuration file: $config_file
123   Account: $account_num
124   Server hostname: $server
125   Directories to back up:
126__E
127print '      ',$_,"\n" for(@tobackup);
128print <<__E;
129
130Note: If other file systems are mounted inside these directories, then
131they will NOT be backed up. You will have to create separate locations for
132any mounted filesystems inside your backup locations.
133
134__E
135
136# create directories
137if(!-d $config_dir)
138{
139        printf "Creating $config_dir...\n";
140        mkdir $config_dir,0755 or die "Can't create $config_dir";
141}
142
143if(!-d "$config_dir/bbackupd")
144{
145        printf "Creating $config_dir/bbackupd\n";
146        mkdir "$config_dir/bbackupd",0700 or die "Can't create $config_dir/bbackupd";
147}
148
149if(!-d "$working_dir")
150{
151        printf "Creating $working_dir\n";
152        if(!mkdir($working_dir,0700))
153        {
154                die "Couldn't create $working_dir -- create this manually and try again\n";
155        }
156}
157
158# generate the private key for the server
159if(!-f $private_key)
160{
161        print "Generating private key...\n";
162        if(system("openssl genrsa -out $private_key 2048") != 0)
163        {
164                die "Couldn't generate private key."
165        }
166}
167
168# generate a certificate request
169if(!-f $certificate_request)
170{
171        die "Couldn't run openssl for CSR generation" unless
172                open(CSR,"|openssl req -new -key $private_key -sha1 -out $certificate_request");
173        print CSR <<__E;
174.
175.
176.
177.
178.
179BACKUP-$account_num
180.
181.
182.
183
184__E
185        close CSR;
186        print "\n\n";
187        die "Certificate request wasn't created.\n" unless -f $certificate_request
188}
189
190# generate the key material for the file
191if(!-f $enc_key_file)
192{
193        print "Generating keys for file backup\n";
194        if(system("openssl rand -out $enc_key_file 1024") != 0)
195        {
196                die "Couldn't generate file backup keys."
197        }
198}
199
200# write the notify when store full script
201print "Writing notify script $notify_script\n";
202open NOTIFY,">$notify_script" or die "Can't open for writing";
203
204my $hostname = `hostname`; chomp $hostname;
205my $current_username = `whoami`; chomp $current_username;
206my $sendmail = `whereis sendmail`; chomp $sendmail;
207$sendmail =~ s/\n.\Z//s;
208# for Linux style whereis
209$sendmail = $1 if $sendmail =~ /^sendmail:\s+([\S]+)/;
210# last ditch guess
211$sendmail = 'sendmail' if $sendmail !~ m/\S/;
212
213print NOTIFY <<__EOS;
214#!/bin/sh
215
216# This script is run whenever bbackupd changes state or encounters a
217# problem which requires the system administrator to assist:
218#
219# 1) The store is full, and no more data can be uploaded.
220# 2) Some files or directories were not readable.
221# 3) A backup run starts or finishes.
222#
223# The default script emails the system administrator, except for backups
224# starting and stopping, where it does nothing.
225
226SUBJECT="BACKUP PROBLEM on host $hostname"
227SENDTO="$current_username"
228
229if [ "\$1" = "" ]; then
230        echo "Usage: \$0 <store-full|read-error|backup-ok|backup-error|backup-start|backup-finish>" >&2
231        exit 2
232elif [ "\$1" = store-full ]; then
233        $sendmail \$SENDTO <<EOM
234Subject: \$SUBJECT (store full)
235To: \$SENDTO
236
237
238The store account for $hostname is full.
239
240=============================
241FILES ARE NOT BEING BACKED UP
242=============================
243
244Please adjust the limits on account $account_num on server $server.
245
246EOM
247elif [ "\$1" = read-error ]; then
248$sendmail \$SENDTO <<EOM
249Subject: \$SUBJECT (read errors)
250To: \$SENDTO
251
252
253Errors occured reading some files or directories for backup on $hostname.
254
255===================================
256THESE FILES ARE NOT BEING BACKED UP
257===================================
258
259Check the logs on $hostname for the files and directories which caused
260these errors, and take appropriate action.
261
262Other files are being backed up.
263
264EOM
265elif [ "\$1" = backup-start -o "\$1" = backup-finish -o "\$1" = backup-ok ]; then
266        # do nothing by default
267        true
268else
269$sendmail \$SENDTO <<EOM
270Subject: \$SUBJECT (unknown)
271To: \$SENDTO
272
273
274The backup daemon on $hostname reported an unknown error (\$1).
275
276==========================
277FILES MAY NOT BE BACKED UP
278==========================
279
280Please check the logs on $hostname.
281
282EOM
283fi
284__EOS
285
286close NOTIFY;
287chmod 0700,$notify_script or die "Can't chmod $notify_script";
288
289
290# write the configuration file
291print "Writing configuration file $config_file\n";
292open CONFIG,">$config_file" or die "Can't open config file for writing";
293print CONFIG <<__E;
294
295StoreHostname = $server
296AccountNumber = 0x$account_num
297KeysFile = $enc_key_file
298
299CertificateFile = $certificate
300PrivateKeyFile = $private_key
301TrustedCAsFile = $ca_root_cert
302
303DataDirectory = $working_dir
304
305
306# This script is run whenever bbackupd changes state or encounters a
307# problem which requires the system administrator to assist:
308#
309# 1) The store is full, and no more data can be uploaded.
310# 2) Some files or directories were not readable.
311# 3) A backup run starts or finishes.
312#
313# The default script emails the system administrator, except for backups
314# starting and stopping, where it does nothing.
315
316NotifyScript = $notify_script
317
318__E
319
320if($backup_mode eq 'lazy')
321{
322        # lazy mode configuration
323        print CONFIG <<__E;
324
325# The number of seconds between backup runs under normal conditions. To avoid
326# cycles of load on the server, this time is randomly adjusted by a small
327# percentage as the daemon runs.
328
329UpdateStoreInterval = 3600
330
331
332# The minimum age of a file, in seconds, that will be uploaded. Avoids
333# repeated uploads of a file which is constantly being modified.
334
335MinimumFileAge = 21600
336
337
338# If a file is modified repeated, it won't be uploaded immediately in case
339# it's modified again, due to the MinimumFileAge specified above. However, it
340# should be uploaded eventually even if it is being modified repeatedly. This
341# is how long we should wait, in seconds, after first noticing a change.
342# (86400 seconds = 1 day)
343
344MaxUploadWait = 86400
345
346# If the connection is idle for some time (e.g. over 10 minutes or 600
347# seconds, not sure exactly how long) then the server will give up and
348# disconnect the client, resulting in Connection Protocol_Timeout errors
349# on the server and TLSReadFailed or TLSWriteFailed errors on the client.
350# Also, some firewalls and NAT gateways will kill idle connections after
351# similar lengths of time.
352#
353# This can happen for example when most files are backed up already and
354# don't need to be sent to the store again, while scanning a large
355# directory, or while calculating diffs of a large file. To avoid this,
356# KeepAliveTime specifies that special keep-alive messages should be sent
357# when the connection is otherwise idle for a certain length of time,
358# specified here in seconds.
359#
360# The default is that these messages are never sent, equivalent to setting
361# this option to zero, but we recommend that all users enable this.
362
363KeepAliveTime = 120
364
365__E
366}
367else
368{
369        # snapshot configuration
370        print CONFIG <<__E;
371
372# This configuration file is written for snapshot mode.
373# You will need to run bbackupctl to instruct the daemon to upload files.
374
375AutomaticBackup = no
376UpdateStoreInterval = 0
377MinimumFileAge = 0
378MaxUploadWait = 0
379
380__E
381}
382
383print CONFIG <<__E;
384
385# Files above this size (in bytes) are tracked, and if they are renamed they will simply be
386# renamed on the server, rather than being uploaded again. (64k - 1)
387
388FileTrackingSizeThreshold = 65535
389
390
391# The daemon does "changes only" uploads for files above this size (in bytes).
392# Files less than it are uploaded whole without this extra processing.
393
394DiffingUploadSizeThreshold = 8192
395
396
397# The limit on how much time is spent diffing files, in seconds. Most files
398# shouldn't take very long, but if you have really big files you can use this
399# to limit the time spent diffing them.
400#
401# * Reduce if you are having problems with processor usage.
402#
403# * Increase if you have large files, and think the upload of changes is too
404#   large and you want bbackupd to spend more time searching for unchanged
405#   blocks.
406
407MaximumDiffingTime = 120
408
409
410# Uncomment this line to see exactly what the daemon is going when it's connected to the server.
411
412# ExtendedLogging = yes
413
414
415# This specifies a program or script script which is run just before each
416# sync, and ideally the full path to the interpreter. It will be run as the
417# same user bbackupd is running as, usually root.
418#
419# The script must output (print) either "now" or a number to STDOUT (and a
420# terminating newline, no quotes).
421#
422# If the result was "now", then the sync will happen. If it's a number, then
423# no backup will happen for that number of seconds (bbackupd will pause) and
424# then the script will be run again.
425#
426# Use this to temporarily stop bbackupd from syncronising or connecting to the
427# store. For example, you could use this on a laptop to only backup when on a
428# specific network, or when it has a working Internet connection.
429
430# SyncAllowScript = /path/to/intepreter/or/exe script-name parameters etc
431
432
433# Where the command socket is created in the filesystem.
434
435CommandSocket = $working_dir/bbackupd.sock
436
437# Uncomment the StoreObjectInfoFile to enable the experimental archiving
438# of the daemon's state (including client store marker and configuration)
439# between backup runs. This saves time and increases efficiency when
440# bbackupd is frequently stopped and started, since it removes the need
441# to rescan all directories on the remote server. However, it is new and
442# not yet heavily tested, so use with caution.
443
444# StoreObjectInfoFile = $working_dir/bbackupd.state
445
446Server
447{
448        PidFile = $working_dir/bbackupd.pid
449}
450
451
452# BackupLocations specifies which locations on disc should be backed up. Each
453# directory is in the format
454#
455#       name
456#       {
457#               Path = /path/of/directory
458#               (optional exclude directives)
459#       }
460#
461# 'name' is derived from the Path by the config script, but should merely be
462# unique.
463#
464# The exclude directives are of the form
465#
466#       [Exclude|AlwaysInclude][File|Dir][|sRegex] = regex or full pathname
467#
468# (The regex suffix is shown as 'sRegex' to make File or Dir plural)
469#
470# For example:
471#
472#       ExcludeDir = /home/guest-user
473#       ExcludeFilesRegex = \.(mp3|MP3)\$
474#       AlwaysIncludeFile = /home/username/veryimportant.mp3
475#
476# This excludes the directory /home/guest-user from the backup along with all mp3
477# files, except one MP3 file in particular.
478#
479# In general, Exclude excludes a file or directory, unless the directory is
480# explicitly mentioned in a AlwaysInclude directive. However, Box Backup
481# does NOT scan inside excluded directories and will never back up an
482# AlwaysIncluded file or directory inside an excluded directory or any
483# subdirectory thereof.
484#
485# To back up a directory inside an excluded directory, use a configuration
486# like this, to ensure that each directory in the path to the important
487# files is included, but none of their contents will be backed up except
488# the directories further down that path to the important one.
489#
490# ExcludeDirsRegex = ^/home/user/bigfiles/
491# ExcludeFilesRegex = ^/home/user/bigfiles/
492# AlwaysIncludeDir = /home/user/bigfiles/path
493# AlwaysIncludeDir = /home/user/bigfiles/path/to
494# AlwaysIncludeDir = /home/user/bigfiles/path/important
495# AlwaysIncludeDir = /home/user/bigfiles/path/important/files
496# AlwaysIncludeDirsRegex = ^/home/user/bigfiles/path/important/files/
497# AlwaysIncludeFilesRegex = ^/home/user/bigfiles/path/important/files/
498#
499# If a directive ends in Regex, then it is a regular expression rather than a
500# explicit full pathname. See
501#
502#       man 7 re_format
503#
504# for the regex syntax on your platform.
505
506BackupLocations
507{
508__E
509
510# write the dirs to backup
511for my $d (@tobackup)
512{
513        $d =~ m/\A.(.+)\Z/;
514        my $n = $1;
515        $n =~ tr`/`-`;
516       
517        my $excludekeys = '';
518        if(substr($enc_key_file, 0, length($d)+1) eq $d.'/')
519        {
520                $excludekeys = "\t\tExcludeFile = $enc_key_file\n";
521                print <<__E;
522
523NOTE: Keys file has been explicitly excluded from the backup.
524
525__E
526        }
527       
528        print CONFIG <<__E
529        $n
530        {
531                Path = $d
532$excludekeys    }
533__E
534}
535
536print CONFIG "}\n\n";
537close CONFIG;
538
539# explain to the user what they need to do next
540my $daemon_args = ($config_file eq $default_config_location)?'':" $config_file";
541my $ctl_daemon_args = ($config_file eq $default_config_location)?'':" -c $config_file";
542
543print <<__E;
544
545===================================================================
546
547bbackupd basic configuration complete.
548
549What you need to do now...
550
5511) Make a backup of $enc_key_file
552   This should be a secure offsite backup.
553   Without it, you cannot restore backups. Everything else can
554   be replaced. But this cannot.
555   KEEP IT IN A SAFE PLACE, OTHERWISE YOUR BACKUPS ARE USELESS.
556
5572) Send $certificate_request
558   to the administrator of the backup server, and ask for it to
559   be signed.
560
5613) The administrator will send you two files. Install them as
562      $certificate
563      $ca_root_cert
564   after checking their authenticity.
565
5664) You may wish to read the configuration file
567      $config_file
568   and adjust as appropriate.
569   
570   There are some notes in it on excluding files you do not
571   wish to be backed up.
572
5735) Review the script
574      $notify_script
575   and check that it will email the right person when the store
576   becomes full. This is important -- when the store is full, no
577   more files will be backed up. You want to know about this.
578
5796) Start the backup daemon with the command
580      @sbindir_expanded@/bbackupd$daemon_args
581   in /etc/rc.local, or your local equivalent.
582   Note that bbackupd must run as root.
583__E
584if($backup_mode eq 'snapshot')
585{
586        print <<__E;
587
5887) Set up a cron job to run whenever you want a snapshot of the
589   file system to be taken. Run the command
590      @bindir_expanded@/bbackupctl -q$ctl_daemon_args sync
591__E
592}
593print <<__E;
594
595===================================================================
596
597Remember to make a secure, offsite backup of your backup keys,
598as described in step 1 above. If you do not, you have no backups.
599
600__E
601
Note: See TracBrowser for help on using the repository browser.