This commit is contained in:
Victor LABORIE 2018-03-27 16:39:03 +02:00
parent 0927e79954
commit d565374c5d

778
bkctld
View file

@ -12,20 +12,20 @@ usage(){
cat <<EOF cat <<EOF
Usage: $0 <subcommand> [options] Usage: $0 <subcommand> [options]
Subcommands: Subcommands:
init <jailname> Init jail <jailname> init <jailname> Init jail <jailname>
update <jailname>|all Update jail <jailname> or all update <jailname>|all Update jail <jailname> or all
remove <jailname>|all Remove jail <jailname> or all remove <jailname>|all Remove jail <jailname> or all
start <jailname>|all Start jail <jailname> or all start <jailname>|all Start jail <jailname> or all
stop <jailname>|all Stop jail <jailname> or all stop <jailname>|all Stop jail <jailname> or all
reload <jailname>|all Reload jail <jailname> or all reload <jailname>|all Reload jail <jailname> or all
restart <jailname>|all Restart jail <jailname> or all restart <jailname>|all Restart jail <jailname> or all
sync <jailname>|all Sync jail <jailname> or all to another node sync <jailname>|all Sync jail <jailname> or all to another node
status [<jailname>] Print status of <jailname> (default all jail) status [<jailname>] Print status of <jailname> (default all jail)
key <jailname> [<keyfile>] Set or get ssh pubic key of <jailname> key <jailname> [<keyfile>] Set or get ssh pubic key of <jailname>
port <jailname> [<ssh_port>|auto] Set or get ssh port of <jailname> port <jailname> [<port>|auto] Set or get ssh port of <jailname>
ip <jailname> [<ip>|all] Set or get allowed(s) ip(s) of <jailname> ip <jailname> [<ip>|all] Set or get allowed(s) ip(s) of <jailname>
inc Make incremental inc of all jails inc Make incremental inc of all jails
rm Remove old incremtal inc of all jails rm Remove old incremtal inc of all jails
EOF EOF
} }
@ -76,491 +76,489 @@ error() {
## check functions ## check functions
check_jail() { check_jail() {
jail="${1}" jail="${1}"
[ -d "${JAILDIR}/${jail}" ] && return 0 [ -d "${JAILDIR}/${jail}" ] && return 0
return 1 return 1
} }
check_jail_on() { check_jail_on() {
jail=$1 jail=$1
return=1 return=1
if [ -f ${JAILDIR}/${jail}/${SSHD_PID} ]; then if [ -f ${JAILDIR}/${jail}/${SSHD_PID} ]; then
pid=$(cat ${JAILDIR}/${jail}/${SSHD_PID}) pid=$(cat ${JAILDIR}/${jail}/${SSHD_PID})
ps -p $pid > /dev/null && return=0 ps -p $pid > /dev/null && return=0
fi fi
if [ "$return" -eq 1 ]; then if [ "$return" -eq 1 ]; then
rm -f ${JAILDIR}/${jail}/${SSHD_PID} rm -f ${JAILDIR}/${jail}/${SSHD_PID}
grep -q "${JAILDIR}/${jail}/proc" /proc/mounts && umount --lazy ${JAILDIR}/${jail}/proc/ grep -q "${JAILDIR}/${jail}/proc" /proc/mounts && umount --lazy ${JAILDIR}/${jail}/proc/
grep -q "${JAILDIR}/${jail}/dev" /proc/mounts && umount --lazy --recursive ${JAILDIR}/${jail}/dev grep -q "${JAILDIR}/${jail}/dev" /proc/mounts && umount --lazy --recursive ${JAILDIR}/${jail}/dev
fi fi
return "$return" return "$return"
} }
## get functions : get info on jail ## get functions : get info on jail
get_port() { get_port() {
jail=$1 jail=$1
port=$(grep -E "Port [0-9]+" ${JAILDIR}/${jail}/${SSHD_CONFIG}|grep -oE "[0-9]+") port=$(grep -E "Port [0-9]+" ${JAILDIR}/${jail}/${SSHD_CONFIG}|grep -oE "[0-9]+")
echo $port echo $port
} }
get_key() { get_key() {
jail=$1 jail=$1
if [ -f ${JAILDIR}/${jail}/${AUTHORIZED_KEYS} ]; then if [ -f ${JAILDIR}/${jail}/${AUTHORIZED_KEYS} ]; then
cat ${JAILDIR}/${jail}/${AUTHORIZED_KEYS} cat ${JAILDIR}/${jail}/${AUTHORIZED_KEYS}
fi fi
} }
get_ip() { get_ip() {
jail=$1 jail=$1
grep -E "^AllowUsers" "${JAILDIR}/$jail/${SSHD_CONFIG}"|grep -Eo "root@[^ ]+"| while read allow; do grep -E "^AllowUsers" "${JAILDIR}/$jail/${SSHD_CONFIG}"|grep -Eo "root@[^ ]+"| while read allow; do
echo "$allow"|cut -d'@' -f2 echo "$allow"|cut -d'@' -f2
done done
} }
get_inc() { get_inc() {
jail=$1 jail=$1
inc="0" inc="0"
if [ -f ${CONFDIR}/${jail} ]; then if [ -f ${CONFDIR}/${jail} ]; then
day=$(grep -c "day" ${CONFDIR}/${jail}) day=$(grep -c "day" ${CONFDIR}/${jail})
month=$(grep -c "month" ${CONFDIR}/${jail}) month=$(grep -c "month" ${CONFDIR}/${jail})
inc="${day}/${month}" inc="${day}/${month}"
fi fi
echo $inc echo $inc
} }
## set functions : set info on jail ## set functions : set info on jail
set_port() { set_port() {
jail=$1 jail=$1
port=$2 port=$2
if [ "$port" = "auto" ]; then if [ "$port" = "auto" ]; then
port=$(grep -h Port ${JAILDIR}/*/${SSHD_CONFIG} 2>/dev/null | grep -Eo "[0-9]+" | sort -n | tail -1) port=$(grep -h Port ${JAILDIR}/*/${SSHD_CONFIG} 2>/dev/null | grep -Eo "[0-9]+" | sort -n | tail -1)
port=$((port+1)) port=$((port+1))
if [ ! $port -gt 1 ]; then [ "${port}" -le 1 ] && port=2222
port=2222 fi
fi sed -i "s/^Port .*/Port ${port}/" ${JAILDIR}/$jail/${SSHD_CONFIG}
fi set_firewall $jail
sed -i "s/^Port .*/Port ${port}/" ${JAILDIR}/$jail/${SSHD_CONFIG}
set_firewall $jail
} }
set_key() { set_key() {
jail=$1 jail=$1
keyfile=$2 keyfile=$2
[ -e "${keyfile}" ] || error "Keyfile $keyfile dosen't exist !" [ -e "${keyfile}" ] || error "Keyfile $keyfile dosen't exist !"
cat $keyfile > ${JAILDIR}/${jail}/${AUTHORIZED_KEYS} cat $keyfile > ${JAILDIR}/${jail}/${AUTHORIZED_KEYS}
chmod 600 ${JAILDIR}/${jail}/${AUTHORIZED_KEYS} chmod 600 ${JAILDIR}/${jail}/${AUTHORIZED_KEYS}
} }
set_ip() { set_ip() {
jail=$1 jail=$1
ip=$2 ip=$2
if [ "$ip" = "all" ] || [ "$ip" = "0.0.0.0/0" ]; then if [ "$ip" = "all" ] || [ "$ip" = "0.0.0.0/0" ]; then
ips="0.0.0.0/0" ips="0.0.0.0/0"
else else
ips=$(get_ip $jail) ips=$(get_ip $jail)
ips=$(echo $ips $ip|xargs -n1|grep -v "0.0.0.0/0"|sort|uniq) ips=$(echo $ips $ip|xargs -n1|grep -v "0.0.0.0/0"|sort|uniq)
fi fi
allow="AllowUsers" allow="AllowUsers"
for ip in $ips; do for ip in $ips; do
allow="$allow root@${ip}" allow="$allow root@${ip}"
done done
sed -i "s~^AllowUsers .*~${allow}~" ${JAILDIR}/$jail/${SSHD_CONFIG} sed -i "s~^AllowUsers .*~${allow}~" ${JAILDIR}/$jail/${SSHD_CONFIG}
set_firewall $jail set_firewall $jail
} }
set_firewall() { set_firewall() {
jail=$1 jail=$1
if [ -n "${FIREWALL_RULES}" ]; then if [ -n "${FIREWALL_RULES}" ]; then
if [ -f $FIREWALL_RULES ]; then if [ -f $FIREWALL_RULES ]; then
sed -i "/#${jail}$/d" $FIREWALL_RULES sed -i "/#${jail}$/d" $FIREWALL_RULES
fi fi
if ( check_jail $jail ); then if ( check_jail $jail ); then
port=$(get_port $jail) port=$(get_port $jail)
for ip in $(get_ip $jail); do for ip in $(get_ip $jail); do
echo "/sbin/iptables -A INPUT -p tcp --sport 1024: --dport $port -s $ip -j ACCEPT #$jail" >> $FIREWALL_RULES echo "/sbin/iptables -A INPUT -p tcp --sport 1024: --dport $port -s $ip -j ACCEPT #$jail" >> $FIREWALL_RULES
done done
if [ -f /etc/init.d/minifirewall ]; then if [ -f /etc/init.d/minifirewall ]; then
/etc/init.d/minifirewall restart >/dev/null /etc/init.d/minifirewall restart >/dev/null
fi fi
fi fi
fi fi
} }
## mk_jail function : create or update a jail ## mk_jail function : create or update a jail
mk_jail() { mk_jail() {
jail=$1 jail=$1
passwd="${TPLDIR}/passwd" passwd="${TPLDIR}/passwd"
shadow="${TPLDIR}/shadow" shadow="${TPLDIR}/shadow"
group="${TPLDIR}/group" group="${TPLDIR}/group"
sshrc="${TPLDIR}/sshrc" sshrc="${TPLDIR}/sshrc"
[ -f "${LOCALTPLDIR}/passwd" ] && passwd="${LOCALTPLDIR}/passwd" [ -f "${LOCALTPLDIR}/passwd" ] && passwd="${LOCALTPLDIR}/passwd"
[ -f "${LOCALTPLDIR}/shadow" ] && shadow="${LOCALTPLDIR}/shadow" [ -f "${LOCALTPLDIR}/shadow" ] && shadow="${LOCALTPLDIR}/shadow"
[ -f "${LOCALTPLDIR}/group" ] && group="${LOCALTPLDIR}/group" [ -f "${LOCALTPLDIR}/group" ] && group="${LOCALTPLDIR}/group"
[ -f "${LOCALTPLDIR}/sshrc" ] && group="${LOCALTPLDIR}/sshrc" [ -f "${LOCALTPLDIR}/sshrc" ] && group="${LOCALTPLDIR}/sshrc"
umask 077 umask 077
info "1 - Creating the chroot" info "1 - Creating the chroot"
cd "${JAILDIR}/${jail}" cd "${JAILDIR}/${jail}"
rm -rf bin lib lib64 run usr var/run etc/ssh/*key rm -rf bin lib lib64 run usr var/run etc/ssh/*key
mkdir -p dev proc mkdir -p dev proc
mkdir -p usr/bin usr/sbin usr/lib usr/lib/x86_64-linux-gnu usr/lib/openssh usr/lib64 mkdir -p usr/bin usr/sbin usr/lib usr/lib/x86_64-linux-gnu usr/lib/openssh usr/lib64
mkdir -p etc/ssh var/log run/sshd mkdir -p etc/ssh var/log run/sshd
mkdir -p root/.ssh var/backup -m 0700 mkdir -p root/.ssh var/backup -m 0700
ln -s usr/bin bin ln -s usr/bin bin
ln -s usr/lib lib ln -s usr/lib lib
ln -s usr/lib64 lib64 ln -s usr/lib64 lib64
ln -st var ../run ln -st var ../run
touch var/log/lastlog var/log/wtmp run/utmp touch var/log/lastlog var/log/wtmp run/utmp
info "2 - Copying essential files" info "2 - Copying essential files"
[ -f /etc/ssh/ssh_host_rsa_key ] && cp /etc/ssh/ssh_host_rsa_key etc/ssh [ -f /etc/ssh/ssh_host_rsa_key ] && cp /etc/ssh/ssh_host_rsa_key etc/ssh
[ -f /etc/ssh/ssh_host_ecdsa_key ] && cp /etc/ssh/ssh_host_ecdsa_key etc/ssh [ -f /etc/ssh/ssh_host_ecdsa_key ] && cp /etc/ssh/ssh_host_ecdsa_key etc/ssh
[ -f /etc/ssh/ssh_host_ed25519_key ] && cp /etc/ssh/ssh_host_ed25519_key etc/ssh [ -f /etc/ssh/ssh_host_ed25519_key ] && cp /etc/ssh/ssh_host_ed25519_key etc/ssh
cp "$passwd" etc cp "$passwd" etc
cp "$shadow" etc cp "$shadow" etc
cp "$group" etc cp "$group" etc
cp "$sshrc" etc/ssh cp "$sshrc" etc/ssh
info "3 - Copying binaries" info "3 - Copying binaries"
cp -f /lib/ld-linux.so.2 lib 2>/dev/null || cp -f /lib64/ld-linux-x86-64.so.2 lib64 cp -f /lib/ld-linux.so.2 lib 2>/dev/null || cp -f /lib64/ld-linux-x86-64.so.2 lib64
cp /lib/x86_64-linux-gnu/libnss* lib/x86_64-linux-gnu cp /lib/x86_64-linux-gnu/libnss* lib/x86_64-linux-gnu
for dbin in /bin/sh /bin/ls /bin/mkdir /bin/cat /bin/rm /bin/sed /usr/bin/rsync /usr/bin/lastlog /usr/bin/touch /usr/sbin/sshd /usr/lib/openssh/sftp-server; do for dbin in /bin/sh /bin/ls /bin/mkdir /bin/cat /bin/rm /bin/sed /usr/bin/rsync /usr/bin/lastlog /usr/bin/touch /usr/sbin/sshd /usr/lib/openssh/sftp-server; do
cp -f $dbin ${JAILDIR}/${jail}/$dbin; cp -f $dbin ${JAILDIR}/${jail}/$dbin;
for lib in $(ldd $dbin | grep -Eo "/.*so.[0-9\.]+"); do for lib in $(ldd $dbin | grep -Eo "/.*so.[0-9\.]+"); do
cp -p $lib ${JAILDIR}/${jail}/$lib cp -p $lib ${JAILDIR}/${jail}/$lib
done done
done done
} }
## sub functions : functions call by subcommand ## sub functions : functions call by subcommand
sub_init() { sub_init() {
jail=$1 jail=$1
sshd_config="${TPLDIR}/sshd_config" sshd_config="${TPLDIR}/sshd_config"
inctpl="${TPLDIR}/inc.tpl" inctpl="${TPLDIR}/inc.tpl"
[ -f "${LOCALTPLDIR}/sshd_config" ] && sshd_config="${LOCALTPLDIR}/sshd_config" [ -f "${LOCALTPLDIR}/sshd_config" ] && sshd_config="${LOCALTPLDIR}/sshd_config"
[ -f "${LOCALTPLDIR}/inc.tpl" ] && inctpl="${LOCALTPLDIR}/inc.tpl" [ -f "${LOCALTPLDIR}/inc.tpl" ] && inctpl="${LOCALTPLDIR}/inc.tpl"
check_jail $jail && error "${jail} : trying to create existant jail" check_jail $jail && error "${jail} : trying to create existant jail"
rootdir=$(dirname "$JAILDIR") rootdir=$(dirname "$JAILDIR")
rootdir_inode=$(stat --format=%i "$rootdir") rootdir_inode=$(stat --format=%i "$rootdir")
jaildir_inode=$(stat --format=%i $JAILDIR) jaildir_inode=$(stat --format=%i $JAILDIR)
if [ "$rootdir_inode" -eq 256 ] || [ "$jaildir_inode" -eq 256 ]; then if [ "$rootdir_inode" -eq 256 ] || [ "$jaildir_inode" -eq 256 ]; then
$BTRFS subvolume create ${JAILDIR}/${jail} $BTRFS subvolume create ${JAILDIR}/${jail}
else else
mkdir -p ${JAILDIR}/${jail} mkdir -p ${JAILDIR}/${jail}
fi fi
mk_jail $jail mk_jail $jail
info "4 - Copie default sshd_config" info "4 - Copie default sshd_config"
install -m 0640 $sshd_config ${JAILDIR}/$jail/${SSHD_CONFIG} install -m 0640 $sshd_config ${JAILDIR}/$jail/${SSHD_CONFIG}
info "5 - Set usable sshd port" info "5 - Set usable sshd port"
set_port $jail auto set_port $jail auto
info "6 - Copie default inc configuration" info "6 - Copie default inc configuration"
install -m 0640 $inctpl ${CONFDIR}/$jail install -m 0640 $inctpl ${CONFDIR}/$jail
notice "${jail} : created jail" notice "${jail} : created jail"
} }
sub_update() { sub_update() {
jail=$1 jail=$1
check_jail $jail || error "${jail} : trying to update inexistant jail" check_jail $jail || error "${jail} : trying to update inexistant jail"
check_jail_on $jail && sub_stop $jail check_jail_on $jail && sub_stop $jail
mk_jail $jail mk_jail $jail
notice "${jail} : updated jail" notice "${jail} : updated jail"
} }
sub_remove() { sub_remove() {
jail=$1 jail=$1
check_jail $jail || error "${jail} : trying to remove inexistant jail" check_jail $jail || error "${jail} : trying to remove inexistant jail"
check_jail_on $jail && sub_stop $jail check_jail_on $jail && sub_stop $jail
rm -f ${CONFDIR}/${jail} rm -f ${CONFDIR}/${jail}
jail_inode=$(stat --format=%i ${JAILDIR}/${jail}) jail_inode=$(stat --format=%i ${JAILDIR}/${jail})
if [ "$jail_inode" -eq 256 ]; then if [ "$jail_inode" -eq 256 ]; then
$BTRFS subvolume delete ${JAILDIR}/${jail} | debug $BTRFS subvolume delete ${JAILDIR}/${jail} | debug
else else
rm -rf ${JAILDIR}/${jail} | debug rm -rf ${JAILDIR}/${jail} | debug
fi fi
if [ -d ${INCDIR}/${jail} ]; then if [ -d ${INCDIR}/${jail} ]; then
incs=$(ls ${INCDIR}/${jail}) incs=$(ls ${INCDIR}/${jail})
for inc in $incs; do for inc in $incs; do
inc_inode=$(stat --format=%i ${INCDIR}/${jail}/$inc) inc_inode=$(stat --format=%i ${INCDIR}/${jail}/$inc)
if [ "$inc_inode" -eq 256 ]; then if [ "$inc_inode" -eq 256 ]; then
$BTRFS subvolume delete ${INCDIR}/${jail}/${inc} | debug $BTRFS subvolume delete ${INCDIR}/${jail}/${inc} | debug
else else
warning "You need to purge ${INCDIR}/${jail}/$inc manually !" warning "You need to purge ${INCDIR}/${jail}/$inc manually !"
fi fi
done done
rmdir --ignore-fail-on-non-empty ${INCDIR}/${jail} | debug rmdir --ignore-fail-on-non-empty ${INCDIR}/${jail} | debug
fi fi
set_firewall $jail set_firewall $jail
notice "${jail} : deleted jail" notice "${jail} : deleted jail"
} }
sub_start() { sub_start() {
jail=$1 jail=$1
check_jail $jail || error "${jail} : trying to start inexistant jail" check_jail $jail || error "${jail} : trying to start inexistant jail"
check_jail_on $jail && error "${jail} : trying to start already running jail" check_jail_on $jail && error "${jail} : trying to start already running jail"
cd "${JAILDIR}/${jail}" cd "${JAILDIR}/${jail}"
grep -q "${JAILDIR}/${jail}/proc" /proc/mounts || mount -t proc "proc-${jail}" proc grep -q "${JAILDIR}/${jail}/proc" /proc/mounts || mount -t proc "proc-${jail}" proc
grep -q "${JAILDIR}/${jail}/dev" /proc/mounts || mount -nt tmpfs "dev-${jail}" dev grep -q "${JAILDIR}/${jail}/dev" /proc/mounts || mount -nt tmpfs "dev-${jail}" dev
[ -e "dev/console" ] || mknod -m 622 dev/console c 5 1 [ -e "dev/console" ] || mknod -m 622 dev/console c 5 1
[ -e "dev/null" ] || mknod -m 666 dev/null c 1 3 [ -e "dev/null" ] || mknod -m 666 dev/null c 1 3
[ -e "dev/zero" ] || mknod -m 666 dev/zero c 1 5 [ -e "dev/zero" ] || mknod -m 666 dev/zero c 1 5
[ -e "dev/ptmx" ] || mknod -m 666 dev/ptmx c 5 2 [ -e "dev/ptmx" ] || mknod -m 666 dev/ptmx c 5 2
[ -e "dev/tty" ] || mknod -m 666 dev/tty c 5 0 [ -e "dev/tty" ] || mknod -m 666 dev/tty c 5 0
[ -e "dev/random" ] || mknod -m 444 dev/random c 1 8 [ -e "dev/random" ] || mknod -m 444 dev/random c 1 8
[ -e "dev/urandom" ] || mknod -m 444 dev/urandom c 1 9 [ -e "dev/urandom" ] || mknod -m 444 dev/urandom c 1 9
chown root:tty dev/console dev/ptmx dev/tty chown root:tty dev/console dev/ptmx dev/tty
ln -fs proc/self/fd dev/fd ln -fs proc/self/fd dev/fd
ln -fs proc/self/fd/0 dev/stdin ln -fs proc/self/fd/0 dev/stdin
ln -fs proc/self/fd/1 dev/stdout ln -fs proc/self/fd/1 dev/stdout
ln -fs proc/self/fd/2 dev/stderr ln -fs proc/self/fd/2 dev/stderr
ln -fs proc/kcore dev/core ln -fs proc/kcore dev/core
mkdir -p dev/pts mkdir -p dev/pts
mkdir -p dev/shm mkdir -p dev/shm
grep -q "${JAILDIR}/${jail}/dev/pts" /proc/mounts || mount -t devpts -o gid=4,mode=620 none dev/pts grep -q "${JAILDIR}/${jail}/dev/pts" /proc/mounts || mount -t devpts -o gid=4,mode=620 none dev/pts
grep -q "${JAILDIR}/${jail}/dev/shm" /proc/mounts || mount -t tmpfs none dev/shm grep -q "${JAILDIR}/${jail}/dev/shm" /proc/mounts || mount -t tmpfs none dev/shm
chroot "${JAILDIR}/${jail}" /usr/sbin/sshd -E /var/log/authlog || error "${jail} : error on starting sshd" chroot "${JAILDIR}/${jail}" /usr/sbin/sshd -E /var/log/authlog || error "${jail} : error on starting sshd"
pid=$(cat "${JAILDIR}/${jail}/${SSHD_PID}") pid=$(cat "${JAILDIR}/${jail}/${SSHD_PID}")
notice "${jail} was started [${pid}]" notice "${jail} was started [${pid}]"
} }
sub_stop() { sub_stop() {
jail=$1 jail=$1
check_jail $jail || error "${jail} : trying to stop inexistant jail" check_jail $jail || error "${jail} : trying to stop inexistant jail"
check_jail_on $jail || error "${jail} : trying to stop not running jail" check_jail_on $jail || error "${jail} : trying to stop not running jail"
pid=$(cat ${JAILDIR}/${jail}/${SSHD_PID}) pid=$(cat ${JAILDIR}/${jail}/${SSHD_PID})
for conn in $(ps --ppid $pid -o pid=); do for conn in $(ps --ppid $pid -o pid=); do
kill $conn kill $conn
done done
kill $pid && notice "${jail} was stopped [${pid}]" kill $pid && notice "${jail} was stopped [${pid}]"
umount --lazy --recursive ${JAILDIR}/${jail}/dev umount --lazy --recursive ${JAILDIR}/${jail}/dev
umount --lazy ${JAILDIR}/${jail}/proc/ umount --lazy ${JAILDIR}/${jail}/proc/
} }
sub_reload() { sub_reload() {
jail=$1 jail=$1
check_jail $jail || error "${jail} : trying to reload inexistant jail" check_jail $jail || error "${jail} : trying to reload inexistant jail"
check_jail_on $jail || error "${jail} : trying to reload not running jail" check_jail_on $jail || error "${jail} : trying to reload not running jail"
pid=$(cat "${JAILDIR}/${jail}/${SSHD_PID}") pid=$(cat "${JAILDIR}/${jail}/${SSHD_PID}")
pkill -HUP "${pid}" pkill -HUP "${pid}"
notice "${jail} was reloaded [${pid}]" notice "${jail} was reloaded [${pid}]"
} }
sub_status() { sub_status() {
jail=$1 jail=$1
check_jail $jail || error "${jail} : inexistant jail ! Use '$0 status' for list all" check_jail $jail || error "${jail} : inexistant jail ! Use '$0 status' for list all"
inc=$(get_inc $jail) inc=$(get_inc $jail)
if ( check_jail_on $jail ); then if ( check_jail_on $jail ); then
status="ON " status="ON "
else else
status="OFF" status="OFF"
fi fi
port=$(get_port $jail) port=$(get_port $jail)
ip=$(get_ip $jail|xargs|tr -s ' ' ',') ip=$(get_ip $jail|xargs|tr -s ' ' ',')
echo "$jail $status $port $inc $ip" | awk '{ printf("%- 30s %- 10s %- 10s %- 10s %- 40s\n", $1, $2, $3, $4, $5); }' echo "$jail $status $port $inc $ip" | awk '{ printf("%- 30s %- 10s %- 10s %- 10s %- 40s\n", $1, $2, $3, $4, $5); }'
} }
sub_params() { sub_params() {
jail=$1 jail=$1
params=$2 params=$2
option=$3 option=$3
check_jail $jail || error "${jail} : inexistant jail'" check_jail $jail || error "${jail} : inexistant jail'"
if [ -z "${option}" ]; then if [ -z "${option}" ]; then
get_${params} $jail get_${params} $jail
else else
set_${params} $jail $option set_${params} $jail $option
notice "${jail} : update $params => $option" notice "${jail} : update $params => $option"
fi fi
} }
sub_sync() { sub_sync() {
jail=$1 jail=$1
check_jail $jail || error "${jail} : trying to sync inexistant jail" check_jail $jail || error "${jail} : trying to sync inexistant jail"
[ -n "${NODE}" ] || error "Sync need config of \$NODE in /etc/default/bkctld !" [ -n "${NODE}" ] || error "Sync need config of \$NODE in /etc/default/bkctld !"
jail=$1 jail=$1
ssh $NODE bkctld init $jail | debug ssh $NODE bkctld init $jail | debug
rsync -a ${JAILDIR}/${jail}/ ${NODE}:${JAILDIR}/${jail}/ --exclude proc/* --exclude sys/* --exclude dev/* --exclude run --exclude var/backup/* rsync -a ${JAILDIR}/${jail}/ ${NODE}:${JAILDIR}/${jail}/ --exclude proc/* --exclude sys/* --exclude dev/* --exclude run --exclude var/backup/*
rsync -a ${CONFDIR}/$jail ${NODE}:${CONFDIR}/$jail rsync -a ${CONFDIR}/$jail ${NODE}:${CONFDIR}/$jail
if ( check_jail_on $jail ); then if ( check_jail_on $jail ); then
ssh $NODE bkctld start $jail | debug ssh $NODE bkctld start $jail | debug
fi fi
if [ -n "${FIREWALL_RULES}" ]; then if [ -n "${FIREWALL_RULES}" ]; then
rsync -a ${FIREWALL_RULES} ${NODE}:${FIREWALL_RULES} rsync -a ${FIREWALL_RULES} ${NODE}:${FIREWALL_RULES}
ssh $NODE /etc/init.d/minifirewall restart | debug ssh $NODE /etc/init.d/minifirewall restart | debug
fi fi
} }
sub_inc() { sub_inc() {
date=$(date +"%Y-%m-%d-%H") date=$(date +"%Y-%m-%d-%H")
jails=$(ls $JAILDIR) jails=$(ls $JAILDIR)
for jail in $jails; do for jail in $jails; do
inc="${INCDIR}/${jail}/${date}" inc="${INCDIR}/${jail}/${date}"
mkdir -p ${INCDIR}/${jail} mkdir -p ${INCDIR}/${jail}
if [ ! -d "${inc}" ]; then if [ ! -d "${inc}" ]; then
start=$(date +"%H:%M:%S") start=$(date +"%H:%M:%S")
jail_inode=$(stat --format=%i ${JAILDIR}/${jail}) jail_inode=$(stat --format=%i ${JAILDIR}/${jail})
if [ "$jail_inode" -eq 256 ]; then if [ "$jail_inode" -eq 256 ]; then
$BTRFS subvolume snapshot -r ${JAILDIR}/${jail} $inc | debug $BTRFS subvolume snapshot -r ${JAILDIR}/${jail} $inc | debug
else else
cp -alx ${JAILDIR}/${jail}/ $inc | debug cp -alx ${JAILDIR}/${jail}/ $inc | debug
fi fi
end=$(date +"%H:%M:%S") end=$(date +"%H:%M:%S")
notice "${jail} : made $date inc [$start/$end]" notice "${jail} : made $date inc [$start/$end]"
else else
warning "${jail} : trying to made already existant inc" warning "${jail} : trying to made already existant inc"
fi fi
done done
} }
sub_rm() { sub_rm() {
empty="/tmp/bkctld-${$}-$(date +%N))" empty="/tmp/bkctld-${$}-$(date +%N))"
mkdir $empty mkdir $empty
pidfile="/var/run/bkctld-rm.pid" pidfile="/var/run/bkctld-rm.pid"
if [ -f "${pidfile}" ]; then if [ -f "${pidfile}" ]; then
pid=$(cat $pidfile) pid=$(cat $pidfile)
ps -u $pid >/dev/null ps -u $pid >/dev/null
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
kill -9 $pid kill -9 $pid
warning "$0 rm always run (PID $pid), killed by $$ !" warning "$0 rm always run (PID $pid), killed by $$ !"
fi
rm $pidfile
fi fi
echo $$ > $pidfile rm $pidfile
rms_logs="" fi
jails=$(ls $JAILDIR) echo $$ > $pidfile
for jail in $jails; do rms_logs=""
incs=$(ls ${INCDIR}/$jail) jails=$(ls $JAILDIR)
if [ -f ${CONFDIR}/$jail ]; then for jail in $jails; do
keepfile="${CONFDIR}/.keep-${jail}" incs=$(ls ${INCDIR}/$jail)
while read j; do if [ -f ${CONFDIR}/$jail ]; then
date=$( echo "$j" | cut -d. -f1 ) keepfile="${CONFDIR}/.keep-${jail}"
before=$( echo "$j" | cut -d. -f2 ) while read j; do
date -d "$(date "$date") $before" "+%Y-%m-%d" date=$( echo "$j" | cut -d. -f1 )
done < "${CONFDIR}/$jail" > "$keepfile" before=$( echo "$j" | cut -d. -f2 )
for j in $(echo "${incs}" | grep -v -f "$keepfile"); do date -d "$(date "$date") $before" "+%Y-%m-%d"
start=$(date +"%H:%M:%S") done < "${CONFDIR}/$jail" > "$keepfile"
inc_inode=$(stat --format=%i "${INCDIR}/${jail}/${j}") for j in $(echo "${incs}" | grep -v -f "$keepfile"); do
if [ "$inc_inode" -eq 256 ]; then start=$(date +"%H:%M:%S")
$BTRFS subvolume delete "${INCDIR}/${jail}/${j}" | debug inc_inode=$(stat --format=%i "${INCDIR}/${jail}/${j}")
else if [ "$inc_inode" -eq 256 ]; then
cd "${INCDIR}/$jail" $BTRFS subvolume delete "${INCDIR}/${jail}/${j}" | debug
rsync -a --delete "$empty/" "$j/" else
rmdir "$j" cd "${INCDIR}/$jail"
fi rsync -a --delete "$empty/" "$j/"
end=$(date +"%H:%M:%S") rmdir "$j"
notice "${jail} : deleted $j inc [$start/$end]" fi
done end=$(date +"%H:%M:%S")
fi notice "${jail} : deleted $j inc [$start/$end]"
done done
rmdir $empty fi
rm $pidfile done
rmdir $empty
rm $pidfile
} }
## main function : check usage and valid params ## main function : check usage and valid params
main() { main() {
[ "$(id -u)" -ne 0 ] && error "You need to be root to run $0 !" [ "$(id -u)" -ne 0 ] && error "You need to be root to run $0 !"
[ -f /etc/default/bkctld ] && . /etc/default/bkctld [ -f /etc/default/bkctld ] && . /etc/default/bkctld
[ -z "${CONFDIR}" ] && CONFDIR='/etc/evobackup' [ -z "${CONFDIR}" ] && CONFDIR='/etc/evobackup'
[ -z "${JAILDIR}" ] && JAILDIR='/backup/jails' [ -z "${JAILDIR}" ] && JAILDIR='/backup/jails'
[ -z "${INCDIR}" ] && INCDIR='/backup/incs' [ -z "${INCDIR}" ] && INCDIR='/backup/incs'
[ -z "${TPLDIR}" ] && TPLDIR='/usr/share/bkctld' [ -z "${TPLDIR}" ] && TPLDIR='/usr/share/bkctld'
[ -z "${LOCALTPLDIR}" ] && LOCALTPLDIR='/usr/local/share/bkctld' [ -z "${LOCALTPLDIR}" ] && LOCALTPLDIR='/usr/local/share/bkctld'
[ -z "${SSHD_PID}" ] && SSHD_PID='/run/sshd.pid' [ -z "${SSHD_PID}" ] && SSHD_PID='/run/sshd.pid'
[ -z "${SSHD_CONFIG}" ] && SSHD_CONFIG='/etc/ssh/sshd_config' [ -z "${SSHD_CONFIG}" ] && SSHD_CONFIG='/etc/ssh/sshd_config'
[ -z "${AUTHORIZED_KEYS}" ] && AUTHORIZED_KEYS='/root/.ssh/authorized_keys' [ -z "${AUTHORIZED_KEYS}" ] && AUTHORIZED_KEYS='/root/.ssh/authorized_keys'
[ -z "${LOGLEVEL}" ] && LOGLEVEL=6 [ -z "${LOGLEVEL}" ] && LOGLEVEL=6
BTRFS=$(which btrfs) BTRFS=$(which btrfs)
mkdir -p $CONFDIR $JAILDIR $INCDIR mkdir -p $CONFDIR $JAILDIR $INCDIR
subcommand=$1 subcommand=$1
jail=$2 jail=$2
option=$3 option=$3
case $subcommand in case $subcommand in
"" | "-h" | "--help") "" | "-h" | "--help")
usage usage
;; ;;
"inc" | "rm") "inc" | "rm")
"sub_${subcommand}" "sub_${subcommand}"
;; ;;
"init") "init")
if [ -n "${jail}" ]; then if [ -n "${jail}" ]; then
"sub_${subcommand}" $jail "sub_${subcommand}" $jail
else else
usage usage
fi fi
;; ;;
"key" | "port" | "ip") "key" | "port" | "ip")
if [ -n "${jail}" ]; then if [ -n "${jail}" ]; then
sub_params $jail $subcommand $option sub_params $jail $subcommand $option
else else
usage usage
fi fi
;; ;;
"start" | "stop" | "reload" | "restart" | "sync" | "update" | "remove") "start" | "stop" | "reload" | "restart" | "sync" | "update" | "remove")
if [ -n "${jail}" ]; then if [ -n "${jail}" ]; then
if [ "${jail}" = "all" ]; then if [ "${jail}" = "all" ]; then
jails=$(ls $JAILDIR) jails=$(ls $JAILDIR)
for jail in $jails; do for jail in $jails; do
case $subcommand in case $subcommand in
"start") "start")
check_jail_on $jail || "sub_${subcommand}" $jail check_jail_on $jail || "sub_${subcommand}" $jail
;; ;;
"stop" | "reload") "stop" | "reload")
check_jail_on $jail && "sub_${subcommand}" $jail check_jail_on $jail && "sub_${subcommand}" $jail
;; ;;
"restart") "restart")
check_jail_on $jail && sub_stop $jail check_jail_on $jail && sub_stop $jail
sub_start $jail sub_start $jail
;; ;;
*) *)
"sub_${subcommand}" $jail "sub_${subcommand}" $jail
;; ;;
esac esac
done done
else else
if [ "${subcommand}" != "restart" ]; then if [ "${subcommand}" != "restart" ]; then
"sub_${subcommand}" $jail "sub_${subcommand}" $jail
else else
check_jail_on $jail && sub_stop $jail check_jail_on $jail && sub_stop $jail
sub_start $jail sub_start $jail
fi fi
fi fi
else else
usage usage
fi fi
;; ;;
"status") "status")
if [ -z "${jail}" ]; then if [ -z "${jail}" ]; then
jails=$(ls $JAILDIR) jails=$(ls $JAILDIR)
for jail in $jails; do for jail in $jails; do
"sub_${subcommand}" $jail "sub_${subcommand}" $jail
done done
else else
"sub_${subcommand}" $jail "sub_${subcommand}" $jail
fi fi
;; ;;
*) *)
shift shift
warning "'${subcommand}' is not a known subcommand." && usage warning "'${subcommand}' is not a known subcommand." && usage
exit 1 exit 1
;; ;;
esac esac
} }
main "$@" main "$@"