#!/bin/bash id=$(id -u) if [ $id != 0 ]; then echo "Error, you need to be root to run bkctl !" exit 1 fi if [ -f /etc/default/evobackup ]; then source /etc/default/evobackup else echo "Error, you need /etc/default/evobackup !" exit 1 fi mkdir -p $CONFDIR $JAILDIR $INCDIR ProgName=$(basename $0) sub_help(){ echo "Usage: $ProgName [options]" echo "Subcommands:" echo " init " echo " start " echo " stop " echo " reload " echo " restart " echo " status []" echo " key []" echo " port []" echo " inc" echo " rm" echo "" echo "For help with each subcommand run:" echo "$ProgName -h|--help" echo "" } sub_init() { mkdir -p ${JAILDIR}/${jail} umask 022 echo -n "1 - Creating the chroot..." mkdir -p ${JAILDIR}/${jail}/{bin,dev,etc/ssh,lib,lib64,proc} mkdir -p ${JAILDIR}/${jail}/lib/{x86_64-linux-gnu,tls/i686/cmov,i686/cmov} mkdir -p ${JAILDIR}/${jail}/usr/{bin,lib,sbin} mkdir -p ${JAILDIR}/${jail}/usr/lib/{x86_64-linux-gnu,openssh,i686/cmov} mkdir -p ${JAILDIR}/${jail}/root/.ssh && chmod 700 ${JAILDIR}/${jail}/root/.ssh mkdir -p ${JAILDIR}/${jail}/var/{log,run/sshd} touch ${JAILDIR}/${jail}/var/log/{authlog,lastlog,messages,syslog} touch ${JAILDIR}/${jail}/etc/fstab echo "...OK" echo -n "2 - Copying essential files..." cp /proc/devices ${JAILDIR}/${jail}/proc cp /etc/ssh/{ssh_host_rsa_key,ssh_host_dsa_key} ${JAILDIR}/${jail}/etc/ssh/ cp ${TPLDIR}/{passwd,shadow,group} ${JAILDIR}/${jail}/etc/ if [ ! -f ${JAILDIR}/$jail/${SSHD_CONFIG} ]; then cp ${TPLDIR}/sshd_config ${JAILDIR}/$jail/${SSHD_CONFIG} fi echo "...OK" echo -n "3 - Copying binaries..." cp -f /lib/ld-linux.so.2 ${JAILDIR}/${jail}/lib/ 2>/dev/null || cp -f /lib64/ld-linux-x86-64.so.2 ${JAILDIR}/${jail}/lib64/ cp /lib/x86_64-linux-gnu/libnss* ${JAILDIR}/${jail}/lib/x86_64-linux-gnu/ for dbin in /bin/bash /bin/cat /bin/chown /bin/mknod /bin/rm /bin/ls /bin/sed /bin/sh /bin/uname /bin/mount /usr/bin/rsync /usr/sbin/sshd /usr/lib/openssh/sftp-server; do cp -f $dbin ${JAILDIR}/${jail}/$dbin; for lib in $(ldd $dbin | grep -Eo "/.*so.[0-9\.]+"); do cp -p $lib ${JAILDIR}/${jail}/$lib done done echo "...OK" } sub_start() { set -e check_jail $jail status=`check_jail_on $jail` if [ $status == "ON" ]; then echo "Jail $jail already running !" exit 1 fi mount -t proc proc-chroot ${JAILDIR}/${jail}/proc/ mount -nt tmpfs none ${JAILDIR}/${jail}/dev mknod -m 622 ${JAILDIR}/${jail}/dev/console c 5 1 mknod -m 666 ${JAILDIR}/${jail}/dev/null c 1 3 mknod -m 666 ${JAILDIR}/${jail}/dev/zero c 1 5 mknod -m 666 ${JAILDIR}/${jail}/dev/ptmx c 5 2 mknod -m 666 ${JAILDIR}/${jail}/dev/tty c 5 0 mknod -m 444 ${JAILDIR}/${jail}/dev/random c 1 8 mknod -m 444 ${JAILDIR}/${jail}/dev/urandom c 1 9 chown root:tty ${JAILDIR}/${jail}/dev/{console,ptmx,tty} ln -s ${JAILDIR}/${jail}/proc/self/fd ${JAILDIR}/${jail}/dev/fd ln -s ${JAILDIR}/${jail}/proc/self/fd/0 ${JAILDIR}/${jail}/dev/stdin ln -s ${JAILDIR}/${jail}/proc/self/fd/1 ${JAILDIR}/${jail}/dev/stdout ln -s ${JAILDIR}/${jail}/proc/self/fd/2 ${JAILDIR}/${jail}/dev/stderr ln -s ${JAILDIR}/${jail}/proc/kcore ${JAILDIR}/${jail}/dev/core mkdir ${JAILDIR}/${jail}/dev/pts mkdir ${JAILDIR}/${jail}/dev/shm mount -t devpts -o gid=4,mode=620 none ${JAILDIR}/${jail}/dev/pts mount -t tmpfs none ${JAILDIR}/${jail}/dev/shm exec chroot ${JAILDIR}/${jail} /usr/sbin/sshd -E /var/log/authlog } sub_stop() { set -e check_jail $jail status=`check_jail_on $jail` if [ $status == "OFF" ]; then echo "Jail $jail is not running !" exit 1 fi pid=`cat ${JAILDIR}/${jail}/${SSHD_PID}` ps --ppid $pid -o pid=| while read conn; do kill $conn done kill $pid umount ${JAILDIR}/${jail}/proc/ umount ${JAILDIR}/${jail}/dev/pts umount ${JAILDIR}/${jail}/dev/shm sleep 0.2 umount ${JAILDIR}/${jail}/dev/ } sub_reload() { set -e check_jail $jail status=`check_jail_on $jail` if [ $status == "ON" ]; then pkill -HUP -F ${JAILDIR}/${jail}/${SSHD_PID} fi } sub_restart() { set -e check_jail $jail $0 stop $jail $0 start $jail } sub_key() { set -e check_jail $jail keyfile=$3 if [ -n "$keyfile" ]; then set_key $jail $keyfile else get_key $jail fi } sub_port() { set -e check_jail $jail port=$3 pre_port=`get_port $jail` if [ -z $port ]; then echo "$pre_port" else set_port $jail $port $0 reload $jail fi } sub_status() { set -e check_jail $jail inc=`check_inc jail` status=`check_jail_on $jail` port=`get_port $jail` echo "$jail : $status ($port) -> $inc" } sub_inc() { for jail in `ls -1 $CONFDIR`; do echo -n "hard copy $jail begins at : " >> $LOGFILE /bin/date +"%d-%m-%Y ; %H:%M" >> $LOGFILE mkdir -p ${INCDIR}${jail} cp -alx ${JAILDIR}/${jail}/ ${INCDIR}${jail}/$DATE echo -n "hard copy $i ends at : " >> $LOGFILE /bin/date +"%d-%m-%Y ; %H:%M" >> $LOGFILE done #| tee -a $LOGFILE | mail -s "[info] EvoBackup - create incs" $MYMAIL } sub_rm() { for i in $( ls -1 $CONFDIR ); do # list actual inc backups for j in $( ls $INCDIR$i ); do echo $j done > "$TMPDIR"$i.files # list non-obsolete inc backups for j in $( cat $CONFDIR$i ); do MYDATE=$( echo $j | cut -d. -f1 ) BEFORE=$( echo $j | cut -d. -f2 ) date -d "$(date $MYDATE) $BEFORE" "+%Y-%m-%d" done > "$TMPDIR"$i.keep # delete obsolete inc backups for j in $( grep -v -f "$TMPDIR"$i.keep "$TMPDIR"$i.files ); do echo -n "Delete $i/$j begins at : " >> $LOGFILE /bin/date +"%d-%m-%Y ; %H:%M" >> $LOGFILE cd $INCDIR$i [ -n "$j" ] && rsync -a --delete $EMPTYDIR/ $j* [ -n "$j" ] && rmdir $j* && touch /tmp/evobackup-rm.txt echo -n "Delete $i/$j ends at : " >> $LOGFILE /bin/date +"%d-%m-%Y ; %H:%M" >> $LOGFILE done done #| tee -a $LOGFILE | ( [ -e "/tmp/evobackup-rm.txt" ] && mail -s "[info] EvoBackup - purge incs" $MYMAIL && rm /tmp/evobackup-rm.txt ) rm -rf $TMPDIR $EMPTYDIR } check_jail() { jail=$1 if [ ! -d ${JAILDIR}/${jail} ]; then echo "$jail doesn't exits !" >/dev/stderr exit 1 fi } check_jail_on() { jail=$1 status="OFF" if [ -f ${JAILDIR}/${jail}/${SSHD_PID} ]; then pid=`cat ${JAILDIR}/${jail}/${SSHD_PID}` ps -p $pid > /dev/null if [ $? == 0 ]; then status="ON " else rm ${JAILDIR}/${jail}/${SSHD_PID} fi fi echo $status } check_inc() { jail=$1 inc="0" if [ -f ${CONFDIR}/${jail} ]; then day=`grep -c "day" ${CONFDIR}/${jail}` month=`grep -c "month" ${CONFDIR}/${jail}` inc="${day}/${month}" fi echo $inc } get_port() { jail=$1 port=`grep -E "Port [0-9]+" ${JAILDIR}/${jail}/${SSHD_CONFIG}|grep -oE "[0-9]+"` echo $port } set_port() { jail=$1 port=$2 if [ $port = "auto" ]; then port=$(grep -h Port ${JAILDIR}/*/${SSHD_CONFIG} 2>/dev/null | grep -Eo [0-9]+ | sort -n | tail -1) port=$((port+1)) if [ ! $port -gt 1 ]; then port=2222 fi fi sed -i "s/^Port .*/Port ${port}/" ${JAILDIR}/$jail/${SSHD_CONFIG} } get_key() { jail=$1 if [ -f ${JAILDIR}/${jail}/${AUTHORIZED_KEYS} ]; then cat ${JAILDIR}/${jail}/${AUTHORIZED_KEYS} fi } set_key() { jail=$1 keyfile=$2 if [ -f $keyfile ]; then cat $keyfile > ${JAILDIR}/${jail}/${AUTHORIZED_KEYS} chmod 600 ${JAILDIR}/${jail}/${AUTHORIZED_KEYS} else echo "Keyfile $keyfile dosen't exist !" exit 1 fi } subcommand=$1 jail=$2 case $subcommand in "" | "-h" | "--help") sub_help ;; "inc" | "rm") pkill -f /run/bkctl.pid #| mail -s "[warn] EvoBackup - purge incs interrupted" $MYMAIL rm -f /run/bkctl.pid sub_${subcommand} $@ & echo $! > /run/bkctl.pid ;; "init" | "key" | "port") if [ -z $jail ]; then sub_help exit 1 fi sub_${subcommand} $@ ;; "start" | "stop" | "reload" | "restart") if [ -z $jail ]; then sub_help exit 1 fi if [ $jail = "all" ]; then for jail in `ls $JAILDIR`; do $0 ${subcommand} $jail done else sub_${subcommand} $@ fi ;; "status") if [ -z $jail ]; then for jail in `ls $JAILDIR`; do $0 status $jail done else sub_${subcommand} $@ fi ;; *) shift echo "Error: '$subcommand' is not a known subcommand." >&2 echo " Run '$ProgName --help' for a list of known subcommands." >&2 exit 1 ;; esac