#!/bin/bash # # Creates a Full Backup of Nagios XI # Copyright (c) 2011-2020 Nagios Enterprises, LLC. All rights reserved. # PATH=/home/nagios/bin:/usr/bin:/bin . /home/nagios/bin/colors.sh BASEDIR="/usr/local/nagiosxi/scripts" timeStamp=`date +%s` hostname="`/bin/hostname`" pName="" sName="" noping=/bin/false noFile=/bin/false execute="-n" syncfile="" isP=/bin/false isS=/bin/false rsync_opts="-a --delete --delete-after" # Import Nagios XI and xi-sys.cfg config vars . $BASEDIR/../var/xi-sys.cfg eval $(php $BASEDIR/import_xiconfig.php) ############################### # USAGE / HELP ############################### usage () { echo "" echo "Use this script to synchronize primary XI to secondary, or to expand primary information on secondary" echo "" echo " -P | --primary Set the FQDN of the primary (what is returned by /bin/hostname)" echo " -S | --secondary Set the FQDN of the secondary (what is returned by /bin/hostname)" echo " -F | --file Set the name of the file that we will be restoring from on the secondary" echo " -E | --execute Perform the sync (otherwise, it just does a dry-run)" echo " -n | --name Set the name of the backup minus the .tar.gz" echo " -p | --prepend Prepend a string to the .tar.gz name" echo " -a | --append Append a string to the .tar.gz name" echo " -d | --directory Change the directory to store the compressed backup" echo " --nofile Ignore the missing sync file but continue the process" echo "" } ############################### # ADDING LOGIC FOR NEW BACKUPS ############################### while [ -n "$1" ]; do case "$1" in -P | --primary) pName="$2" ;; -S | --secondary) sName="$2" ;; -E | --execute) execute="" ;; -F | --file) syncfile="$2" ;; --noping) noping=/bin/true ;; --nofile) noFile=/bin/true ;; -h | --help) usage exit 0 ;; -n | --name) fullname=$2 ;; -p | --prepend) prepend=$2"." ;; -a | --append) append="."$2 ;; -d | --directory) rootdir=$2 ;; esac shift done do_primary() { #ping_host $sName #[ $? -ne 0 ] && echo "Cannot ping $sName. Use --noping to continue wihout ping." && exit echo "Starting sync from $pName to $sName" # Restart nagios to forcibly update retention.dat verbose "Restarting nagios to forcibly update retention.dat" sudo $BASEDIR/manage_services.sh stop nagios sleep 5 sudo $BASEDIR/manage_services.sh start nagios if [ -z $rootdir ]; then rootdir="/store/backups/nagiosxi" fi # Move to root dir to store backups cd $rootdir ############################# # SET THE NAME & TIME ############################# name=$fullname if [ -z $fullname ]; then name=$prepend$timeStamp$append fi # Get current Unix timestamp as name if [ -z $name ]; then name=timeStampts fi # My working directory workDir=$rootdir/$name # Make directory for this specific backup mkdir -p $workDir do_rsync() { verbose "Syncing $1 (Excluding ${2:-nothing})..." src="$1" [ -n "$2" ] && exclude="--exclude $2" || exclude="" [ ! -e "$src" ] && warning " OK: No such file or directory: $src" && return [ -d "$src" ] && sudo /usr/bin/rsync --rsync-path="sudo /bin/rsync" ${rsync_opts} ${exclude} ${execute} ${src}/ nagios@${sName}:${src}/ [ -f "$src" ] && sudo /usr/bin/rsync --rsync-path="sudo /bin/rsync" ${rsync_opts} ${exclude} ${execute} ${src} nagios@${sName}:${src} } do_backup_files() { ############################## # BACKUP DIRS ############################## # Only backup NagiosQL if it exists if [ -d "/var/www/html/nagiosql" ]; then do_rsync /var/www/html/nagiosql do_rsync /etc/nagiosql fi do_rsync /etc/apache2/sites-available/default-ssl.conf do_rsync /etc/logrotate.d/nagiosxi do_rsync /etc/mrtg/conf.d do_rsync /etc/mrtg/mrtg.cfg do_rsync /etc/snmp do_rsync /etc/sysconfig/nagios do_rsync /home/nagios do_rsync $httpdconfdir/nagios.conf do_rsync $httpdconfdir/nagiosmobile.conf do_rsync $httpdconfdir/nagiosxi.conf do_rsync $httpdconfdir/nagvis.conf do_rsync $httpdconfdir/nrdp.conf do_rsync $httpdconfdir/ssl.conf do_rsync /usr/local/nagios do_rsync /usr/local/nagiosmobile do_rsync /usr/local/nagiosxi custom-includes/css/ do_rsync /usr/local/nagvis do_rsync /usr/local/nrdp do_rsync /usr/share/snmp do_rsync /var/lib/mrtg do_rsync /var/spool/cron/apache do_rsync /var/spool/cron/crontabs/$apacheuser } # End of do_backup_files do_backup_sql() { ############################## # BACKUP DATABASES ############################## echo "Backing up MySQL databases..." mkdir -p $workDir/mysql if [[ "$cfg__db_info__ndoutils__dbserver" == *":"* ]]; then ndoutils_dbport=`echo "$cfg__db_info__ndoutils__dbserver" | cut -f2 -d":"` ndoutils_dbserver=`echo "$cfg__db_info__ndoutils__dbserver" | cut -f1 -d":"` else ndoutils_dbport='3306' ndoutils_dbserver="$cfg__db_info__ndoutils__dbserver" fi mysqldump -h "$ndoutils_dbserver" --port="$ndoutils_dbport" -u $cfg__db_info__ndoutils__user --password="$cfg__db_info__ndoutils__pwd" --add-drop-database -B $cfg__db_info__ndoutils__db > $workDir/mysql/nagios.sql res=$? if [ $res != 0 ]; then echo "Error backing up MySQL database 'nagios' - check the password in this script!" rm -r $workDir exit $res; fi if [[ "$cfg__db_info__nagiosql__dbserver" == *":"* ]]; then nagiosql_dbport=`echo "$cfg__db_info__nagiosql__dbserver" | cut -f2 -d":"` nagiosql_dbserver=`echo "$cfg__db_info__nagiosql__dbserver" | cut -f1 -d":"` else nagiosql_dbport='3306' nagiosql_dbserver="$cfg__db_info__nagiosql__dbserver" fi mysqldump -h "$nagiosql_dbserver" --port="$nagiosql_dbport" -u $cfg__db_info__nagiosql__user --password="$cfg__db_info__nagiosql__pwd" --add-drop-database -B $cfg__db_info__nagiosql__db > $workDir/mysql/nagiosql.sql res=$? if [ $res != 0 ]; then echo "Error backing up MySQL database 'nagiosql' - check the password in this script!" rm -r $workDir exit $res; fi # Only backup PostgresQL if we are still using it if [ $cfg__db_info__nagiosxi__dbtype == "pgsql" ]; then echo "Backing up PostgresQL databases..." mkdir -p $workDir/pgsql if [ -z $cfg__db_info__nagiosxi__dbserver ]; then cfg__db_info__nagiosxi__dbserver="localhost" fi pg_dump -h $cfg__db_info__nagiosxi__dbserver -c -U $cfg__db_info__nagiosxi__user $cfg__db_info__nagiosxi__db > $workDir/pgsql/nagiosxi.sql res=$? if [ $res != 0 ]; then echo "Error backing up PostgresQL database 'nagiosxi' !" rm -r $workDir exit $res; fi else if [[ "$cfg__db_info__nagiosxi__dbserver" == *":"* ]]; then nagiosxi_dbport=`echo "$cfg__db_info__nagiosxi__dbserver" | cut -f2 -d":"` nagiosxi_dbserver=`echo "$cfg__db_info__nagiosxi__dbserver" | cut -f1 -d":"` else nagiosxi_dbport='3306' nagiosxi_dbserver="$cfg__db_info__nagiosxi__dbserver" fi mysqldump -h "$nagiosxi_dbserver" --port="$nagiosxi_dbport" -u $cfg__db_info__nagiosxi__user --password="$cfg__db_info__nagiosxi__pwd" --add-drop-database -B $cfg__db_info__nagiosxi__db > $workDir/mysql/nagiosxi.sql res=$? if [ $res != 0 ]; then echo "Error backing up MySQL database 'nagiosxi' - check the password in this script!" rm -r $workDir exit $res; fi fi ############################## # COMPRESS BACKUP ############################## verbose "Compressing database file..." -n tar czfp $name.tar.gz $name rm -rf $name verbose "Done." # Change ownership chown $nagiosuser:$nagiosgroup $name.tar.gz if [ -s $name.tar.gz ];then echo " " echo "===============" echo "BACKUP COMPLETE" echo "===============" echo "Backup stored in $rootdir/$name.tar.gz" else echo " " echo "===============" echo "BACKUP FAILED" echo "===============" echo "File was not created at $rootdir/$name.tar.gz" rm -rf $workDir exit 1; fi do_rsync $rootdir/$name.tar.gz rm -Rf $rootdir/$name.tar.gz } # End of do_backup_sql do_backup_files do_backup_sql } # End of do_primary restore_secondary() { # Change this password if your root password is different than "nagiosxi" # MySQL root password themysqlpass="nagiosxi" # Tests mysql connection by opening a connection and selecting the DB we want to use test_mysql_connection() { local db_host="$1" local db_port="$2" local db_username="$3" local db_password="$4" db_error=$(mysql -h "$db_host" --port="$db_port" -u $db_username --password=$db_password -e "show databases;" 2>&1) return $? } rootdir=/store/backups/nagiosxi backupfile=$1 # This is a poor way to write this, but it's the easiest. Skip doing all the restore operations if there's no file to restore from. if [ ! $noFile ]; then if [ ! -f $backupfile ]; then error "Unable to find backup file $backupfile!" exit 1 fi ts=`date +%s` mydir=${rootdir}/${ts}-restore mkdir -p $mydir if [ ! -d $mydir ]; then error "Unable to create restore directory $mydir!" exit 1 fi # Extract backup verbose "Extracting backup to $mydir..." cd $mydir tar xzfps $backupfile # Change to subdirectory cd `ls | head -1` backupdir=`pwd` verbose "Backup files look okay. Preparing to restore..." # Shutdown services verbose "Shutting down services..." [ -r "/usr/local/nagios/var/retention.dat" ] && cp /usr/local/nagios/var/retention.dat $backupdir sudo $BASEDIR/manage_services.sh stop nagios sudo $BASEDIR/manage_services.sh stop ndo2db sudo $BASEDIR/manage_services.sh stop npcd [ -r "$backupdir/retention.dat" ] && cp $backupdir/retention.dat /usr/local/nagios/var/retention.dat rootdir=/ # Overwrite the mysqlpass with the hardcoded one at the top mysqlpass="$themysqlpass" # Restore databases verbose "Restoring MySQL databases..." if [[ "$cfg__db_info__ndoutils__dbserver" == *":"* ]]; then ndoutils_dbport=`echo "$cfg__db_info__ndoutils__dbserver" | cut -f2 -d":"` ndoutils_dbserver=`echo "$cfg__db_info__ndoutils__dbserver" | cut -f1 -d":"` else ndoutils_dbport='3306' ndoutils_dbserver="$cfg__db_info__ndoutils__dbserver" fi # Test mysql and see if we can connect before continuing x=1 while [ $x -le 5 ]; do test_mysql_connection $ndoutils_dbserver $ndoutils_dbport "root" $mysqlpass if [ $? == 1 ]; then error "ERROR: Could not connect to $ndoutils_dbserver:$ndoutils_dbport with root password supplied." read -s -r -p "Please enter the MySQL root password: " mysqlpass echo "" else break fi if [ $x -eq 5 ]; then error "ERROR: Aborting restore: Could not connect to MySQL." error "$db_error" exit 1 fi x=$(($x+1)) done # Save old Program URL old_url=$(echo "select value from xi_options where name='url'" | mysql -h "$ndoutils_dbserver" --port="$ndoutils_dbport" -u root --password=$mysqlpass -N nagiosxi) mysql -h "$ndoutils_dbserver" --port="$ndoutils_dbport" -u root --password=$mysqlpass < $backupdir/mysql/nagios.sql res=$? if [ $res != 0 ]; then error "Error restoring MySQL database 'nagios'" exit 1 fi # Restore old Program URL echo "update xi_options set value='$old_url' where name='url'" | mysql -h "$ndoutils_dbserver" --port="$ndoutils_dbport" -u root --password=$mysqlpass -N nagiosxi if [[ "$cfg__db_info__nagiosql__dbserver" == *":"* ]]; then nagiosql_dbport=`echo "$cfg__db_info__nagiosql__dbserver" | cut -f2 -d":"` nagiosql_dbserver=`echo "$cfg__db_info__nagiosql__dbserver" | cut -f1 -d":"` else nagiosql_dbport='3306' nagiosql_dbserver="$cfg__db_info__nagiosql__dbserver" fi # Test mysql again and see if we can connect before continuing x=1 while [ $x -le 5 ]; do test_mysql_connection $nagiosql_dbserver $nagiosql_dbport "root" $mysqlpass if [ $? == 1 ]; then error "ERROR: Could not connect to $nagiosql_dbserver:$nagiosql_dbport with root password supplied." read -s -r -p "Please enter the MySQL root password: " mysqlpass echo "" else break fi if [ $x -eq 5 ]; then error "ERROR: Aborting restore: Could not connect to MySQL." error "$db_error" exit 1 fi x=$(($x+1)) done mysql -h "$nagiosql_dbserver" --port="$nagiosql_dbport" -u root --password=$mysqlpass < $backupdir/mysql/nagiosql.sql res=$? if [ $res != 0 ]; then error "Error restoring MySQL database 'nagiosql'" exit 1 fi # Only restore PostgresQL if we are still using it if [ "$cfg__db_info__nagiosxi__dbtype" == "pgsql" ]; then service postgresql initdb &>/dev/null || true verbose "Restoring Nagios XI PostgresQL database..." if [ -f /var/lib/pgsql/data/pg_hba.conf ]; then pghba="/var/lib/pgsql/data/pg_hba.conf" cp -pr $pghba $pghba.old else #Ubuntu/Debian pghba=$(find /etc/postgresql -name "*pg_hba.conf") cp -pr $pghba $pghba.old fi echo "local all all trust host all all 127.0.0.1/32 trust host all all ::1/128 trust" > $pghba $BASEDIR/manage_services.sh start postgresql sudo -u postgres psql -c "create user nagiosxi with password 'n@gweb';" sudo -u postgres psql -c "create database nagiosxi owner nagiosxi;" $BASEDIR/manage_services.sh restart postgresql # Sleep a bit (required so Postgres finishes startup before we connect again) verbose "Sleeping for a few seconds (please wait)..." sleep 7 psql -U nagiosxi nagiosxi < $backupdir/pgsql/nagiosxi.sql res=$? if [ $res != 0 ]; then error "Error restoring PostgresQL database 'nagiosxi' !" exit 1 fi $BASEDIR/manage_services.sh restart postgresql if [ "$dist" == "el7" ] || [ "$dist" == "el8" ]; then systemctl enable postgresql.service elif [[ "$distro" == "Ubuntu" ]] || [[ "$distro" == "Debian" ]]; then update-rc.d postgresql enable else chkconfig postgresql on fi # Remove nagiosxi db from mysql if postgres is used instead if [[ "$cfg__db_info__nagiosql__dbserver" == *":"* ]]; then nagiosql_dbport=`echo "$cfg__db_info__nagiosql__dbserver" | cut -f2 -d":"` nagiosql_dbserver=`echo "$cfg__db_info__nagiosql__dbserver" | cut -f1 -d":"` else nagiosql_dbport='3306' nagiosql_dbserver="$cfg__db_info__nagiosql__dbserver" fi mysql -h "$nagiosql_dbserver" --port="$nagiosql_dbport" -u root --password=$mysqlpass < "DROP TABLE IF EXISTS nagiosxi;" else verbose "Restoring Nagios XI MySQL database..." if [[ "$cfg__db_info__nagiosxi__dbserver" == *":"* ]]; then nagiosxi_dbport=`echo "$cfg__db_info__nagiosxi__dbserver" | cut -f2 -d":"` nagiosxi_dbserver=`echo "$cfg__db_info__nagiosxi__dbserver" | cut -f1 -d":"` else nagiosxi_dbport='3306' if [ "x$cfg__db_info__nagiosxi__dbserver" == "x" ]; then nagiosxi_dbserver="localhost" else nagiosxi_dbserver="$cfg__db_info__nagiosxi__dbserver" fi fi # Test mysql again and see if we can connect before continuing x=1 while [ $x -le 5 ]; do test_mysql_connection $nagiosxi_dbserver $nagiosxi_dbport "root" $mysqlpass if [ $? == 1 ]; then error "ERROR: Could not connect to $nagiosxi_dbserver:$nagiosxi_dbport with root password supplied." read -s -r -p "Please enter the MySQL root password: " mysqlpass echo "" else break fi if [ $x -eq 5 ]; then error "ERROR: Aborting restore: Could not connect to MySQL." error "$db_error" exit 1 fi x=$(($x+1)) done mysql -h "$nagiosxi_dbserver" --port="$nagiosxi_dbport" -u root --password=$mysqlpass < $backupdir/mysql/nagiosxi.sql res=$? if [ $res != 0 ]; then error "Error restoring MySQL database 'nagiosxi' !" exit 1 fi fi fi # This is from the "noFile" check previously ############################## # RESTART SERVICES ############################## verbose "Restarting services..." sudo $BASEDIR/manage_services.sh restart mysqld sudo $BASEDIR/manage_services.sh restart httpd sudo $BASEDIR/manage_services.sh start npcd sudo $BASEDIR/manage_services.sh start ndo2db sudo $BASEDIR/manage_services.sh start nagios verbose "Restarting Nagios XI" cd /usr/local/nagiosxi/scripts ./reconfigure_nagios.sh rm -rf $mydir echo " " echo "===============" echo "RESTORE COMPLETE" echo "===============" } do_secondary() { [ ! $noFile -a ! -r "$syncfile" ] && error "No sync file ($syncfile) found." && exit 2 restore_secondary "$syncfile" if [ $? -eq 0 ]; then rm -f ${syncfile} fi } # End of do_secondary ping_host() { $noping && return 0 /usr/local/nagios/libexec/check_icmp -H $1 >/dev/null 2>&1 } [ -z "$pName" -o -z "$sName" ] && echo "Must specify primary name and secondary name" && exit 0 [ "$hostname" = "$pName" ] && isP=/bin/true [ "$hostname" = "$sName" ] && isS=/bin/true $isP && do_primary $isS && do_secondary