OmniBackup is a MIT-licensed Bash script which delivers the following set of features:
- Support for *NIX operating systems (e.g. *BSD and GNU/Linux)
- Configuration and customization of backup mechanism through JSON
- Support for OpenLDAP backups
- Support for PostgreSQL backups as a whole or per database
- Support for MariaDB and MySQL backups as a whole or per database
- Support for filesystem backups with optional ability to follow symbolic links
- Support for pluggable customized scripts to extend OmniBackup functionality beyond its original design which allows support for many different backup scenarios that has not been built into OmniBackup, yet
- Backup file name tagging which allows including date, time, or host name in the archive name
- Online backup without a prerequisite to suspend any service
- Support for customized backup tasks priority order
- Support for multiple backup servers
- Ability to always keep a copy of backups offline
- Ability to keep a copy of backups offline if no backup server is available, or in case of an error such as a file transfer error
- Secure file transfer through SSH / SCP protocol
- LZMA2, gzip and bzip2 compression algorithms along with different compression levels to maintain a balance between speed and file size
- Ability to preserve permissions inside backup files
- Support for symmetric cryptography algorithms AES-128, AES-192 and AES-256 (a.k.a Rijndael or Advanced Encryption Standard)
- Random passphrase generation for encrypted backups with variable length and patterns or a unique passphrase for all backups
- Support for RSA signatures to verify the backup origin and integrity
- Passphrase encryption using RSA public keys for individual backup servers
- Backup integrity verification by offering hash algorithms such as MD4, MD5, MDC-2, RIPEMD160, SHA, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512 and WHIRLPOOL
- Optional Base64 encoding
- System logs and a standalone log file including all details
- Reporting through email to a list of recipients with ability to include passphrases
- Customized mail subject for successful and failed backup operations
- Customized support message for reports
- Crontab integration
- Custom temporary / working directory
- Automatic and smart clean-up ability
- One instance only policy which avoids running multiple instances by mistake at the same time, therefore avoids system slow-down
- An example configuration file in JSON format to get you up and running
Please be wary of the fact that this script has approximately 3.5 K
lines of Bash code and devoured hell of a time from me to write and debug. You should also consider that this is my first heavy Bash experiment and I may not write quality code in the language since I'm a newcomer to Bash. I do not claim that OmniBackup is production ready, that's why I did version the first release at 0.1.0
. Also keep in mind that OmniBackup heavily relies on 3rd-party software which increases the chance for fatal bugs, therefore losing data. So, I provide OmniBackup without any warranties, guarantees or conditions, of any kind and I accept no liability or responsibility for any misuse or damage. Please use it at your own risk and remember you are solely responsible for any resulting damage or data loss.
- Message Types and Their Meanings
- Requirements
- Installation
- Configuring Temporary Directory
- Configuring Compression
- Configuring Security
- Configuring Reports
- Configuring Remote Backup Servers
- Configuring Backup Tasks
- Configuring Backup Priority and Order
- Configuring OpenLDAP Backups
- Configuring Database Backups
- Configuring PostgreSQL Database Backups
- Configuring MariaDB and MySQL Databases Backups
- Configuring Filesystem Backups
- Configuring Other Backups
- 3rd-party Commands status codes
- Generating RSA Keys
- Password-less SSH Login
- SMTP Relay for Hosts with Private IPs
- First Run
- Crontab
- Restore
- Restoring Encrypted Archives
- Restoring Archives
- Restoring OpenLDAP Backups
- Restoring PostgreSQL Backups
- Restoring MariaDB or MySQL Backups
- Staying Away From Disaster
- Example Report
- ToDo
- License
Before we go any further, you may want to know that other than regular logs there are different kinds of messages in OmniBackup which may appear on screen, system logs or mail reports:
DEBUG
it's for development purpose only, so you should not see any message of this kind.ERROR
some error happened, but hopefully the program is able to continue.FATAL
indicates that something went south due to unrecoverable errors and the program terminates immediately.INFO
informational notices to inform you about regular events inside the program.SUCCESS
indicates an operation has been successful.TRACE
it's for development purpose only, so you should not see any message of this kind.WARNING
indicates that a dangerous situation might happen or already happened which is not desired.
Originally OmniBackup developed on FreeBSD. Recently, I had the time to test it on Funtoo Linux (a variant of Gentoo) and without any modification to the original code it worked just fine. In my estimation, the current code should work out of the box inside any GNU/Linux distribution since I tried my best to write it in a platform-independent manner by reading pile of man pages. I assume if it works on FreeBSD it should also work on other BSDs and GNU/Linuxes. But I'm only 99.99% sure and when it comes to programming computers 0.01% human error is really too much and risky. So, I really appreciate feedbacks and possible patches or pull-requests.
Aside from Bash, OmniBackup requires other tools and utilities. Although most of these programs are found in a base installation of your operating system, it relies on a few other programs which has to be installed before you go any further. Note that if OmniBackup cannot find a program it gives you a fatal error message and exits.
Requirements for OmniBackup include:
basename
bash
version4.2+
bzip2
caller
cat
cd
chown
cut
date
dirname
du
echo
expr
flock
grep
gzip
head
hostname
jq
version1.4+
logger
mail
mkdir
mysqldump
openssl
pg_dump
pg_dumpall
printf
readlink
rm
scp
slapcat
ssh
strings
sudo
tar
tr
xz
I should add, not all of the above dependencies are required in order for OmniBackup to work. At runtime, it dynamically decides which dependencies are required and then search for them. For example, if you did not enabled PostgreSQL database backup, it won't look for pg_dump
, pg_dumpall
and sudo
binaries. Or, if you choose to go with LZMA2 compression algorithm it only looks for xz
and ignore both bzip2
and gzip
binaries. Of course some of these commands like cd
are internal and there is no need to lookup the filesystem to find them. On my FreeBSD system I only had to install the following ports in order to have all the dependencies complete:
databases/postgresql9*-client
one of these ports providepg_dump
andpg_dumpall
databases/mariadb*-client
one of these ports providesmysqldump
databases/mysql5*-client
one of these ports providesmysqldump
openldap24-server
providesslapcat
security/sudo
providessudo
shells/bash
providesbash
sysutils/flock
probably a default on GNU/Linux, providesflock
executable on FreeBSDtextproc/jq
providesjq
Note that from the above list flock
and jq are only mandatory requirements unless based on OmniBackup configurations other dependencies get pulled in. The best way to determine dependencies is to ignore the list of dependencies and first configure your OmniBackup instance. When your done with that, run OmniBackup manually for the first time. If it won't complain about any dependency then you are good to go. However, if it does, then you should resolve the dependencies one by one until you satisfy all the dependencies and good to go.
Notes for Funtoo/Gentoo Linux: From the mandatory requirements list, I had to install app-misc/jq
. All other requirements except mail
were in place. Both mail-client/mailx
and mail-mta/ssmtp
provide mail
command for you.
$ emerge -avt mail-client/mailx
or
$ emerge -avt mail-mta/ssmtp
In addition to that, running OmniBackup for the first time on Funtoo generated lots of this error:
logger: socket /dev/log: No such file or directory
To fix that install and start app-admin/syslog-ng
:
$ emerge -avt app-admin/syslog-ng
$ rc-update add syslog-ng default
$ service syslog-ng start
From FreeBSD Ports:
$ cd /usr/ports/sysutils/omnibackup
$ make install clean
Binary install using pkgng
$ pkg install sysutils/omnibackup
Installing OmniBackup is really easy. It consists of two files: a huge script file -- approximately 107 KB
-- named backup.sh
which looks for the second file at runtime named config.json
. It looks for config.json
in the following order:
- In the user's home directory
~
that OmniBackup runs under. e.g:/root/.omnibackup/config.json
or/home/babaei/.omnibackup/config.json
- In
/usr/local/etc/omnibackup/config.json
- In
/etc/omnibackup/config.json
- In the current directory which is the directory that OmniBackup executable itself resides
For the sake of simplicity I'll keep the config.json
file in the same directory as the executable itself, in the rest of this document.
So, let's say I want to install OmniBackup inside /usr/local/omnibackup
. In addition to that, I assume from now on you do everything as root
user:
$ cd /usr/local/
GitHub:
$ git clone https://github.com/NuLL3rr0r/omnibackup.git
GitLab:
$ git clone https://github.com/NuLL3rr0r/omnibackup.git
$ cd omnibackup
$ cp config.json.sample config.json
$ chmod u+rx,go-r,a-w backup.sh
$ chmod u+rw,go-rw,a-x config.json
All we did was cloning the code from GitHub, copying over the sample configuration file as a template and assigning the right permissions for both the script and configuration file. I prefer to make this files root
accessible only, so no one else can read our configuration or modify it or even triggering the backup process.
You should avoid running the backup script in this step. As I mentioned we just copied a sample file to get you up and running. So, you should only run it after the final configurations are done, since it pickups possible dependencies from the configuration file and it may baffles you with the wrong dependencies errors. So, for now open-up the configuration file in your favorite editor and take a look.
The first option inside config.json
file is .temp_dir
which specifes the temporary or working directory for OmniBackup. /var/tmp
seems to be a reasonable place. Feel free to adopt it according to your needs. But, if you are going to change it to a path other than /var/tmp/
or /tmp/
choose an empty one. Note that each time you run OmniBackup it creates a log file inside /var/tmp/
e.g. /var/tmp/backup.2015-07-31.58471.log
. You cannot change the path for the log files due to technical limitations. Keep in mind that OmniBackup never removes its log files due to their small footprints. They may come handy when reports won't deliver to your email.
{
"temp_dir" : "/var/tmp",
}
You've been given three options for compression:
{
"compression" :
{
"algorithm" : "lzma2",
"level" : "6e",
"preserve_permissions" : "yes"
},
}
.compression.algorithm
accepts only four possible values: lzma2
, gzip
and bzip2
which determines the compression algorithm, or, you can leave it blank for no compression at all. This affects the extension of the backup file which we call archive from now on. For lzma2
it will be .tar.xz
, for gzip
, .tar.gz
, for bzip2
, tar.bz2
and for no compression mode it will be simply .tar
. Also, lzma2
, gizp
and bzip2
values, pull in xz
, gizp
and bizip2
binaries as dependency, respectively.
.compression.level
option accepts values between 1
to 9
for gizp
and bzip2
algorithms. For lzma2
algorithm it accepts values between 1
to 9
and 1e
to 9e
. e
stands for extreme and aggressive compression which demands more RAM and CPU cycles. In case you choose no compression mode, the level
option will be ignored.
.compression.preserve_permissions
is self-explanatory, it preserve the archived files permissions inside the final archive file.
Security module provides many features that you may not notice at the first sight:
{
"security" :
{
"checksum_algorithm" : "sha512",
"encryption" :
{
"enable" : "yes",
"key_size" : "256",
"base64_encode" : "no",
"passphrase" : "",
"random_passphrase_pattern" : "print",
"random_passphrase_length" : 128,
"private_key" : "~/keys/private.pem"
}
},
}
Please be wary, this module heavily relies on OpenSSL. So, some of the hash or encryption algorithms may not work in case you or your distribution built OpenSSL with those options excluded.
.security.checksum_algorithm
provides various hash algorithms to verify the archive file integrity later on. md4
, md5
, mdc2
, ripemd160
, sha
, sha1
, sha224
, sha256
, sha384
, sha512
and whirlpool
algorithms are all valid options and well supported. If encryption is disabled or you did not provide a private key, OmniBackup creates a checksum file with extension .sum
which includes the archive checksum and uploads it along with your archive file. If encryption is enabled and you did provide a private key it uses the checksum file to sign the archive and instead of uploading .sum
file, uploads the signature file with extension .sign
, so that it can be verified using your public key at the destination. In either case OmniBackup includes the checksum in reports and send it through email to you.
.security.encryption.enable
should either set to yes
or no
. If you set it to no
the rest of the encryption options will be ignored.
.security.encryption.key_size
only accepts 128
, 192
and 256
values which in turn enables AES-128, AES-192 and AES-256 encryption.
.security.encryption.base64_encode
if you set it to yes
, the encrypted archive file, signature file and the encrypted archive passphrase will be base64 encoded, otherwise they will all be in binary format which saves up disk space and bandwidth.
.security.encryption.passphrase
is the passphrase to encrypt or decrypt archive files. If you leave it blank, OmniBackup generates a random password for each archive file. Otherwise, it uses the specified password for all archive files and ignore both random_passphrase_pattern
and random_passphrase_length
options. If you decide to use a unique password for all backups make sure config.json
is only readable by its owner. If set to blank, it pulls in grep
, head
, strings
and tr
as dependency.
.security.encryption.random_passphrase_pattern
indicates the pattern to generate a random passphrase. For more information see the documentation of GNU and BSD implementations of grep
:
alnum
Alphanumeric characters:alpha
anddigit
; in theC
locale and ASCII character encoding, this is the same as[0-9A-Za-z]
.alpha
Alphabetic characters:lower
andupper
; in theC
locale and ASCII character encoding, this is the same as[A-Za-z]
.blank
Blank characters: space and tab.cntrl
Control characters. In ASCII, these characters have octal codes000
through037
, and177 (DEL)
. In other character sets, these are the equivalent characters, if any.digit
Digits:0 1 2 3 4 5 6 7 8 9
.graph
Graphical characters:alnum
andpunct
.lower
Lower-case letters; in theC
locale and ASCII character encoding, this isa b c d e f g h i j k l m n o p q r s t u v w x y z
.print
Printable characters:alnum
,punct
, and space.punct
Punctuation characters; in theC
locale and ASCII character encoding, this is! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~
.space
Space characters: in theC
locale, this is tab, newline, vertical tab, form feed, carriage return, and space.upper
Upper-case letters: in theC
locale and ASCII character encoding, this isA B C D E F G H I J K L M N O P Q R S T U V W X Y Z
.xdigit
Hexadecimal digits:0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f
.
.security.encryption.random_passphrase_length
a positive number bigger than 0
that indicates the length of random passphrases.
.security.encryption.private_key
is a private key in PEM format used to sign the encrypted archive file so that anyone knows the file originated from you. Note it only accepts absolute path and relative paths starting from home folder (tilde ~
). Do not start paths relative to OmniBackup directory. Also, keep in mind that avoid space and exotic characters inside path. It's both sane and safe to only include A-Z
, a-z
and underscore _
in path because I cannot guarantee its safety. We'll discuss RSA key generation later on.
Reports module is here to allow you become aware of all the details of the events that happened during the backup process, through email:
{
"reports" :
{
"mailboxes" :
[
{
"email_address" : "[email protected]",
"attach_passphrases" : "yes"
},
{
"email_address" : "[email protected]",
"attach_passphrases" : "no"
}
],
"subject" :
{
"success" : "[{HOST_NAME} {DATE}] BACKUP REPORT / SUCCESS",
"error" : "[{HOST_NAME} {DATE}] BACKUP REPORT / ERROR",
"fatal" : "[{HOST_NAME} {DATE}] BACKUP REPORT / FATAL ERROR"
},
"support_info" : "Have question or need technical assistance, please visit http://www.babaei.net/ or write an email to info [ at ] babaei.net."
},
}
.reports.mailboxes
is a JSON array of email addresses and their settings who will receive the backup report when it's done, either successful or failed.
.reports.mailboxes.email_address
should be a valid email address.
.reports.mailboxes.attach_passphrases
determines whether passphrases for archive files should be attached to the reports for that specific email or not.
.reports.subject
provides the ability to determine the subject of reports for different scenarios that might happen during the backup process at runtime, so by looking at your inbox you immediately realize what happened and take the appropriate action if it's necessary. {HOST_NAME}
and {DATE}
are recognized special placeholder keywords. They will be replaced at runtime by the host name OmniBackup backup running on or the date OmniBackup instance starts backup jobs, respectively. There is also a {TIME}
variable if one desires to include the time in the subject of the email.
.reports.success
is the email subject when backup process finished successfully.
.reports.error
is the email subject when at least one error happened during the backup process.
.reports.fatal
is the email subject when backup process faced a fatal error so it could not finish the jobs.
.reports.support_info
allows adding a customized support message to the end of the reports.
Using the .remote
section of the configuration file, you can configure as many as remote backup servers that you wish. If you plan to keep backup files locally, this section provides two possible ways to do that which we'll discuss later. Note that you also have to setup password-less SSH login regardless of choosing a remote server or the current host as a backup server.
{
"remote" :
{
"keep_backup_locally" : "partial",
"servers" :
[
{
"host" : "10.12.0.4",
"port" : "22",
"user" : "babaei",
"dir" : "~/backups/{HOST_NAME}",
"backups_to_preserve" : 7,
"public_key" : "~/keys/10.12.0.4_babaei.pem"
},
{
"host" : "example.domain",
"port" : "8931",
"user" : "babaei",
"dir" : "~/backups/{HOST_NAME}",
"backups_to_preserve" : 31,
"public_key" : "~/keys/example.domain_babaei.pem"
}
]
},
}
.remote.keep_backup_locally
accepts four possible values.
-
never
: always remove the temporary backup file, no matter what. -
error
: always remove the temporary backup file unless an upload error happens. -
partial
: keep the backup file in case the upload operation for a single backup file was partially successful. This indicates that at least one upload operation for a specific backup file has been successful. So, we are sure we have the backup file on at least one of the backup servers. -
success
: do not remove the local backup file and keep it inside.temp_dir
directory, even in case of succeeding all upload operations. This option is one way to always keep the backup files locally although it is not recommended. If you're going to use this method anyway, it is recommended to use some other path instead of/var/tmp
or/tmp
as your.temp_dir
. -
.remote.servers
is a JSON array of backup servers. The second method to keep a copy of backup files locally is to define the current host as another remote server here which is the recommended method to do so. -
.remote.servers.host
is the host name or IP address of a backup server. -
.remote.servers.port
is the SSH port for that backup server. -
.remote.servers.user
is a user with SSH access on the server. -
.remote.servers.dir
specifies a directory in which we keep the backup files.{HOST_NAME}
is recognized as a valid placeholder for the current host's name (not the backup server) and should be automatically replaced at runtime. -
.backups_to_preserve
determines how many days of older backups should be kept. For example, if I set this to10
for one of the backup servers, I should only have10
days of backup on that server, plus today or tonight's backup. Be advised that any negative number -- e.g.-1
-- has special meanings here. It means do not clean up any older backup, basically keep them forever. -
public_key
is a public key in PEM format for encrypting passphrases. As you recall these passphrases are required to decrypt the archive files. If you do not specify a public key for a backup server, you do not have access to encrypted passphrases on that server. It is useful in case that you do not wish to keep the passphrases in the same place as your encrypted archive files, even the encrypted ones. I must warn and assure you, if you are using random passphrases and and you did not provide any public key here, your backups are good for nothing unless you chose to attach passphrases to at least one email in the reports section. In addition to everything, it's possible to only provide one pair of RSA keys instead of one private key and multiple public keys if you are the sole receiver of the backup files on those multiple servers. I'll describe RSA key generation later.
.backup
is the actual part of the configuration which determines what has to be backed up. I'll break it down into a few sections for the sake of simplicity.
{
"backup" :
{
"archive_name" : "{DATE}_{HOST_NAME}_{TAG}",
},
}
.backup.archive_name
is a pattern for archive file names. You can prefix or postfix them as you wish by modifying this option. {DATE}
shall be replaced by the actual date that OmniBackup script started. The date format is fixed and looks like YYYY-MM-DD
. If you need to include the time in addition to the date, a <code{TIME}> option is also available in HH-MM-SS
form. {HOST_NAME}
shall be replaced by the host name that OmniBackup runs on. {TAG}
is an option for each item that should be backed up, so it shall be replaced with that option's value for each backup task. So, with above configuration in mind, a typical backup archive file should look like this:
2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz
2015-07-31
, blog.babaei.net
and openldap-babaei-net
are {DATE}
, {HOST_NAME}
and {TAG}
in the archive file name, respectively.
One of the most important steps is to configure what should be backed up, in which order:
{
"backup" :
{
"priority_order" :
[
"openldap",
"database",
"filesystem",
"misc"
],
},
}
.backup.priority_order
only recognizes four elements: openldap
, database
, filesystem
and misc
. Although, they should be self-explanatory, I have to add a comment for misc
which is a special item in this list. It allows you to run an external script and pass arguments to it. After the script is finished, OmniBackup is able to backup a directory or file as its output. So, we'll be able to plug extra scripts to OmniBackup. We will discuss this later.
In the above example, OmniBackup backups in this order: OpenLDAP, databases, filesystem and finally other customized backups. You can change the order by swapping their order of appearance. If you want for example avoid backing up, filesystem, you should remove it from this list. Otherwise, OmniBackup looks for its configuration.
Let's consider an example if I need to only backup first database and then filesystem:
{
"backup" :
{
"priority_order" :
[
"database",
"filesystem"
],
},
}
This is all we need to backup OpenLDAP objects and directories using slapcat
:
{
"backup" :
{
"openldap" :
{
"tag" : "openldap-babaei-net",
"user" : "ldap",
"group" : "ldap",
"flags" : ""
},
},
}
.backup.openldap.tag
is used to replace {TAG}
in .backup.archive_name
. Since it's going to be part of a file name, it is highly recommended to avoid space or any other character that needs escaping or quotation.
.backup.openldap.user
is optional system user to run slapcat
under.
.backup.openldap.group
is optional system group to run slapcat
under.
.backup.openldap.flags
is used to pass arguments directly to slapcat
. If you are OK with defaults or do not have any idea what is that, just leave it as it is.
Like the general backup configuration, database section also needs specifying the types of backup jobs and their order of running:
{
"backup" :
{
"database" :
{
"priority_order" :
[
"postgres",
"mysql"
],
},
},
}
OmniBackup officially only recognizes two types of database to backup. PostgreSQL and MariaDB / MySQL. Of course, it won't stop you from writing your own backup scripts for other databases. You can plug such scripts to OmniBackup using .backup.misc
which we'll see later.
.backup.database.priority_order
everything for .backup.priority_order
also applies here.
Configuring PostgreSQL backups consists of two easy steps: first providing a user name with an optional group name and finally a list of databases to backup:
{
"backup" :
{
"database" :
{
"postgres" :
{
"user" : "pgsql",
"group" : "pgsql",
"databases" :
[
{
"tag" : "postgres",
"name" : "*",
"comment" : "All PostgreSQL databases"
},
{
"tag" : "postgres-gitlab",
"name" : "gitlab",
"comment" : "GitLab database"
},
{
"tag" : "postgres-redmine",
"name" : "redmine",
"comment" : "Redmine database"
},
{
"tag" : "postgres-agilo",
"name" : "agilo",
"comment" : "Agilo for Trac database"
},
{
"tag" : "postgres-owncloud",
"name" : "owncloud",
"comment" : "ownCloud database"
},
{
"tag" : "postgres-tracks",
"name" : "tracks",
"comment" : "Get on Tracks database"
}
]
},
},
},
}
backup.database.postgres.user
is a system user's name which runs our PostgreSQL service. For example, on my FreeBSD system it is called pgsql
. This user should be created by Ports, pkgng installation of PostgreSQL or whatever package manager your distro uses. It has different names on different platforms. You can figure it out by investigating /etc/passwd
or /etc/master.passwd
:
$ cat /etc/passwd
or
$ cat /etc/master.passwd
backup.database.postgres.group
is a mandatory system group's name which runs our PostgreSQL service. This one is completely optional. You can figure this one out by investigating /etc/group
.
backup.database.postgres.databases
is a JSON array of PostgreSQL databases.
backup.database.postgres.databases.tag
is a tag for archive file name. Everything for .backup.openldap.tag
also applies here.
backup.database.postgres.databases.name
is the exact database name inside your PostgreSQL instance. * means create a backup of all tables in one go, in one single dump file. I found it a best practice to have an entire database dump and a separate dump for each database. Why? Because, in one hand I sometimes forget to add new databases here, so that * takes care of that for me. On the other hand, sometimes you may face error restoring or importing back all your databases using a single dump file -- due to a bug, human error or anything --, so you have each database backup separately, then you won't loose much in such a scenario.
backup.database.postgres.databases.comment
is used inside logs, syslogs and reports to refer to that database instead of name which is not always clear.
The same as PostgreSQL goes for configuring MariaDB or MySQL databases:
{
"backup" :
{
"database" :
{
"mysql" :
{
"user" : "mysql",
"group" : "mysql",
"internal_user" : "root",
"databases" :
[
{
"tag" : "mysql",
"name" : "*",
"comment" : "All MySQL databases"
},
{
"tag" : "mysql-piwik",
"name" : "piwik",
"comment" : "Piwik database"
},
{
"tag" : "mysql-osticket",
"name" : "osticket",
"comment" : "Piwik database"
}
]
}
},
},
}
backup.database.mysql.user
serves a similar purpose as backup.database.postgres.user
except opposed to PostgreSQL this one is optional.
backup.database.mysql.group
serves a similar purpose as backup.database.postgres.group
and is optional.
backup.database.mysql.internal_user
is mandatory MariaDB / MySQL internal user name - usually root - who has enough privileges to take backups.
backup.database.mysql.databases
is a JSON array of MariaDB / MySQL databases.
backup.database.mysql.databases.tag
is a tag for archive file name. Everything for .backup.openldap.tag
also applies here.
backup.database.mysql.databases.name
serves the exact same purpose as backup.database.postgres.databases.name
.
backup.database.mysql.databases.comment
serves the exact same purpose as backup.database.postgres.databases.comment
.
Configuring filesystem backups are much easier since it's just a list of paths (files or directories) to backup:
{
"backup" :
{
"filesystem" :
[
{
"tag" : "www",
"path" : "/usr/local/www/nginx",
"follow_symlinks" : "yes",
"comment" : "Web server root directory"
},
{
"tag" : "repos",
"path" : "/usr/local/gitlab",
"follow_symlinks" : "yes",
"comment" : "GitLab repositories"
},
{
"tag" : "mail",
"path" : "/usr/local/mail",
"follow_symlinks" : "yes",
"comment" : "Mail server root directory"
},
{
"tag" : "etc-system",
"path" : "/etc",
"follow_symlinks" : "yes",
"comment" : "Base system configurations"
},
{
"tag" : "etc-ports",
"path" : "/usr/local/etc",
"follow_symlinks" : "yes",
"comment" : "Installed ports configurations"
},
{
"tag" : "loader-conf",
"path" : "/boot/loader.conf",
"follow_symlinks" : "yes",
"comment" : "System bootstrap configuration information"
},
{
"tag" : "boot-splash",
"path" : "/boot/splash.pcx",
"follow_symlinks" : "yes",
"comment" : "Boot-time splash screen"
},
{
"tag" : "slim-fbsd-theme",
"path" : "/usr/local/share/slim/themes/fbsd",
"follow_symlinks" : "yes",
"comment" : "FreeBSD SLiM theme"
}
],
},
}
backup.filesystem.tag
serves the exact same purpose as backup.openldap.tag
.
backup.filesystem.path
is the path to a directory, file or symbolic link to backup.
backup.filesystem.follow_symlinks
determines whether to follow symbolic links or leave them out from the archive.
backup.filesystem.comment
serves the exact same purpose as backup.database.postgres.databases.comment
.
Misc section allows plugging extra backup scripts to OmniBackup and capture their output as an archive. This one is also a JSON array:
{
"backup" :
{
"misc" :
[
{
"tag" : "cloudflare-ip-ranges",
"command" : "/usr/local/www/nginx/cron/cloudflare-ip-ranges-updater.sh",
"args" : "ipv4 ipv6",
"path" : "/usr/local/www/nginx/include/cloudflare",
"follow_symlinks" : "yes",
"remove_path_when_done" : "no",
"comment" : "CloudFlare IP database for nginx RealIP module"
}
]
},
}
backup.misc.tag
serves the exact same purpose as backup.openldap.tag
.
backup.misc.command
is the command or script to run. Although you can use pipes, arguments or in general a complicated one-liner command it is not recommended to do so since this option does not meant for such a scenario. I highly recommend creating another script and put everything in there. If your script succeeds return 0
, if not, return none zero values such as 1
.
backup.misc.args
is the list of arguments to pass to your script.
backup.misc.path
is the path to a directory, file or symbolic link as external script's output to backup.
backup.misc.follow_symlinks
determines whether to follow symbolic links or leave them out from the archive.
backup.misc.remove_path_when_done
determines whether to remove the path or not after the external script finished it jobs successfully. Be careful with this one if you don't know what is it or its function is not clear to you, yet.
backup.misc.comment
serves the exact same purpose as backup.database.postgres.databases.comment
.
.command
is a vital part of the configuration file and it should be present in order for OmniBackup to run properly. If its function is ambiguous to you, just leave it alone in the configuration file. That's why I put it at the end of the file, although the order does not matter in the configuration file. For two reasons OmniBackup needs this part:
- When OmniBackup runs, the first thing it looks for are its dependencies. It reads them from this list.
- When OmniBackup runs a third party command in case of failure it has to translate the return code of that command to a human understandable message. So, if you want to know what happened in case of error, you should leave this alone or extend it if you are sure about what are you doing.
For example look at the return codes for jq
, scp
and ssh
commands in the following list. Note that the return codes and their equivalent messages may not be accurate. Believe me, I tried my best to find the accurate ones. If you find something inaccurate, please let me know.
{
"command" :
{
"basename" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"bzip2" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"caller" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"cat" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"cd" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"chown" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"cut" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"date" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"du" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"dirname" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"echo" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"expr" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"flock" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"grep" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"gzip" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"head" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"hostname" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"jq" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_1" : "The last output value was either false or null.",
"rc_2" : "Usage problem or system error.",
"rc_3" : "Compile error,.",
"rc_4" : "Parse error.",
"rc_any" : "The operation failed."
}
},
"logger" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"mail" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"mkdir" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"mysqldump" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"openssl" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"pg_dump" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"pg_dumpall" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"printf" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"readlink" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"rm" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"scp" :
{
"return_code" :
{
"rc_0" : "Operation was successful.",
"rc_1" : "General error in file copy.",
"rc_2" : "Destination is not directory, but it should be.",
"rc_3" : "Maximum symlink level exceeded.",
"rc_4" : "Connecting to host failed.",
"rc_5" : "Connection broken.",
"rc_6" : "File does not exist.",
"rc_7" : "No permission to access file.",
"rc_8" : "General error in sftp protocol.",
"rc_9" : "File transfer protocol mismatch.",
"rc_10" : "No file matches a given criteria.",
"rc_65" : "Host not allowed to connect.",
"rc_66" : "General error in ssh protocol.",
"rc_67" : "Key exchange failed.",
"rc_68" : "Reserved.",
"rc_69" : "MAC error.",
"rc_70" : "Compression error.",
"rc_71" : "Service not available.",
"rc_72" : "Protocol version not supported.",
"rc_73" : "Host key not verifiable.",
"rc_74" : "Connection failed.",
"rc_75" : "Disconnected by application.",
"rc_76" : "Too many connections.",
"rc_77" : "Authentication cancelled by user.",
"rc_78" : "No more authentication methods available.",
"rc_79" : "Invalid user name.",
"rc_any" : "Unknown scp error."
}
},
"slapcat" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"ssh" :
{
"return_code" :
{
"rc_0" : "Operation was successful.",
"rc_1" : "Generic error.",
"rc_2" : "Connection failed.",
"rc_10" : "No file matches a given criteria.",
"rc_65" : "Host not allowed to connect.",
"rc_66" : "General error in ssh protocol.",
"rc_67" : "Key exchange failed.",
"rc_68" : "Reserved.",
"rc_69" : "MAC error.",
"rc_70" : "Compression error.",
"rc_71" : "Service not available.",
"rc_72" : "Protocol version not supported.",
"rc_73" : "Host key not verifiable.",
"rc_74" : "Connection failed.",
"rc_75" : "Disconnected by application.",
"rc_76" : "Too many connections.",
"rc_77" : "Authentication cancelled by user.",
"rc_78" : "No more authentication methods available.",
"rc_79" : "Invalid user name.",
"rc_255" : "Generic ssh error.",
"rc_any" : "Unknown ssh error."
}
},
"strings" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"sudo" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"tar" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"tr" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
},
"xz" :
{
"return_code" :
{
"rc_0" : "The operation completed successfully.",
"rc_any" : "The operation failed."
}
}
}
}
Generating a pair of RSA keys is fairly an easy task. Just make sure you have OpenSSL installed and then we are good to go. To generate a 4096-bit
private RSA key -- since I found it fair enough in terms of both security and performance -- :
$ openssl genrsa -out private.pem 4096
To extract the public key from our private key:
$ openssl rsa -in private.pem -out public.pem -outform PEM -pubout
Setting up a password-less SSH login is even easier than Generating RSA Keys. First, run the following command on the host which is going to run OmniBackup:
$ ssh-keygen -t rsa -b 4096
When it starts asking questions, it's possible to choose the default answers by just pressing Return
or Enter
key on your keyboard:
Generating public/private rsa key pair.
Enter file in which to save the key (/home/babaei/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/babaei/.ssh/id_rsa.
Your public key has been saved in /home/babaei/.ssh/id_rsa.pub.
The key fingerprint is:
e6:b1:2b:53:cd:22:0c:17:70:3f:a0:ab:c3:f4:b1:12 [email protected]
The key's randomart image is:
+--[ RSA 4096]----+
| ..o |
| o.o |
| . .o |
| ... . |
| E o+ So |
| o + oooooo |
| = o oo. |
| o o . |
| o. |
+-----------------+
Then push the public key to every single remote backup server by issuing the following command, once for each server:
$ cat ~/.ssh/id_rsa.pub | ssh -p {SSH_PORT_NUMBER} {USER_NAME}@{HOST_NAME_OR_IP} 'cat >> ~/.ssh/authorized_keys'
It asks for password the first time you run the above command per each server. After that, you should be able to login to the desired remote host without being asked for a password:
$ ssh -p {SSH_PORT_NUMBER} {USER_NAME}@{HOST}
If you did not setup a mail server or your server does not have a public IP you have to use another mail server, either your own or public services such as Gmail, Yahoo Mail, Inbox.com, Outlook or any other one as SMTP relay for outgoing messages. So that OmniBackup or any other program will be able to send email through a relay. sSMTP is such a great tool to easlity allow that.
On my FreeBSD system I have to first completely disable Sendmail which is the default MTA in a base installation of FreeBSD:
sendmail_enable="NO"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"
Then we build and install mail/ssmtp
from Ports collection:
$ cd /usr/ports/mail/ssmtp/
$ make config-recursive
$ make install clean
Or, install the binary package from pkgng:
$ pkg install mail/ssmtp
To replace sendmail
with ssmtp
, either do the following:
$ cd /usr/ports/mail/ssmtp/
$ make replace
Or, change your /etc/mail/mailer.conf
to:
sendmail /usr/local/sbin/ssmtp
send-mail /usr/local/sbin/ssmtp
mailq /usr/local/sbin/ssmtp
newaliases /usr/local/sbin/ssmtp
hoststat /usr/bin/true
purgestat /usr/bin/true
OK, before you can use the program, you should copy the files revaliases.sample
and ssmtp.conf.sample
in /usr/local/etc/ssmtp
to revaliases
and ssmtp.conf
respectively, then edit them to suit your needs:
$ cp /usr/local/etc/ssmtp/revaliases.sample /usr/local/etc/ssmtp/revaliases
$ cp /usr/local/etc/ssmtp/ssmtp.conf.sample /usr/local/etc/ssmtp/ssmtp.conf
Let's assume, I have a running SMTP mail server on mail.example.com
which allows SSL connections on port 465
. I have a working user account on this mail server called [email protected]
.
Now, I want every message from user root
to be sent as Charlie Root [email protected]
and every message from user babaei
as [email protected]
. All other users as [email protected]
. So:
root:[email protected]:mail.example.com:465
babaei:[email protected]:mail.example.com:465
root=postmaster
mailhub=mail.example.com:465
rewriteDomain=babaei.net
hostname=blog.babaei.net
FromLineOverride=YES
UseTLS=YES
[email protected]
AuthPass=SECRET_PASSWORD
Debug=NO
Note that if you are using STARTTLS
on another port other than 465
, you should use UseSTARTTLS=YES
instead of UseTLS=YES
in the above example.
There's also a security consideration in the above example. You should always keep both AuthUser
and AuthPass
before the Debug
option, why? Because when it's enable it prints your user name and password in system logs.
If everything is done properly, you should be able to send an email from command line:
cat /etc/motd | mail -v -s "Hello, World!" [email protected]
OK, after taking the journey of configuring OmniBackup, now it's time to run it for the first time in order to verify it works properly.
$ bash /usr/local/omnibackup/backup.sh
The run-time flow of OmniBackup is as follows:
-
OmniBackup starts by looking for its dependencies and initializing its modules through its configuration file. Most
FATAL
errors are identified at this stage. If you get aFATAL
error it terminates with an appropriate message which points you to the root of the issue (usually configuration errors). Otherwise, you should get to the next stage. -
In this step OmniBackup tries to verify the remote backup servers connectivity and cleans-up older backups if it has to. If a connection error happens, OmniBackup ignores the error and continues to the next step. That's because it may be a temporary down-time and the the backup server might be available later.
-
At this stage OmniBackup is ready to proceed with backup tasks. So, it starts the backup tasks in the order that you have specified through the configuration file. It runs each backup task one by one, compress it into an archive file and does the encryption if enabled, finally, uploads it to the backup servers. If an error other than connection errors happen, it leaves the temporary data untouched for your inspection and moves on to the next backup task. So, you have to manually clean-up those files, later on. If a connection problem to a remote server occurs it obeys
.backup.keep_backup_locally
settings. -
In the penultimate step, OmniBackup cleans-up all the temporary files unless there are errors from previous steps.
-
And finally OmniBackup sends reports to the specified list of recipients in the
.reports
section of the configuration file.
Note that in any stage if a FATAL
error happens it tries to first go to clean-up stage and send the reports. But sometimes there's a possibility for FATAL
errors even before OmniBackup initialized successfully so the flow may not work as expected and you may not receive any reports. In such a situation manual inspection is expected.
Moreover, it's possible to interrupt or break the backup operation at any time using Ctrl+C
or SIGTERM
. In such a situation, OmniBackup tries to release it's lock gracefully, but you won't receive any mail reports.
It is highly recommended to learn the fundamentals of configuring cron jobs if you are not familiar with the topic. Anyway, to schedule a backup task as user root
:
$ crontab -e -u root
Then add the backup cron job and make sure the PATH
variable is present with the following values:
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
MAILTO=""
# Order of crontab fields
# minute hour mday month wday command
# OmniBackup
# at 01:00am UTC
00 01 * * * /usr/local/omnibackup/backup.sh
To see whether the cron job was added successfully or not, you can issue the following command:
$ crontab -l -u root
In the above example I scheduled the backup task to run at 01:00 AM
and since the server timezone is UTC it will run at 01:00 AM UTC
each night. To verify whether the backup job runs properly as a cron job or not, it's possible to run OmniBackup with a limited set of environment variables:
$ env -i SHELL=/bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin HOME=/root LOGNAME=Charlie /usr/local/omnibackup/backup.sh
In order to restore anything backed-up by OmniBackup, the initial step is to retrieve the intended archive file from one of the remote backup servers, there are many ways to do so. The easiest that I've found is using scp
command:
$ scp -P {SSH_PORT_NUMBER} {USER_NAME}@{HOST_NAME_OR_IP}:{PATH_TO_FILE} {LOCAL_TEMPORATY_PATH}
e.g.
$ mkdir -p /var/tmp/openldap-restore/
$ scp -P 22 [email protected]:~/backups/blog.babaei.net/openldap-babaei-net/2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.* /var/tmp/openldap-restore/
2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt /var/tmp/openldap-restore 100%
2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt.secret /var/tmp/openldap-restore 100%
2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt.sign /var/tmp/openldap-restore 100%
The above example retrieves three files from the remote server 10.12.0.4
by using wildcard character *, into the directory /var/tmp/openldap-restore
. Since I enabled encryption, I need all those files.
OK, depending on our encryption settings in OmniBackup's configuration file. This step may become a little bit longer or shorter.
If encryption was enabled for our archive file without a public key, OmniBackup gives us two files. They should have .crypt
and .crypt.sum
extensions:
2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt
2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt.sum
If we did provide a public key for a remote server, OmniBackup gives us two more files other than the actual archive file itself on that server with extensions .crypt.secret
and .crypt.sign
but not a .crypt.sum
file:
2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt
2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt.secret
2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt.sign
The next step is to know whether our encrypted archive file is in binary or Base64 encoded format. If we did disable or enabled Base64 encoding at the time of archive creation it should affect all .crypt
, .crypt.secret
and .crypt.sign
files together, so they are all either binary or Base64 encoded. We can use file
utility to distinguish these two formats:
For example if it's Base64 encoded:
$ file 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt
2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt: ASCII text
If it's binary:
$ file 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt
2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt: data
Now, it's time to verify our archive's integrity. If you get only .crypt
and .crypt.sum
files, you can verify the archive integrity this way:
$ cat 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt.sum
SHA512(/var/tmp/backup.2015-07-31.58471/2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt)= 94e4e827f9024df8b547aa48037bc5cef8a851702bb9b7853c8be570c2b6a97de3b0af2e5bca70c15fc94304c44810d747bce6d028f56535dd085e67d3341367
The contents of the .sum
file is nothing more than a hash generated from the contents of our actual archive file. In the above example the chosen hash was SHA-512. So, we have to verify the hash this way:
$ openssl dgst -sha512 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt
SHA512(2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt)= 94e4e827f9024df8b547aa48037bc5cef8a851702bb9b7853c8be570c2b6a97de3b0af2e5bca70c15fc94304c44810d747bce6d028f56535dd085e67d3341367
We've just reproduced the original hash and it looks exactly the same as the archived one which verifies the file integrity. But there is one flaw with encryption without a public key, we cannot be sure that someone else did not change the file and generate their own hash unless we locate the emailed report or log files and check the hash against them.
Anyway, OpenSSL has support for various hash algorithms through the following command-line parameters:
-md4 to use the md4 message digest algorithm
-md5 to use the md5 message digest algorithm
-mdc2 to use the mdc2 message digest algorithm
-ripemd160 to use the ripemd160 message digest algorithm
-sha to use the sha message digest algorithm
-sha1 to use the sha1 message digest algorithm
-sha224 to use the sha224 message digest algorithm
-sha256 to use the sha256 message digest algorithm
-sha384 to use the sha384 message digest algorithm
-sha512 to use the sha512 message digest algorithm
-whirlpool to use the whirlpool message digest algorithm
In addition to that, there are alternative utilities than OpenSSL to regenerate the archive hash. For example, FreeBSD provides md5
, sha1
, sha256
, sha512
and rmd160
, while GNU/Linux provides md5sum
, sha1sum
, sha224sum
, sha256sum
, sha384sum
and sha512sum
utilities to do so. No matter which tool or program you use, the final results must be the same:
$ sha512 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt
SHA512 (2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt) = 94e4e827f9024df8b547aa48037bc5cef8a851702bb9b7853c8be570c2b6a97de3b0af2e5bca70c15fc94304c44810d747bce6d028f56535dd085e67d3341367
OK, let's assume you did provide a public key for the remote backup server that you've just retrieved the archive file from. First, we have to verify the archive file's origin using the public key from OmniBackup's host (the current host). Note that this public key may not be the same as the public key provided by the remote backup server. It's a sibiling to private key in the .security.encryption.private_key
option of OmniBackup configuration file. For the sake of simplicity, from now on I assume you only have a single pair of keys called private.pem
and public.pem
rather than having multiple pair of keys.
OK, the signature file for our example is 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt.sign
. So:
For binary format:
$ openssl rsautl -verify -inkey public.pem -pubin -keyform PEM -in 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt.sign
SHA512(2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt)= 94e4e827f9024df8b547aa48037bc5cef8a851702bb9b7853c8be570c2b6a97de3b0af2e5bca70c15fc94304c44810d747bce6d028f56535dd085e67d3341367
For Base64 encoded format:
$ openssl base64 -d -in 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt.sign | openssl rsautl -verify -inkey public.pem -pubin -keyform PEM
SHA512(2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt)= 94e4e827f9024df8b547aa48037bc5cef8a851702bb9b7853c8be570c2b6a97de3b0af2e5bca70c15fc94304c44810d747bce6d028f56535dd085e67d3341367
If it prints out the archive file checksum in whatever hash format you chose as archive's checksum, then the file origin is valid and OK. From here on, you can verify the archive's integrity as mentioned earlier.
If you did not use a unique password for all of your archives, we should take an extra step to retrieve the passphrase in order to be able to decrypt the archive. If you do not have a .secret
file, you probably did not provide a public key for that server. The only way to retrieve the password is to go through your emails and find the proper report email for that archive and extract the attached password at the end of that report. If you did not allow OmniBackup to attach the passphrases to the email reports, I can only wish you the best of luck. You'll be lost forever! However, if you found it in your reports, it looks something like this depending on your chosen settings in the .security.encryption
area of OmniBackup's configuration file:
[encrypted_archive.crypt](SECRET_PASSPHRASE)
e.g.
[2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt](?PL].]2IFTm*P=M7moy?4OH_VP?i^0T.oN\S04C"k8?RTyeal^H+ZF^ Gz!Ihb;n?_sgADNY-#;Nn:Hs34ybpOSmgd/9,X1Yhv:JkeE]o{Z;|!\@f*VoWo6&lmI|(vzJ)
For those archives that have the .secret
file, there is another way. It's possible to decrypt and extract the passphrase from it's .secret
file using backup server's private key. Of course, it may or may not be different than OmniBackup's private key depending on your choice to use one pair of keys for everything or multiple ones at the time of archive creation. To decrypt the passphrase:
For binary format:
$ openssl base64 -d -in 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt.secret | openssl rsautl -decrypt -inkey private.pem -out 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt.pwd
For Base64 encoded format:
$ openssl rsautl -decrypt -inkey private.pem -in 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt.secret -out 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt.pwd
OK, what we did basically is decrypting and writing the passphrase to a file with .pwd
extension called 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt.pwd
. We decided to write it to a file since it's a random set of characters and it may for example contain spaces at the end which is not distinguishable. However, If you would like to print it on screen instead of a file, it's possible to omit the -out
parameter from openssl
command line.
OK, if you recall your unique passphrase, extracted it from your email or decrypted it from a .secret
file, now its time to decrypt the actual archive, itself.
To decrypt it from binary format, and provide the password from command line
$ openssl enc -aes-256-cbc -d -in 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt -out 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz -k {SECRET_PASSPHRASE} -md sha1
To decrypt it from Base64 format, and provide the password from command line
$ openssl enc -aes-256-cbc -d -a -in 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt -out 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz -k {SECRET_PASSPHRASE} -md sha1
To decrypt it from binary format, and provide the password from a .pwd
file:
$ openssl enc -aes-256-cbc -d -in 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt -out 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz -pass file:"2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt.pwd" -md sha1
To decrypt it from Base64 format, and provide the password from a .pwd
file:
$ openssl enc -aes-256-cbc -d -a -in 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt -out 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz -pass file:"2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt.pwd" -md sha1
Now we've got our achive file 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz.crypt
decrypted as 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz
. For instructions on how to restore it, move to the next section.
If you did not have encryption enabled, you should have a .sum
file along with the archive file to verify archive integrity. Please refer to the previous section in order to find out how to do that.
Depending on how we configured .compression.algorithm
in OmniBackup's configuration file, our archive may have different extensions and formats, therefore requires different decompression algorithms. To decompress and untar our archive file:
LZMA2:
$ tar xvJf 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz
gzip:
$ tar xvzf 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz
bzip2:
$ tar xvjf 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.bz2
No Compression:
$ tar xvf 2015-07-31_blog.babaei.net_openldap-babaei-net..tar
And if you are required to restore the permissions from archive file:
LZMA2:
$ tar xvJpf 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz
gzip
$ tar xvzpf 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.xz
bzip2:
$ tar xvjpf 2015-07-31_blog.babaei.net_openldap-babaei-net.tar.bz2
No Compression:
$ tar xvpf 2015-07-31_blog.babaei.net_openldap-babaei-net.tar
If you would like to extract the archive file in a path other than the current directory:
$ tar {OPTIONS} {ARCHIVE_FILE} -C /path/to/extract/to
After extracting the OpenLDAP archive file, restoring OpenLDAP database is a peace of cake. On my FreeBSD system I do the following (you may want to take a backup from /var/db/openldap-data
first):
$ service slapd stop
$ rm -rf /var/db/openldap-data
$ service slapd start
$ cd 2015-07-31_blog.babaei.net_openldap-babaei-net
$ slapadd -l openldap-babaei-net.ldif
$ slapcat
Be advised that, slapd
service or /var/db/openldap-data
database may have different names or paths on other operating systems.
After extracting the PostgreSQL archive file, if you would like to restore your entire database backup -- named * in the configuration file -- :
$ cd 2015-07-31_blog.babaei.net_postgres
$ sudo -u pgsql psql -f postgres.sql postgres
The overall format for restoring the entire database backup is as follows:
$ sudo -u {PGSQL_SYSTEM_USER} psql -f {DUMPALL_FILE} postgres
If you would like to only restore one database for example named gitlab
:
$ cd 2015-07-31_blog.babaei.net_postgres-gitlab
$ sudo -u pgsql psql gitlab < postgres-gitlab.sql
The overall format for restoring a single database is as follows:
$ sudo -u {PGSQL_SYSTEM_USER} psql {DATABASE_NAME} < {DATABASE_DUMP_FILE}
After extracting the MariaDB or MySQL archive file, if you would like to restore your entire database backup -- named * in the configuration file -- :
$ cd 2015-07-31_blog.babaei.net_mysql
$ mysql -u root -p < mysql.sql
If you would like to only restore one database for example named piwik
:
$ cd cd 2015-07-31_blog.babaei.net_mysql-piwik
$ mysql -u root -p
MariaDB [(none)]> create database piwik;
MariaDB [piwik]> use piwik;
MariaDB [piwik]> source mysql-piwik.sql;
MariaDB [piwik]> \q
Note that in the above examples, root
is not a system user and it's a MariaDB / MySQL internal user who has enough privileges to restore a database.
There’s an old saying “Your data is only as good as your last backup.” That’s very true. But, there’s a little known corollary to this: “Your backups are only as good as your last restore.” It’s great that you’re backing up your databases, but you need to do more. You need to test your backups.
The ultimate test for any backup is a restore to a server, ...
-- Backup Verification: Tips for Database Backup Testing, Grant Fritchey
[Fri Jul 31 01:00:00 UTC 2015] 292 <== INFO 2076 <== This is OmniBackup v0.1.0.
[Fri Jul 31 01:00:00 UTC 2015] 2079 <== Initiating the backup process '/usr/local/omnibackup/backup.sh'...
[Fri Jul 31 01:00:00 UTC 2015] 292 <== INFO 237 <== Found command '/usr/bin/readlink'.
[Fri Jul 31 01:00:00 UTC 2015] 292 <== INFO 237 <== Found command '/usr/bin/dirname'.
[Fri Jul 31 01:00:00 UTC 2015] 292 <== INFO 237 <== Found command '/usr/bin/basename'.
[Fri Jul 31 01:00:00 UTC 2015] 2083 <== Initiating 'Logger' module...
[Fri Jul 31 01:00:00 UTC 2015] 292 <== INFO 237 <== Found command '/bin/echo'.
[Fri Jul 31 01:00:00 UTC 2015] 292 <== INFO 237 <== Found command '/usr/bin/cut'.
[Fri Jul 31 01:00:00 UTC 2015] 292 <== INFO 237 <== Found command '/usr/bin/logger'.
[Fri Jul 31 01:00:00 UTC 2015] 292 <== INFO 2085 <== 'Logger' module initialized successfully.
[Fri Jul 31 01:00:00 UTC 2015] 292 <== INFO 2086 <== Writing logs to '/var/tmp/backup.2015-07-31.58471.log'.
[Fri Jul 31 01:00:00 UTC 2015] 2095 <== Initiating 'Config' module...
[Fri Jul 31 01:00:00 UTC 2015] 292 <== INFO 237 <== Found command '/bin/cat'.
[Fri Jul 31 01:00:00 UTC 2015] 292 <== INFO 237 <== Found command '/usr/local/bin/jq'.
[Fri Jul 31 01:00:00 UTC 2015] 292 <== INFO 2103 <== 'Config' module initialized successfully.
[Fri Jul 31 01:00:00 UTC 2015] 2106 <== Translating status codes to message...
[Fri Jul 31 01:00:01 UTC 2015] 292 <== INFO 2154 <== Successfully translated status codes to message.
[Fri Jul 31 01:00:01 UTC 2015] 2157 <== Initiating 'Clean up' module...
[Fri Jul 31 01:00:01 UTC 2015] 292 <== INFO 237 <== Found command '/bin/mkdir'.
[Fri Jul 31 01:00:01 UTC 2015] 292 <== INFO 237 <== Found command '/bin/rm'.
[Fri Jul 31 01:00:01 UTC 2015] 292 <== INFO 2184 <== Temp directory '/var/tmp/backup.2015-07-31.58471' has been created and ready.
[Fri Jul 31 01:00:01 UTC 2015] 292 <== INFO 2186 <== 'Clean up' module initialized successfully.
[Fri Jul 31 01:00:01 UTC 2015] 2189 <== Initiating 'Reports' module...
[Fri Jul 31 01:00:01 UTC 2015] 292 <== INFO 237 <== Found command '/usr/bin/mail'.
[Fri Jul 31 01:00:01 UTC 2015] 292 <== INFO 237 <== Found command '/usr/bin/printf'.
[Fri Jul 31 01:00:01 UTC 2015] 292 <== INFO 2245 <== 'Reports' module initialized successfully.
[Fri Jul 31 01:00:01 UTC 2015] 292 <== INFO 237 <== Found command '/usr/local/bin/flock'.
[Fri Jul 31 01:00:01 UTC 2015] 2249 <== Trying to acquire the lock '/var/run/omnibackup.lock'...
[Fri Jul 31 01:00:01 UTC 2015] 292 <== INFO 2253 <== Successfully acquired the lock.
[Fri Jul 31 01:00:01 UTC 2015] 2259 <== Initiating 'Compression' module...
[Fri Jul 31 01:00:01 UTC 2015] 292 <== INFO 237 <== Found command '/usr/bin/tar'.
[Fri Jul 31 01:00:01 UTC 2015] 292 <== INFO 237 <== Found command '/usr/bin/xz'.
[Fri Jul 31 01:00:01 UTC 2015] 292 <== INFO 2341 <== 'Compression' module initialized successfully.
[Fri Jul 31 01:00:01 UTC 2015] 2344 <== Initiating 'Security' module...
[Fri Jul 31 01:00:01 UTC 2015] 292 <== INFO 237 <== Found command '/usr/bin/grep'.
[Fri Jul 31 01:00:01 UTC 2015] 292 <== INFO 237 <== Found command '/usr/bin/head'.
[Fri Jul 31 01:00:01 UTC 2015] 292 <== INFO 237 <== Found command '/usr/bin/strings'.
[Fri Jul 31 01:00:01 UTC 2015] 292 <== INFO 237 <== Found command '/usr/bin/tr'.
[Fri Jul 31 01:00:01 UTC 2015] 292 <== INFO 237 <== Found command '/usr/bin/openssl'.
[Fri Jul 31 01:00:01 UTC 2015] 292 <== INFO 2411 <== 'Security' module initialized successfully.
[Fri Jul 31 01:00:01 UTC 2015] 2414 <== Initiating 'Remote' module...
[Fri Jul 31 01:00:01 UTC 2015] 292 <== INFO 237 <== Found command '/usr/bin/du'.
[Fri Jul 31 01:00:02 UTC 2015] 292 <== INFO 237 <== Found command '/bin/expr'.
[Fri Jul 31 01:00:02 UTC 2015] 292 <== INFO 237 <== Found command '/usr/bin/scp'.
[Fri Jul 31 01:00:02 UTC 2015] 292 <== INFO 237 <== Found command '/usr/bin/ssh'.
[Fri Jul 31 01:00:02 UTC 2015] 292 <== INFO 2493 <== 'Remote' module initialized successfully.
[Fri Jul 31 01:00:02 UTC 2015] 2496 <== Initiating 'Backup' module...
[Fri Jul 31 01:00:02 UTC 2015] 2581 <== Initiating 'Database dump' module...
[Fri Jul 31 01:00:02 UTC 2015] 2639 <== Initiating 'PostgreSQL dump' module...
[Fri Jul 31 01:00:02 UTC 2015] 292 <== INFO 237 <== Found command '/usr/local/bin/sudo'.
[Fri Jul 31 01:00:02 UTC 2015] 292 <== INFO 237 <== Found command '/usr/local/bin/pg_dump'.
[Fri Jul 31 01:00:02 UTC 2015] 292 <== INFO 237 <== Found command '/usr/local/bin/pg_dumpall'.
[Fri Jul 31 01:00:02 UTC 2015] 292 <== INFO 2703 <== 'PostgreSQL dump' module initialized successfully.
[Fri Jul 31 01:00:02 UTC 2015] 2712 <== Initiating 'MySQL/MariaDB dump' module...
[Fri Jul 31 01:00:02 UTC 2015] 292 <== INFO 237 <== Found command '/usr/local/bin/mysqldump'.
[Fri Jul 31 01:00:02 UTC 2015] 292 <== INFO 2776 <== 'MariaDB/MySQL dump' module initialized successfully.
[Fri Jul 31 01:00:02 UTC 2015] 292 <== INFO 2780 <== 'Database dump' module initialized successfully.
[Fri Jul 31 01:00:02 UTC 2015] 2790 <== Initiating 'Filesystem backup' module...
[Fri Jul 31 01:00:02 UTC 2015] 292 <== INFO 2853 <== 'Filesystem backup' module initialized successfully.
[Fri Jul 31 01:00:02 UTC 2015] 292 <== INFO 2993 <== 'Backup' module initialized successfully.
[Fri Jul 31 01:00:02 UTC 2015] 3039 <== Checking if '[email protected]:203/~/backups/core.babaei.net' exists...
[Fri Jul 31 01:00:03 UTC 2015] 3052 <== Cleaning up old backups at '[email protected]:203/~/backups/core.babaei.net'...
[Fri Jul 31 01:00:03 UTC 2015] 3062 <== Cleaning up '[email protected]:203/~/backups/core.babaei.net/etc-ports/'...
[Fri Jul 31 01:00:03 UTC 2015] 3062 <== Cleaning up '[email protected]:203/~/backups/core.babaei.net/etc-system/'...
[Fri Jul 31 01:00:04 UTC 2015] 3062 <== Cleaning up '[email protected]:203/~/backups/core.babaei.net/loader-conf/'...
[Fri Jul 31 01:00:04 UTC 2015] 3062 <== Cleaning up '[email protected]:203/~/backups/core.babaei.net/mail/'...
[Fri Jul 31 01:00:04 UTC 2015] 3062 <== Cleaning up '[email protected]:203/~/backups/core.babaei.net/mysql-piwik/'...
[Fri Jul 31 01:00:05 UTC 2015] 3062 <== Cleaning up '[email protected]:203/~/backups/core.babaei.net/mysql/'...
[Fri Jul 31 01:00:05 UTC 2015] 3062 <== Cleaning up '[email protected]:203/~/backups/core.babaei.net/postgres-gitlab/'...
[Fri Jul 31 01:00:05 UTC 2015] 3062 <== Cleaning up '[email protected]:203/~/backups/core.babaei.net/postgres-owncloud/'...
[Fri Jul 31 01:00:06 UTC 2015] 3062 <== Cleaning up '[email protected]:203/~/backups/core.babaei.net/postgres-redmine/'...
[Fri Jul 31 01:00:06 UTC 2015] 3062 <== Cleaning up '[email protected]:203/~/backups/core.babaei.net/postgres/'...
[Fri Jul 31 01:00:06 UTC 2015] 3062 <== Cleaning up '[email protected]:203/~/backups/core.babaei.net/repos/'...
[Fri Jul 31 01:00:06 UTC 2015] 3062 <== Cleaning up '[email protected]:203/~/backups/core.babaei.net/www/'...
[Fri Jul 31 01:00:07 UTC 2015] 1853 <== Creating a backup from 'All PostgreSQL databases'...
[Fri Jul 31 01:00:07 UTC 2015] 1867 <== Dumping 'postgres::'*'' to '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres/postgres.sql'...
[Fri Jul 31 01:00:08 UTC 2015] 1463 <== Creating archive '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres.tar.xz'...
[Fri Jul 31 01:00:08 UTC 2015] 1474 <== Removing '2015-07-31_core.babaei.net_postgres'...
[Fri Jul 31 01:00:08 UTC 2015] 1493 <== Generating a random passphrase for '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres.tar.xz'...
[Fri Jul 31 01:00:08 UTC 2015] 1542 <== Encrypting '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres.tar.xz'...
[Fri Jul 31 01:00:08 UTC 2015] 1552 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres.tar.xz'...
[Fri Jul 31 01:00:08 UTC 2015] 1562 <== Generating archive checksum '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres.tar.xz.crypt.sum'...
[Fri Jul 31 01:00:08 UTC 2015] 1581 <== SHA512(/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres.tar.xz.crypt)= 0d4caeb42692dbb5595df82b53c3ff3d14687525eca8ca153470b18aea4b8e8922968e561def455968923772b8886660d91a398838cc4a307a4a0e5513d3dab5
[Fri Jul 31 01:00:08 UTC 2015] 1647 <== Uploading 'All PostgreSQL databases'...
[Fri Jul 31 01:00:08 UTC 2015] 1268 <== Checking if '[email protected]:203/~/backups/core.babaei.net/postgres/2015-07-31' exists...
[Fri Jul 31 01:00:09 UTC 2015] 1275 <== Creating '[email protected]:203/~/backups/core.babaei.net/postgres/2015-07-31'
[Fri Jul 31 01:00:09 UTC 2015] 1295 <== Uploading to '[email protected]:203/~/backups/core.babaei.net/postgres/2015-07-31'...
[Fri Jul 31 01:00:09 UTC 2015] 1300 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres.tar.xz.crypt'... ~ 56K
[Fri Jul 31 01:00:09 UTC 2015] 1370 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres.tar.xz.crypt.sum'... ~ 4.0K
[Fri Jul 31 01:00:10 UTC 2015] 1690 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres.tar.xz.crypt.sum'...
[Fri Jul 31 01:00:10 UTC 2015] 1696 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres.tar.xz.crypt'...
[Fri Jul 31 01:00:10 UTC 2015] 1708 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres.tar.xz.key'...
[Fri Jul 31 01:00:10 UTC 2015] 300 <== SUCCESS 1878 <== 'All PostgreSQL databases' backup completed successfully.
[Fri Jul 31 01:00:10 UTC 2015] 1853 <== Creating a backup from 'GitLab database'...
[Fri Jul 31 01:00:10 UTC 2015] 1867 <== Dumping 'postgres::gitlabhq_production' to '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-gitlab/postgres-gitlab.sql'...
[Fri Jul 31 01:00:10 UTC 2015] 1463 <== Creating archive '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-gitlab.tar.xz'...
[Fri Jul 31 01:00:10 UTC 2015] 1474 <== Removing '2015-07-31_core.babaei.net_postgres-gitlab'...
[Fri Jul 31 01:00:10 UTC 2015] 1493 <== Generating a random passphrase for '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-gitlab.tar.xz'...
[Fri Jul 31 01:00:10 UTC 2015] 1542 <== Encrypting '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-gitlab.tar.xz'...
[Fri Jul 31 01:00:10 UTC 2015] 1552 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-gitlab.tar.xz'...
[Fri Jul 31 01:00:10 UTC 2015] 1562 <== Generating archive checksum '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-gitlab.tar.xz.crypt.sum'...
[Fri Jul 31 01:00:10 UTC 2015] 1581 <== SHA512(/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-gitlab.tar.xz.crypt)= 94e4e827f9024df8b547aa48037bc5cef8a851702bb9b7853c8be570c2b6a97de3b0af2e5bca70c15fc94304c44810d747bce6d028f56535dd085e67d3341367
[Fri Jul 31 01:00:10 UTC 2015] 1647 <== Uploading 'GitLab database'...
[Fri Jul 31 01:00:10 UTC 2015] 1268 <== Checking if '[email protected]:203/~/backups/core.babaei.net/postgres-gitlab/2015-07-31' exists...
[Fri Jul 31 01:00:11 UTC 2015] 1275 <== Creating '[email protected]:203/~/backups/core.babaei.net/postgres-gitlab/2015-07-31'
[Fri Jul 31 01:00:11 UTC 2015] 1295 <== Uploading to '[email protected]:203/~/backups/core.babaei.net/postgres-gitlab/2015-07-31'...
[Fri Jul 31 01:00:11 UTC 2015] 1300 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-gitlab.tar.xz.crypt'... ~ 32K
[Fri Jul 31 01:00:11 UTC 2015] 1370 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-gitlab.tar.xz.crypt.sum'... ~ 4.0K
[Fri Jul 31 01:00:11 UTC 2015] 1690 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-gitlab.tar.xz.crypt.sum'...
[Fri Jul 31 01:00:11 UTC 2015] 1696 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-gitlab.tar.xz.crypt'...
[Fri Jul 31 01:00:11 UTC 2015] 1708 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-gitlab.tar.xz.key'...
[Fri Jul 31 01:00:11 UTC 2015] 300 <== SUCCESS 1878 <== 'GitLab database' backup completed successfully.
[Fri Jul 31 01:00:11 UTC 2015] 1853 <== Creating a backup from 'Redmine database'...
[Fri Jul 31 01:00:11 UTC 2015] 1867 <== Dumping 'postgres::redmine' to '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-redmine/postgres-redmine.sql'...
[Fri Jul 31 01:00:12 UTC 2015] 1463 <== Creating archive '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-redmine.tar.xz'...
[Fri Jul 31 01:00:12 UTC 2015] 1474 <== Removing '2015-07-31_core.babaei.net_postgres-redmine'...
[Fri Jul 31 01:00:12 UTC 2015] 1493 <== Generating a random passphrase for '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-redmine.tar.xz'...
[Fri Jul 31 01:00:12 UTC 2015] 1542 <== Encrypting '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-redmine.tar.xz'...
[Fri Jul 31 01:00:12 UTC 2015] 1552 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-redmine.tar.xz'...
[Fri Jul 31 01:00:12 UTC 2015] 1562 <== Generating archive checksum '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-redmine.tar.xz.crypt.sum'...
[Fri Jul 31 01:00:12 UTC 2015] 1581 <== SHA512(/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-redmine.tar.xz.crypt)= 13edd1c5bf9cd70f172f9daf5dd632661a8c228cd310086001afeae3f1bc71cdc2de1af69423f5d645d13b09fff68455e80400880d8523a74794b41acfb346e1
[Fri Jul 31 01:00:12 UTC 2015] 1647 <== Uploading 'Redmine database'...
[Fri Jul 31 01:00:12 UTC 2015] 1268 <== Checking if '[email protected]:203/~/backups/core.babaei.net/postgres-redmine/2015-07-31' exists...
[Fri Jul 31 01:00:12 UTC 2015] 1275 <== Creating '[email protected]:203/~/backups/core.babaei.net/postgres-redmine/2015-07-31'
[Fri Jul 31 01:00:13 UTC 2015] 1295 <== Uploading to '[email protected]:203/~/backups/core.babaei.net/postgres-redmine/2015-07-31'...
[Fri Jul 31 01:00:13 UTC 2015] 1300 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-redmine.tar.xz.crypt'... ~ 16K
[Fri Jul 31 01:00:13 UTC 2015] 1370 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-redmine.tar.xz.crypt.sum'... ~ 4.0K
[Fri Jul 31 01:00:13 UTC 2015] 1690 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-redmine.tar.xz.crypt.sum'...
[Fri Jul 31 01:00:13 UTC 2015] 1696 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-redmine.tar.xz.crypt'...
[Fri Jul 31 01:00:13 UTC 2015] 1708 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-redmine.tar.xz.key'...
[Fri Jul 31 01:00:13 UTC 2015] 300 <== SUCCESS 1878 <== 'Redmine database' backup completed successfully.
[Fri Jul 31 01:00:13 UTC 2015] 1853 <== Creating a backup from 'ownCloud database'...
[Fri Jul 31 01:00:13 UTC 2015] 1867 <== Dumping 'postgres::owncloud_db' to '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-owncloud/postgres-owncloud.sql'...
[Fri Jul 31 01:00:13 UTC 2015] 1463 <== Creating archive '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-owncloud.tar.xz'...
[Fri Jul 31 01:00:13 UTC 2015] 1474 <== Removing '2015-07-31_core.babaei.net_postgres-owncloud'...
[Fri Jul 31 01:00:13 UTC 2015] 1493 <== Generating a random passphrase for '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-owncloud.tar.xz'...
[Fri Jul 31 01:00:13 UTC 2015] 1542 <== Encrypting '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-owncloud.tar.xz'...
[Fri Jul 31 01:00:13 UTC 2015] 1552 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-owncloud.tar.xz'...
[Fri Jul 31 01:00:14 UTC 2015] 1562 <== Generating archive checksum '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-owncloud.tar.xz.crypt.sum'...
[Fri Jul 31 01:00:14 UTC 2015] 1581 <== SHA512(/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-owncloud.tar.xz.crypt)= 143e7c0242414dfd56a405ad96ee8261330a73a16d50c27003bb07a610fb4819422791ab40a7acb4d210d650e8ed526d4202f99f6729c2ba441a7b10e25d7f02
[Fri Jul 31 01:00:14 UTC 2015] 1647 <== Uploading 'ownCloud database'...
[Fri Jul 31 01:00:14 UTC 2015] 1268 <== Checking if '[email protected]:203/~/backups/core.babaei.net/postgres-owncloud/2015-07-31' exists...
[Fri Jul 31 01:00:14 UTC 2015] 1275 <== Creating '[email protected]:203/~/backups/core.babaei.net/postgres-owncloud/2015-07-31'
[Fri Jul 31 01:00:14 UTC 2015] 1295 <== Uploading to '[email protected]:203/~/backups/core.babaei.net/postgres-owncloud/2015-07-31'...
[Fri Jul 31 01:00:14 UTC 2015] 1300 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-owncloud.tar.xz.crypt'... ~ 16K
[Fri Jul 31 01:00:14 UTC 2015] 1370 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-owncloud.tar.xz.crypt.sum'... ~ 4.0K
[Fri Jul 31 01:00:15 UTC 2015] 1690 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-owncloud.tar.xz.crypt.sum'...
[Fri Jul 31 01:00:15 UTC 2015] 1696 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-owncloud.tar.xz.crypt'...
[Fri Jul 31 01:00:15 UTC 2015] 1708 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_postgres-owncloud.tar.xz.key'...
[Fri Jul 31 01:00:15 UTC 2015] 300 <== SUCCESS 1878 <== 'ownCloud database' backup completed successfully.
[Fri Jul 31 01:00:15 UTC 2015] 1853 <== Creating a backup from 'All MySQL databases'...
[Fri Jul 31 01:00:15 UTC 2015] 1867 <== Dumping 'mysql::'*'' to '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql/mysql.sql'...
[Fri Jul 31 01:00:16 UTC 2015] 1463 <== Creating archive '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql.tar.xz'...
[Fri Jul 31 01:01:01 UTC 2015] 1474 <== Removing '2015-07-31_core.babaei.net_mysql'...
[Fri Jul 31 01:01:02 UTC 2015] 1493 <== Generating a random passphrase for '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql.tar.xz'...
[Fri Jul 31 01:01:03 UTC 2015] 1542 <== Encrypting '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql.tar.xz'...
[Fri Jul 31 01:01:03 UTC 2015] 1552 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql.tar.xz'...
[Fri Jul 31 01:01:03 UTC 2015] 1562 <== Generating archive checksum '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql.tar.xz.crypt.sum'...
[Fri Jul 31 01:01:04 UTC 2015] 1581 <== SHA512(/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql.tar.xz.crypt)= 9e7c0f0fb5d4ace5cc6727ed0c1b70ca477b878c75c8fcc8cb42b43ccfe72f497ba3c78304d6767a7802420dab73edcffc19f8ba171a0e33dd696abc28bc5e38
[Fri Jul 31 01:01:04 UTC 2015] 1647 <== Uploading 'All MySQL databases'...
[Fri Jul 31 01:01:04 UTC 2015] 1268 <== Checking if '[email protected]:203/~/backups/core.babaei.net/mysql/2015-07-31' exists...
[Fri Jul 31 01:01:04 UTC 2015] 1275 <== Creating '[email protected]:203/~/backups/core.babaei.net/mysql/2015-07-31'
[Fri Jul 31 01:01:04 UTC 2015] 1295 <== Uploading to '[email protected]:203/~/backups/core.babaei.net/mysql/2015-07-31'...
[Fri Jul 31 01:01:04 UTC 2015] 1300 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql.tar.xz.crypt'... ~ 11M
[Fri Jul 31 01:01:05 UTC 2015] 1370 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql.tar.xz.crypt.sum'... ~ 4.0K
[Fri Jul 31 01:01:05 UTC 2015] 1690 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql.tar.xz.crypt.sum'...
[Fri Jul 31 01:01:05 UTC 2015] 1696 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql.tar.xz.crypt'...
[Fri Jul 31 01:01:05 UTC 2015] 1708 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql.tar.xz.key'...
[Fri Jul 31 01:01:05 UTC 2015] 300 <== SUCCESS 1878 <== 'All MySQL databases' backup completed successfully.
[Fri Jul 31 01:01:05 UTC 2015] 1853 <== Creating a backup from 'Piwik database'...
[Fri Jul 31 01:01:05 UTC 2015] 1867 <== Dumping 'mysql::piwik' to '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql-piwik/mysql-piwik.sql'...
[Fri Jul 31 01:01:06 UTC 2015] 1463 <== Creating archive '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql-piwik.tar.xz'...
[Fri Jul 31 01:01:50 UTC 2015] 1474 <== Removing '2015-07-31_core.babaei.net_mysql-piwik'...
[Fri Jul 31 01:01:50 UTC 2015] 1493 <== Generating a random passphrase for '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql-piwik.tar.xz'...
[Fri Jul 31 01:01:50 UTC 2015] 1542 <== Encrypting '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql-piwik.tar.xz'...
[Fri Jul 31 01:01:51 UTC 2015] 1552 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql-piwik.tar.xz'...
[Fri Jul 31 01:01:51 UTC 2015] 1562 <== Generating archive checksum '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql-piwik.tar.xz.crypt.sum'...
[Fri Jul 31 01:01:51 UTC 2015] 1581 <== SHA512(/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql-piwik.tar.xz.crypt)= aa90141fe55f5543622887ae81c6911e8663af6fbc57ea8336564481c3d261e4e9ce4ee6425936b7f67996cbf4d546b8ab76f92b1301f19ab19167b8a2ce1889
[Fri Jul 31 01:01:51 UTC 2015] 1647 <== Uploading 'Piwik database'...
[Fri Jul 31 01:01:51 UTC 2015] 1268 <== Checking if '[email protected]:203/~/backups/core.babaei.net/mysql-piwik/2015-07-31' exists...
[Fri Jul 31 01:01:51 UTC 2015] 1275 <== Creating '[email protected]:203/~/backups/core.babaei.net/mysql-piwik/2015-07-31'
[Fri Jul 31 01:01:51 UTC 2015] 1295 <== Uploading to '[email protected]:203/~/backups/core.babaei.net/mysql-piwik/2015-07-31'...
[Fri Jul 31 01:01:51 UTC 2015] 1300 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql-piwik.tar.xz.crypt'... ~ 10M
[Fri Jul 31 01:01:52 UTC 2015] 1370 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql-piwik.tar.xz.crypt.sum'... ~ 4.0K
[Fri Jul 31 01:01:52 UTC 2015] 1690 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql-piwik.tar.xz.crypt.sum'...
[Fri Jul 31 01:01:52 UTC 2015] 1696 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql-piwik.tar.xz.crypt'...
[Fri Jul 31 01:01:52 UTC 2015] 1708 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mysql-piwik.tar.xz.key'...
[Fri Jul 31 01:01:52 UTC 2015] 300 <== SUCCESS 1878 <== 'Piwik database' backup completed successfully.
[Fri Jul 31 01:01:54 UTC 2015] 292 <== INFO 1921 <== All database backup tasks finished.
[Fri Jul 31 01:01:54 UTC 2015] 1955 <== Creating a backup from 'Web server root directory'...
[Fri Jul 31 01:01:54 UTC 2015] 1463 <== Creating archive '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_www.tar.xz'...
[Fri Jul 31 01:31:02 UTC 2015] 1493 <== Generating a random passphrase for '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_www.tar.xz'...
[Fri Jul 31 01:31:02 UTC 2015] 1542 <== Encrypting '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_www.tar.xz'...
[Fri Jul 31 01:31:23 UTC 2015] 1552 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_www.tar.xz'...
[Fri Jul 31 01:31:23 UTC 2015] 1562 <== Generating archive checksum '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_www.tar.xz.crypt.sum'...
[Fri Jul 31 01:31:35 UTC 2015] 1581 <== SHA512(/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_www.tar.xz.crypt)= 9c068d61717ac52f48489842d1c04ad52abbbabbe181cd0aa9e1f291c2108eea336a0d8b239a0a37987fddf8868c40869f80e5af5e5d9c79114deb4a3de8d1fc
[Fri Jul 31 01:31:35 UTC 2015] 1647 <== Uploading 'Web server root directory'...
[Fri Jul 31 01:31:35 UTC 2015] 1268 <== Checking if '[email protected]:203/~/backups/core.babaei.net/www/2015-07-31' exists...
[Fri Jul 31 01:31:36 UTC 2015] 1275 <== Creating '[email protected]:203/~/backups/core.babaei.net/www/2015-07-31'
[Fri Jul 31 01:31:36 UTC 2015] 1295 <== Uploading to '[email protected]:203/~/backups/core.babaei.net/www/2015-07-31'...
[Fri Jul 31 01:31:36 UTC 2015] 1300 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_www.tar.xz.crypt'... ~ 1.4G
[Fri Jul 31 01:32:19 UTC 2015] 1370 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_www.tar.xz.crypt.sum'... ~ 4.0K
[Fri Jul 31 01:32:19 UTC 2015] 1690 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_www.tar.xz.crypt.sum'...
[Fri Jul 31 01:32:19 UTC 2015] 1696 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_www.tar.xz.crypt'...
[Fri Jul 31 01:32:19 UTC 2015] 1708 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_www.tar.xz.key'...
[Fri Jul 31 01:32:19 UTC 2015] 300 <== SUCCESS 1962 <== 'Web server root directory' backup completed successfully.
[Fri Jul 31 01:32:19 UTC 2015] 1955 <== Creating a backup from 'GitLab repositories'...
[Fri Jul 31 01:32:19 UTC 2015] 1463 <== Creating archive '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_repos.tar.xz'...
[Fri Jul 31 01:52:40 UTC 2015] 1493 <== Generating a random passphrase for '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_repos.tar.xz'...
[Fri Jul 31 01:52:40 UTC 2015] 1542 <== Encrypting '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_repos.tar.xz'...
[Fri Jul 31 01:52:55 UTC 2015] 1552 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_repos.tar.xz'...
[Fri Jul 31 01:52:55 UTC 2015] 1562 <== Generating archive checksum '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_repos.tar.xz.crypt.sum'...
[Fri Jul 31 01:53:03 UTC 2015] 1581 <== SHA512(/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_repos.tar.xz.crypt)= 88036dac6d9c5d636a7e31ce0b2303f48f41cc9188f31543f3a964107ab4f364756352cd7320c0471fbbb37068cdfdd1ac0d9b56e8902b82b40754de082a3d4a
[Fri Jul 31 01:53:03 UTC 2015] 1647 <== Uploading 'GitLab repositories'...
[Fri Jul 31 01:53:03 UTC 2015] 1268 <== Checking if '[email protected]:203/~/backups/core.babaei.net/repos/2015-07-31' exists...
[Fri Jul 31 01:53:03 UTC 2015] 1275 <== Creating '[email protected]:203/~/backups/core.babaei.net/repos/2015-07-31'
[Fri Jul 31 01:53:03 UTC 2015] 1295 <== Uploading to '[email protected]:203/~/backups/core.babaei.net/repos/2015-07-31'...
[Fri Jul 31 01:53:03 UTC 2015] 1300 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_repos.tar.xz.crypt'... ~ 1.1G
[Fri Jul 31 01:53:31 UTC 2015] 1370 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_repos.tar.xz.crypt.sum'... ~ 4.0K
[Fri Jul 31 01:53:32 UTC 2015] 1690 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_repos.tar.xz.crypt.sum'...
[Fri Jul 31 01:53:32 UTC 2015] 1696 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_repos.tar.xz.crypt'...
[Fri Jul 31 01:53:32 UTC 2015] 1708 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_repos.tar.xz.key'...
[Fri Jul 31 01:53:32 UTC 2015] 300 <== SUCCESS 1962 <== 'GitLab repositories' backup completed successfully.
[Fri Jul 31 01:53:32 UTC 2015] 1955 <== Creating a backup from 'Mail server root directory'...
[Fri Jul 31 01:53:32 UTC 2015] 1463 <== Creating archive '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mail.tar.xz'...
[Fri Jul 31 02:21:44 UTC 2015] 1493 <== Generating a random passphrase for '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mail.tar.xz'...
[Fri Jul 31 02:21:44 UTC 2015] 1542 <== Encrypting '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mail.tar.xz'...
[Fri Jul 31 02:21:57 UTC 2015] 1552 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mail.tar.xz'...
[Fri Jul 31 02:21:57 UTC 2015] 1562 <== Generating archive checksum '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mail.tar.xz.crypt.sum'...
[Fri Jul 31 02:22:04 UTC 2015] 1581 <== SHA512(/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mail.tar.xz.crypt)= 2b28e978f74ff857deb0643fc5f1dbf7b6c50acec3f919cebf672c9038ec365a06a7ddd2c80c5e28b7cecff9b2d659ab9dde4e9ad606d3d7e4d1819284cb19b8
[Fri Jul 31 02:22:04 UTC 2015] 1647 <== Uploading 'Mail server root directory'...
[Fri Jul 31 02:22:04 UTC 2015] 1268 <== Checking if '[email protected]:203/~/backups/core.babaei.net/mail/2015-07-31' exists...
[Fri Jul 31 02:22:05 UTC 2015] 1275 <== Creating '[email protected]:203/~/backups/core.babaei.net/mail/2015-07-31'
[Fri Jul 31 02:22:05 UTC 2015] 1295 <== Uploading to '[email protected]:203/~/backups/core.babaei.net/mail/2015-07-31'...
[Fri Jul 31 02:22:05 UTC 2015] 1300 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mail.tar.xz.crypt'... ~ 1.2G
[Fri Jul 31 02:22:44 UTC 2015] 1370 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mail.tar.xz.crypt.sum'... ~ 4.0K
[Fri Jul 31 02:22:44 UTC 2015] 1690 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mail.tar.xz.crypt.sum'...
[Fri Jul 31 02:22:44 UTC 2015] 1696 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mail.tar.xz.crypt'...
[Fri Jul 31 02:22:44 UTC 2015] 1708 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_mail.tar.xz.key'...
[Fri Jul 31 02:22:44 UTC 2015] 300 <== SUCCESS 1962 <== 'Mail server root directory' backup completed successfully.
[Fri Jul 31 02:22:44 UTC 2015] 1955 <== Creating a backup from 'Base system configurations'...
[Fri Jul 31 02:22:44 UTC 2015] 1463 <== Creating archive '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-system.tar.xz'...
[Fri Jul 31 02:22:47 UTC 2015] 1493 <== Generating a random passphrase for '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-system.tar.xz'...
[Fri Jul 31 02:22:48 UTC 2015] 1542 <== Encrypting '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-system.tar.xz'...
[Fri Jul 31 02:22:48 UTC 2015] 1552 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-system.tar.xz'...
[Fri Jul 31 02:22:48 UTC 2015] 1562 <== Generating archive checksum '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-system.tar.xz.crypt.sum'...
[Fri Jul 31 02:22:48 UTC 2015] 1581 <== SHA512(/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-system.tar.xz.crypt)= bdfca0fb8bad158780368589da43b0ccc86bfc6f7aa089f615714eb09308854328b9ae8699c267688b50e2fd99aee8fcc1d43054488beae3b1410769f2858422
[Fri Jul 31 02:22:48 UTC 2015] 1647 <== Uploading 'Base system configurations'...
[Fri Jul 31 02:22:48 UTC 2015] 1268 <== Checking if '[email protected]:203/~/backups/core.babaei.net/etc-system/2015-07-31' exists...
[Fri Jul 31 02:22:48 UTC 2015] 1275 <== Creating '[email protected]:203/~/backups/core.babaei.net/etc-system/2015-07-31'
[Fri Jul 31 02:22:48 UTC 2015] 1295 <== Uploading to '[email protected]:203/~/backups/core.babaei.net/etc-system/2015-07-31'...
[Fri Jul 31 02:22:48 UTC 2015] 1300 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-system.tar.xz.crypt'... ~ 304K
[Fri Jul 31 02:22:49 UTC 2015] 1370 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-system.tar.xz.crypt.sum'... ~ 4.0K
[Fri Jul 31 02:22:49 UTC 2015] 1690 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-system.tar.xz.crypt.sum'...
[Fri Jul 31 02:22:49 UTC 2015] 1696 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-system.tar.xz.crypt'...
[Fri Jul 31 02:22:49 UTC 2015] 1708 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-system.tar.xz.key'...
[Fri Jul 31 02:22:49 UTC 2015] 300 <== SUCCESS 1962 <== 'Base system configurations' backup completed successfully.
[Fri Jul 31 02:22:49 UTC 2015] 1955 <== Creating a backup from 'Installed ports configurations'...
[Fri Jul 31 02:22:49 UTC 2015] 1463 <== Creating archive '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-ports.tar.xz'...
[Fri Jul 31 02:22:53 UTC 2015] 1493 <== Generating a random passphrase for '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-ports.tar.xz'...
[Fri Jul 31 02:22:53 UTC 2015] 1542 <== Encrypting '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-ports.tar.xz'...
[Fri Jul 31 02:22:53 UTC 2015] 1552 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-ports.tar.xz'...
[Fri Jul 31 02:22:53 UTC 2015] 1562 <== Generating archive checksum '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-ports.tar.xz.crypt.sum'...
[Fri Jul 31 02:22:53 UTC 2015] 1581 <== SHA512(/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-ports.tar.xz.crypt)= 0df1727a77395ae4346fd9f257451fd9976bc6a2933c209c8daf8aa655834a6f6c472764d067703c954f4963ee2f0f4b585c565de48f4c42aa216204971c7b2e
[Fri Jul 31 02:22:53 UTC 2015] 1647 <== Uploading 'Installed ports configurations'...
[Fri Jul 31 02:22:53 UTC 2015] 1268 <== Checking if '[email protected]:203/~/backups/core.babaei.net/etc-ports/2015-07-31' exists...
[Fri Jul 31 02:22:53 UTC 2015] 1275 <== Creating '[email protected]:203/~/backups/core.babaei.net/etc-ports/2015-07-31'
[Fri Jul 31 02:22:54 UTC 2015] 1295 <== Uploading to '[email protected]:203/~/backups/core.babaei.net/etc-ports/2015-07-31'...
[Fri Jul 31 02:22:54 UTC 2015] 1300 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-ports.tar.xz.crypt'... ~ 640K
[Fri Jul 31 02:22:54 UTC 2015] 1370 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-ports.tar.xz.crypt.sum'... ~ 4.0K
[Fri Jul 31 02:22:54 UTC 2015] 1690 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-ports.tar.xz.crypt.sum'...
[Fri Jul 31 02:22:54 UTC 2015] 1696 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-ports.tar.xz.crypt'...
[Fri Jul 31 02:22:54 UTC 2015] 1708 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_etc-ports.tar.xz.key'...
[Fri Jul 31 02:22:54 UTC 2015] 300 <== SUCCESS 1962 <== 'Installed ports configurations' backup completed successfully.
[Fri Jul 31 02:22:54 UTC 2015] 1955 <== Creating a backup from 'System bootstrap configuration information'...
[Fri Jul 31 02:22:54 UTC 2015] 1463 <== Creating archive '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_loader-conf.tar.xz'...
[Fri Jul 31 02:22:54 UTC 2015] 1493 <== Generating a random passphrase for '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_loader-conf.tar.xz'...
[Fri Jul 31 02:22:54 UTC 2015] 1542 <== Encrypting '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_loader-conf.tar.xz'...
[Fri Jul 31 02:22:54 UTC 2015] 1552 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_loader-conf.tar.xz'...
[Fri Jul 31 02:22:54 UTC 2015] 1562 <== Generating archive checksum '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_loader-conf.tar.xz.crypt.sum'...
[Fri Jul 31 02:22:54 UTC 2015] 1581 <== SHA512(/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_loader-conf.tar.xz.crypt)= d6900b1cb7cd3277eb15d5c80c01dd7b937fd002d66d4c0d1b0e40acfcc90acffc8a3c41a73761c21574b79fed0e8e904e59d71ea512e928cb3079ab75aa7e7c
[Fri Jul 31 02:22:55 UTC 2015] 1647 <== Uploading 'System bootstrap configuration information'...
[Fri Jul 31 02:22:55 UTC 2015] 1268 <== Checking if '[email protected]:203/~/backups/core.babaei.net/loader-conf/2015-07-31' exists...
[Fri Jul 31 02:22:55 UTC 2015] 1275 <== Creating '[email protected]:203/~/backups/core.babaei.net/loader-conf/2015-07-31'
[Fri Jul 31 02:22:55 UTC 2015] 1295 <== Uploading to '[email protected]:203/~/backups/core.babaei.net/loader-conf/2015-07-31'...
[Fri Jul 31 02:22:55 UTC 2015] 1300 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_loader-conf.tar.xz.crypt'... ~ 4.0K
[Fri Jul 31 02:22:55 UTC 2015] 1370 <== Uploading '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_loader-conf.tar.xz.crypt.sum'... ~ 4.0K
[Fri Jul 31 02:22:56 UTC 2015] 1690 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_loader-conf.tar.xz.crypt.sum'...
[Fri Jul 31 02:22:56 UTC 2015] 1696 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_loader-conf.tar.xz.crypt'...
[Fri Jul 31 02:22:56 UTC 2015] 1708 <== Removing '/var/tmp/backup.2015-07-31.58471/2015-07-31_core.babaei.net_loader-conf.tar.xz.key'...
[Fri Jul 31 02:22:56 UTC 2015] 300 <== SUCCESS 1962 <== 'System bootstrap configuration information' backup completed successfully.
[Fri Jul 31 02:22:56 UTC 2015] 292 <== INFO 3141 <== All backup tasks finished.
[Fri Jul 31 02:22:56 UTC 2015] 3159 <== Cleaning up '/var/tmp/backup.2015-07-31.58471'...
[Fri Jul 31 02:22:56 UTC 2015] 3218 <== It took 1h 22m 56s to finish all backup tasks.
[Fri Jul 31 02:22:56 UTC 2015] 292 <== INFO 3219 <== All backups by OmniBackup v0.1.0.
Have question or need technical assistance, please visit http://www.babaei.net/ or write an email to info [ at ] babaei.net.
[2015-07-31_core.babaei.net_postgres.tar.xz.crypt](sY1JCw8va0sYESubH55MG81CIH0HmvMbXakquBGdXvCMKtP6bSmMSlSWLOPQqWHUGnIoyeFjUmZXB6dPn7w9qxrB6MHDuCTz7MLOq3PiS9FH1bzL6kVqkMgcskeJduZY)
[2015-07-31_core.babaei.net_postgres-gitlab.tar.xz.crypt](COKeMtmQevwbU7y9lz96OCzFYjaxnzfXEjoTUCHvAYHBWLV8obluJvwuK4afEkOdPs9vIyuHkx4lgePYdyAejIN5JYffiwQBKtbQYRohhZ39ejYrnbppXBsvQjRbF8up)
[2015-07-31_core.babaei.net_postgres-redmine.tar.xz.crypt](C4oLIMxFBXjLGUjCQ1I4xQGJhLE7pIM8HWtvJOhkR9TNJn3CcadmWpYSp6pbZZCmLs5tMbJ9QQhwB3c1H8GIPzWJLop3bm49c55K7ynrTEj4GW2KjlhozwvNdTps0sJ0)
[2015-07-31_core.babaei.net_postgres-owncloud.tar.xz.crypt](HIKxwvSuk6wIHlRjRchxtT6OxIMdzfiRVehCbrK3QsS8SC6jLXxE1BP2zssVMq5IWpCtRrp89plkxIdKLBLhjC3hKyA7Wo0lc9oZs2nqYob2ofCqWS8IkgRBAaGKJdaj)
[2015-07-31_core.babaei.net_mysql.tar.xz.crypt](hxISUfxgJc49IMr7Z75vlEO71Gy7ZR6bRPNPbRU32UpAIzTzlYm94sefQOgmkv4L7kYMU5e4xN48hhnqZPj9no4UnMgy5C1LdGsm3TPKYUv8Ogzc2h77gPdCcjxjI5Ds)
[2015-07-31_core.babaei.net_mysql-piwik.tar.xz.crypt](QkAtura4wHJ95RHutBgaaFKwWqIvqjswTsfL8vz7HlFpjXLOUeJRaAT6uKDBiOccaggFWD7cru845GLxfYpa4wVTWLUXaUbmB5UyeQ0Jt99qDVvDivLfXUN7EVOIjlD4)
[2015-07-31_core.babaei.net_www.tar.xz.crypt](ciaLyhXnJj9KRiXVsJhEOTt8slxbEYoGRwq9GHuL6nKXZm6rHqA9ySNRe1uwFpGUNVbx7hatcWUFxAC4Wfzzh8OOH8lj4ND7p4T9N3B6pG1Jn6sG3o4EKhYPw75WyRgY)
[2015-07-31_core.babaei.net_repos.tar.xz.crypt](vvEYkJr4KvjalYPIwPs9TRm7UOmqOeLBPVzk02Djov718PoVooVtM5YcsSWqwVort10LK8EY6Q2thCPWCoUnCV6TfznewYW1DZ3OwPqhVWNNdaARvXpdpKmF5nkdxtgV)
[2015-07-31_core.babaei.net_mail.tar.xz.crypt](EBNcWoyZy3kH2fr8YpjW5IIZzFfTMU0EanLXyr0fvObcXb4h3xap2j710YWYkFL5pYliy9BylRMqDBRtDBv6zKXoQsdiiqbvdd79YAIW50DZNCmuJ3hTDi3hYbMsRJpm)
[2015-07-31_core.babaei.net_etc-system.tar.xz.crypt](Qs2aqAPFmsLJ3hz0dB01NzKj3zCV33sXUH39u4YZudfQquXg9q9UeAtQtEzIHUG6alWIG67ANHbEZug8l7E5D55Sv4If81vKnyj2HU1Qrv31GFfxg2IWhCDovSuJloJR)
[2015-07-31_core.babaei.net_etc-ports.tar.xz.crypt](z8SfpAvMsI2efM56WNs3PrxIS9CB1ITD8bB5FMYPyVKqysWTChR3PoMbIjUzNBp02PsX3hJn1Ws7OyZ02UEeqaUMavuOLzeCQDJXnUOYnmUfqzJTE07Hiw3GpkPaJzxb)
[2015-07-31_core.babaei.net_loader-conf.tar.xz.crypt](nGedoAb7kTnlu9gApBX1vurtalU6SEWq8SZ0KweKoLCSG7QUZzDWVUY4PHbIRiahOP3008Gmg4NtpeAOKzohjwgLqQ9vXCLNAcBVqgIYMiDRILsLZ7X81E7WaI3zGkWp)
There is also a list of planned features and TODOs which did not make it into the current release:
- Restore script
- GnuPG integration
- SFTP and FTP support
- Refactoring and code clean-up
- Any potential bug fixes
(The MIT License)
Copyright (c) 2015 - 2019 Mamadou Babaei
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.