#!/usr/bin/env bash script_name="$(basename $(realpath $0))" working_dir="$(dirname $(realpath $0))" conf_file="${working_dir}/conf/${script_name%%.*}.conf" LOCK_DIR="/tmp/$(basename $0).$$.LOCK" log_file="${LOCK_DIR}/${script_name%%.*}.log" backup_date="$(date +%Y-%m-%d-%H%M)" declare -a files_backuped_arr=() declare -a dirs_backuped_arr=() declare -a rm_local_files_arr=() declare -a rm_local_dirs_arr=() # ---------- # Base Function(s) # ---------- usage() { [[ -n "$1" ]] && error "$1" if [[ $terminal ]] ; then cat< [ -u -d ] Example: `basename $0` -h wf.oopen.de -u chris -d /home/chris/devel/git/git.oopen.de/o.open/Office_Networks WF network-name possible values are: NONE-WF NONE-CKUBU NONE-CKUBU2 NONE-CKUBU3 123 AK AKB ANW-URB ANW-KM ANW-KB B3-Bornim BLKR CKUBU EBS ELSTER FHXB FLR-BRB GA-AL GA-Ersatz GA-NH GA-Schloss JONAS iRights Kanzlei-Kiel MBR OOLM OPP SPR-BE WF EOF fi clean_up 1 } clean_up() { # Perform program exit housekeeping rm -rf "$LOCK_DIR" blank_line exit $1 } echononl(){ if $terminal ; then echo X\\c > /tmp/shprompt$$ if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then echo -e -n " $*\\c" 1>&2 else echo -e -n " $*" 1>&2 fi rm /tmp/shprompt$$ fi } fatal(){ echo "" if $terminal ; then echo -e " [ \033[31m\033[1mFatal\033[m ] $*" else echo -e " [ Fatal ] $*" fi echo "" if $terminal ; then echo -e " \033[1mScript terminated\033[m.." else echo -e " Script terminated.." fi echo "" rm -rf $LOCK_DIR exit 1 } error (){ echo "" if $terminal ; then echo -e " [ \033[31m\033[1mError\033[m ] $*" else echo " [ Error ] $*" fi echo "" } warn (){ if $LOGGING || $terminal ; then echo "" if $terminal ; then echo -e " [ \033[33m\033[1mWarn\033[m ] $*" else echo " [ Warn ] $*" fi echo "" fi } info (){ if $LOGGING || $terminal ; then echo "" if $terminal ; then echo -e " [ \033[32m\033[1mInfo\033[m ] $*" else echo " [ Info ] $*" fi echo "" fi } ok (){ if $LOGGING || $terminal ; then echo "" if $terminal ; then echo -e " [ \033[32m\033[1mOk\033[m ] $*" else echo " [ Ok ] $*" fi echo "" fi } echo_done() { if $terminal ; then echo -e "\033[75G[ \033[32mdone\033[m ]" fi } echo_ok() { if $terminal ; then echo -e "\033[75G[ \033[32mok\033[m ]" fi } echo_failed(){ if $terminal ; then echo -e "\033[75G[ \033[1;31mfailed\033[m ]" fi } echo_skipped() { if $terminal ; then echo -e "\033[75G[ \033[33m\033[1mskipped\033[m ]" fi } trim() { local var="$*" var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters echo -n "$var" } blank_line() { if $terminal ; then echo "" fi } # - Backup file or directory # - backup() { is_directory=false if [[ -z "$1" ]] ; then error "No file/directory for backup given!" return elif [[ -h "$1" ]] ; then _source="$(realpath $1)" warn "'$1' is a symlink to $_source." elif [[ ! -d "$1" ]] && [[ ! -f "$1" ]] ; then warn "'$1' not found. Backup skipped." return else _source="$(realpath $1)" fi if [[ -d "$_source" ]]; then is_directory=true echononl "Backup directory '$_source' .." else echononl "Backup file '$_source' .." fi cp -a "$_source" "${_source}.$backup_date" > $log_file 2>&1 if [[ $? -eq 0 ]] ; then echo_ok if $is_directory ; then dirs_backuped_arr+=("$_source") else files_backuped_arr+=("$_source") fi else echo_failed error "$(cat "$log_file")" fi } # - Remove script generated backups, if source wasn't changed # - rm_unchanged_backup() { if [[ ${#files_backuped_arr[@]} -gt 0 ]] ; then for _file in "${files_backuped_arr[@]}" ; do if $(diff "$_file" "${_file}.$backup_date" > /dev/null 2>&1) ; then echononl "File '$(basename "${_file}")' wasn't changed.\n Delete the previous generated backup. .." rm "${_file}.$backup_date" > "$log_file" 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi blank_line fi done fi if [[ ${#dirs_backuped_arr[@]} -gt 0 ]] ; then for _dir in "${dirs_backuped_arr[@]}" ; do if $(diff -Nur "$_dir" "${_dir}.$backup_date" > /dev/null 2>&1) ; then echononl "Directory '$(basename "${_dir}")' wasn't changed.\n Delete the previous generated backup. .." rm -rf "${_dir}.$backup_date" > "$log_file" 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi blank_line fi done fi } remove_local_files() { if [[ ${#rm_local_files_arr[@]} -gt 0 ]] ; then for _file in "${rm_local_files_arr[@]}" ; do echononl "Remove local file '$(basename "$_file")' .." if [[ -f "$_file" ]] ; then rm "$_file" > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi else echo_skipped fi done fi } remove_local_dir() { if [[ ${#rm_local_dirs_arr[@]} -gt 0 ]] ; then for _dir in "${rm_local_dirs_arr[@]}" ; do echononl "Remove local directory '$(basename "$_dir")' .." if [[ -d "$_dir" ]] ; then rm -rf "$_dir" > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi else echo_skipped fi done fi } manage_files() { for file in $* ; do blank_line echononl "Get file '${_network}-config/$file' .." if ssh -l $REMOTE_USER ${REMOTE_HOST} [ -f ${_network}-config/$file ] ; then scp -o User=$REMOTE_USER ${REMOTE_HOST}:${_network}-config/$file . > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok echononl "Remove remote file '${_network}-config/$file' .." ssh -l $REMOTE_USER ${REMOTE_HOST} "rm ${_network}-config/$file" > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi else echo_failed error "$(cat "$log_file")" fi else echo_skipped if [[ -f "${OFFICE_DIR}/$file" ]] ; then echononl "Remove local file '$file' .." rm "${OFFICE_DIR}/$file" > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi fi fi done } manage_archives() { for archive in $* ; do blank_line echononl "Get archive '${_network}-config/$archive' .." if ssh -l $REMOTE_USER ${REMOTE_HOST} [ -f "${_network}-config/$archive" ]; then scp -o User=$REMOTE_USER ${REMOTE_HOST}:${_network}-config/$archive . > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok echononl "Unpack archive '$archive' .." gunzip < $archive | tar -xpf - > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok echononl "Remove downloaded archive '$archive' .." rm -f "$archive" > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi echononl "Remove remote archive '$archive' .." ssh -l $REMOTE_USER ${REMOTE_HOST} "rm ${_network}-config/$archive" > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi else echo_failed error "$(cat "$log_file")" fi else echo_failed error "$(cat "$log_file")" fi else echo_skipped if [[ "$archive" = "root-dot-opennvpndir_NONE-WF.tar.gz" ]] ; then _dir=".openvpn " elif [[ "$archive" = "etc_check_net_NONE-WF.tar.gz" ]] ; then _dir="check_net" else archive_suffix="${archive%%.*}" _tmp_name="${archive_suffix%_*}" _dir="${_tmp_name##*_}" fi if [[ -d "${OFFICE_DIR}/$_dir" ]] ; then echononl "Remove local directory '$_dir' .." rm -rf "${OFFICE_DIR}/$_dir" > $log_file 2>&1 if [[ $? -eq 0 ]]; then echo_ok else echo_failed error "$(cat "$log_file")" fi fi fi done } # ---------- # - Jobhandling # ---------- # - Run 'clean_up' for signals SIGHUP SIGINT SIGTERM # - trap clean_up SIGHUP SIGINT SIGTERM # - Create lock directory '$LOCK_DIR" # mkdir "$LOCK_DIR" # ---------- # - Some checks .. # ---------- # - Running in a terminal? # - if [[ -t 1 ]] ; then terminal=true else terminal=false fi # -Is systemd supported on this system? # - systemd_supported=false systemd=$(which systemd) systemctl=$(which systemctl) if [[ -n "$systemd" ]] && [[ -n "$systemctl" ]] ; then systemd_supported=true fi # - Print help? # - if [[ "$(trim $*)" = "-h" ]] || [[ "$(trim $*)" = "--help" ]] ; then usage fi if [[ -z "$(which basename)" ]]; then fatal 'It seems "basename" is not installed, but needed!' fi if [[ -z "$(which realpath)" ]]; then fatal 'It seems "realpath" is not installed, but needed!' fi # ========== # - Begin Main Script # ========== # ---------- # - Headline # ---------- if $terminal ; then echo "" echo -e "\033[1m----------\033[m" echo -e "\033[32m\033[1mRunning script \033[m\033[1m$script_name\033[32m .. \033[m" echo -e "\033[1m----------\033[m" echo "" fi # ---------- # Read Configurations from $conf_file # ---------- # - Give your default values here # - LOGGING=false BATCH_MODE=false DEFAULT_OFFICE_BASE_DIR="$HOME/Office_Networks" DEFAULT_REMOTE_USER="chris" echononl "Read configuration file '$(basename "$conf_file")' .." if [[ -f "$conf_file" ]]; then source "$conf_file" if [[ $? -eq 0 ]]; then echo_ok else echo_failed fi else echo_skipped warn "No configuration file '$conf_file' present.\n Loading default values.." fi # ---------- # - Read commandline parameter # ---------- while getopts d:h:u: opt ; do case $opt in h) REMOTE_HOST="$OPTARG" ;; u) REMOTE_USER="$OPTARG" ;; d) OFFICE_BASE_DIR="$OPTARG" ;; *) usage ;; esac done [[ -z "$REMOTE_USER" ]] && REMOTE_USER="$DEFAULT_REMOTE_USER" [[ -z "$OFFICE_BASE_DIR" ]] && OFFICE_BASE_DIR="$DEFAULT_OFFICE_BASE_DIR" if [ -z "$REMOTE_HOST" ]; then usage "Remote host not given" fi shift `expr $OPTIND - 1` [ $# -ne "1" ] && usage "wrong number of arguments" _network=$1 OFFICE_DIR=${OFFICE_BASE_DIR}/${_network} if [[ "$_network" != "NONE-WF" ]] \ && [[ "$_network" != "NONE-CKUBU" ]] \ && [[ "$_network" != "NONE-CKUBU2" ]] \ && [[ "$_network" != "NONE-CKUBU3" ]] \ && [[ "$_network" != "123" ]] \ && [[ "$_network" != "AK" ]] \ && [[ "$_network" != "AKB" ]] \ && [[ "$_network" != ""ANW-URB ]] \ && [[ "$_network" != "ANW-KM" ]] \ && [[ "$_network" != "ANW-Kb" ]] \ && [[ "$_network" != "B3-Bornim" ]] \ && [[ "$_network" != "BLKR" ]] \ && [[ "$_network" != "CKUBU" ]] \ && [[ "$_network" != "RBS" ]] \ && [[ "$_network" != "FLR-BRB" ]] \ && [[ "$_network" != "GA-AL" ]] \ && [[ "$_network" != "GA-Ersatz" ]] \ && [[ "$_network" != "GA-NH" ]] \ && [[ "$_network" != "GA-Schloss" ]] \ && [[ "$_network" != "JONAS" ]] \ && [[ "$_network" != "iRights" ]] \ && [[ "$_network" != "Kanzlei-Kiel" ]] \ && [[ "$_network" != "MBR" ]] \ && [[ "$_network" != "OOLM" ]] \ && [[ "$_network" != "OPP" ]] \ && [[ "$_network" != "ReachOut" ]] \ && [[ "$_network" != "SPR-BE" ]] \ && [[ "$_network" != "WF" ]] ;then usage "Wrong network '$_network'!" fi if $terminal ; then echo "" echo "" echo -e " \033[1mMain part of script ..\033[m" echo "" fi declare -i remote_dir_count="$(ssh $REMOTE_HOST "ls -A ${_network}-config 2> /dev/null | wc -l")" if [[ $remote_dir_count -lt 1 ]]; then fatal "Remote Directory is empty. Run \033[1mcopy_gateway-config.sh ${_network}\033[m on remote host first." fi mkdir -p $OFFICE_DIR cd $OFFICE_DIR # - Nameserver Bind # - /etc/bind/* # - manage_archives bind_${_network}.tar.gz # - OpenVPN: # - /etc/openvpn/* # - # - /root/.openvpn # - archives="openvpn_${_network}.tar.gz root-dot-opennvpndir_${_network}.tar.gz" manage_archives $archives # - DynDNS # - # - /etc/ddclient.conf # - manage_files ddclient.conf.${_network} # - DHCP Server # - # - /etc/dhcp/dhcpd.conf - /etc/dhcp3/dhcpd.conf # - /etc/dhcp/dhcpd6.conf - /etc/dhcp3/dhcpd6.conf # - # - hosts.lan.conf # dhcp failover kanzlei kiel # - hosts.w-lan.conf # dhcp failover kanzlei kiel # - # - /etc/init.d/isc-dhcp6-server # - files="dhcpd.conf.${_network} dhcpd6.conf.${_network} isc-dhcp6-server.${_network} hosts.lan.conf.${_network} hosts.w-lan.conf.${_network} default_isc-dhcp-server.${_network}" manage_files "$files" # - DSL PPP # - # - /etc/ppp/peers/* # - # - /etc/ppp/pap-secrets # - /etc/ppp/chap-secrets # - # - /etc/ppp/ip-up.d/email_notice # - manage_files pap-secrets.${_network} chap-secrets.${_network} email_notice.${_network} manage_archives etc_ppp_peers_${_network}.tar.gz # - Postfix SMTP # - # - /etc/postfix/main.cf # - /etc/mailname # - /etc/postfix/generic # - /etc/postfix/generic.db # - /etc/postfix/sasl_passwd # - /etc/postfix/sasl_passwd.db # - files="main.cf.${_network} mailname.${_network} sasl_passwd.${_network} sasl_passwd.db.${_network} generic.${_network} generic.db.${_network}" manage_files $files # - Netzwerk: # - /etc/hostname # - /etc/hosts # - /etc/network/interfaces # - /etc/resolv.conf files="hostname.${_network} hosts.${_network} interfaces.${_network} resolv.conf.${_network} hostapd.conf.${_network}" manage_files $files # - /root/bin directory # - manage_archives root_bin_${_network}.tar.gz # - /usr/local/src directory # - manage_archives usr_local_src_${_network}.tar.gz # - /usr/local/sbin directory # - manage_archives usr_local_sbin_${_network}.tar.gz # - Firewall # - # - /etc/systemd/system/ipt-firewall.service # - /etc/systemd/system/ip6t-firewall.service # - # - /etc/init.d/ipt-firewall # - /etc/init.d/ipt-firewall # - # - /etc/ipt-firewall/* # - manage_archives etc_ipt-firewall_${_network}.tar.gz files="ipt-firewall.service.${_network} ip6t-firewall.service.${_network} ipt-firewall.${_network} ip6t-firewall.${_network} ipt-firewall-gateway.${_network} ip6t-firewall-gateway.${_network}" manage_files $files # - Check Script Onlinestatus # - # - /etc/systemd/system/check_net.service # - # - /usr/local/sbin/check_net.sh # - /usr/local/sbin/netconfig.sh # - # - /etc/check_net/* # - # - /etc/logrotate.d/check_net # - manage_archives etc_check_net_${_network}.tar.gz files="check_net.service.${_network} check_net-logrotate.${_network}" manage_files $files # - Other # - # - /etc/rc.local # - /var/spool/cron/crontabs/root # - /usr/local/igmpproxy/etc/igmpproxy.conf # - /etc/aiccu.conf # - /etc/default/aiccu # - /etc/radvd.conf # - files="rc.local.${_network} cron_root.${_network} igmpproxy.conf.${_network} aiccu.conf.${_network} aiccu.${_network} radvd.conf.${_network}" manage_files $files cat < $OFFICE_DIR/README.txt ------- Notice: ------- You have to change some configuration files becaus the because the configuration of network interfaces must not be equal. !! Take care, to use the right device names !! Maybe they are called i.e. 'enp0sXX', but you can rename it. See also : README.rename.netdevices For the backup gateway host: eth1 --> LAN eth2 --> WAN or ppp0 (DSL device) eth0 --> WLAN or second LAN or what ever or br0 --> WLAN or second LAN or what ever So you have to change the following files dsl-provider.${_network}: ppp0 comes over eth2 interfaces.${_network}: see above default_isc-dhcp-server.${_network} ipt-firewall.${_network}: LAN device (mostly $local_if_1) = eth1 second LAN WLAN or what ever (if present) = eth0 EOF cat $OFFICE_DIR/README.txt #rm /tmp/README$$ clean_up 0