Rsync backup

From SysAdm
Jump to navigation Jump to search

rsync backup script

preparation.

on target host:
1. add backup user Ex. rbackup, /usr/sbin/nologin
2. ~/.ssh/authorized_keys:

 no-pty,no-X11-forwarding,permitopen="127.0.0.1:873",command="/bin/echo get_lost" <ssh-key>

3. /usr/local/etc/rsync/rsync.conf:

 address=127.0.0.1
 [wholefs]
  uid = 0
  gid = 0
  path = /
  read only = yes
  host allow = 127.0.0.1

on backup server:
1. /root/.ssh/config:

 Host HostA
  Hostname 1.1.1.1
  User rbackup
  IdentityFile ~/.ssh/id_rsa
  LocalForward 1111 127.0.0.1:873
 Host HostB
  Hostname 1.1.1.2
  User rbackup
  IdentityFile ~/.ssh/id_rsa
  LocalForward 1111 127.0.0.1:873

2. script:

 #!/bin/sh
 
 config_file="/root/config"
 
 . $config_file
 
 for level in $levels
 do
    if [ $1 = $level ]; then break
    else p_level=$level; fi
 done
 
 eval "lvl_max_ret=\${retain_$level}"
 lvl_max_ret=$(($lvl_max_ret-1))
 
 if [ $p_level ]; then
    eval "p_lvl_max_ret=\${retain_$p_level}"
    p_lvl_max_ret=$((p_lvl_max_ret-1))
    if [ ! -d "${backup_dir}/$p_level.$p_lvl_max_ret" ];
    then
        echo "not enough bakups on prev lvl" >>$log
    else
        i=$lvl_max_ret
        while [ $i -ge 0 ]
        do
            if [ -d "${backup_dir}/$level.$i" ]; then
                if [ $i -eq $lvl_max_ret ]; then
                    echo "rm -rf ${backup_dir}/$level.$i/" >>$log
                    rm -rf "${backup_dir}/$level.$i/" >>$log 2>&1
                else
                    echo "mv ${backup_dir}/$level.$i/ ${backup_dir}/$level.$(($i+1))/" >>$log
                    mv "${backup_dir}/$level.$i/" "${backup_dir}/$level.$(($i+1))/" >>$log 2>&1
                fi
            fi
            i=$(($i-1))
        done
        echo "mv ${backup_dir}/$p_level.$p_lvl_max_ret/ ${backup_dir}/$level.0/" >>$log
        mv "${backup_dir}/$p_level.$p_lvl_max_ret/" "${backup_dir}/$level.0/" >>$log 2>&1
    fi
 else
    if [ ! -d "${backup_dir}/$level.0" ]; then
        echo "mkdir -p ${backup_dir}/$level.0/" >>$log
        mkdir -p "${backup_dir}/$level.0/" >>$log 2>&1
    else
        i=$lvl_max_ret
        while [ $i -gt 0 ]
        do
            if [ -d "${backup_dir}/$level.$i" ]; then
                if [ $i -eq $lvl_max_ret ]; then
                    echo "rm -rf ${backup_dir}/$level.$i/" >>$log
                    rm -rf "${backup_dir}/$level.$i/" >>$log 2>&1
                else
                    echo "mv ${backup_dir}/$level.$i/ ${backup_dir}/$level.$(($i+1))/" >>$log
                    mv "${backup_dir}/$level.$i/" "${backup_dir}/$level.$(($i+1))/" >>$log 2>&1
                fi
            fi
            i=$(($i-1))
        done
        echo "cp -al ${backup_dir}/$level.0/ ${backup_dir}/$level.1/" >>$log
        cp -al "${backup_dir}/$level.0/" "${backup_dir}/$level.1/" >>$log 2>&1
    fi
 
    for host in $hosts
    do
        ssh -f -N -M -S /tmp/cltr $host >>$log 2>&1
        if [ ! -d "${backup_dir}/$level.0/$host" ]; then mkdir -p "${backup_dir}/$level.0/$host"; fi
        echo $host >>$log
        eval "curbaks=\${backup_$host}"
        for bak in $curbaks
        do
            echo $bak >>$log
            rsync -az --port=1111 --relative localhost::wholefs$bak $backup_dir/$level.0/${host} >>$log 2>&1
        done
        ssh -S /tmp/cltr -O exit $host >>$log 2>&1
    done
 fi

3. /root/config:

 log="/root/log.txt"
 
 backup_dir="/root/backup"
 
 levels="daily weekly monthly"
 retain_daily=7
 retain_weekly=4
 retain_monthly=12
 
 hosts="HostA HostB"
 backup_HostA="/root/ /etc/"
 backup_HostB="/root/ /etc/"