#!/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)" # ------------- # - Default values # ------------- # - Give your default values here # - LOGGING=false BATCH_MODE=false DEFAULT_MUNIN_CONF_FILE="/etc/munin/munin-node.conf" DEFAULT_IPT_IPV4_CONF_FILE="/etc/ipt-firewall/main_ipv4.conf" DEFAULT_IPT_IPV6_CONF_FILE="/etc/ipt-firewall/main_ipv6.conf" DEFAULT_IPV4_FIREWALL_SCRIPT="/usr/local/sbin/ipt-firewall-server" DEFAULT_IPV6_FIREWALL_SCRIPT="/usr/local/sbin/ip6t-firewall-server" # ---------- # Base Function(s) # ---------- usage() { [[ -n "$1" ]] && error "$1" [[ $terminal ]] && echo -e " \033[1mUsage:\033[m $(basename $0) [OPTION [OPTION .. \033[1mDescription\033[m Script sets the munin server ip-address at the munin configuration itself and also at firewall configuration (from gitrepository ipt-server). \033[1mOptions\033[m -b Runs script in batch mode. -4 The new IPv4 address for the munin server. -6 The new IPv6 address for the munin server. \033[1mFiles\033[m $conf_file: Configuration file \033[1mExample:\033[m Set IPv4 address of remote munin server to '138.201.33.54' $(basename $0) -4 138.201.33.54 Set IPv4 address of remote munin server to '138.201.33.54' and set also the IPv6 address to '2a01:4f8:171:3493::54' $(basename $0) -4 138.201.33.54 -6 2a01:4f8:171:3493::54 " 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 } todo (){ if $LOGGING || $terminal ; then echo "" if $terminal ; then echo -e " [ \033[33m\033[1mToDo\033[m ] $*" else echo " [ ToDo ] $*" 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 } echo_done() { if $terminal ; then echo -e "\033[80G[ \033[32mdone\033[m ]" fi } echo_ok() { if $terminal ; then echo -e "\033[80G[ \033[32mok\033[m ] " fi } echo_failed(){ if $terminal ; then echo -e "\033[80G[ \033[1;31mfailed\033[m ]" fi } echo_skipped() { if $terminal ; then echo -e "\033[80G[ \033[33m\033[1mskipped\033[m ]" fi } echo_wait(){ if $terminal ; then echo -en "\033[80G[ \033[5m\033[1m...\033[m ]" fi } blank_line() { if $terminal ; then echo "" fi } containsElement () { local e for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done return 1 } # - Remove leading/trailling whitespaces # - trim() { local var="$*" var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters echo -n "$var" } is_valid_ipv4() { local -a octets=( ${1//\./ } ) local RETURNVALUE=0 # return an error if the IP doesn't have exactly 4 octets [[ ${#octets[@]} -ne 4 ]] && return 1 for octet in ${octets[@]} do if [[ ${octet} =~ ^[0-9]{1,3}$ ]] then # shift number by 8 bits, anything larger than 255 will be > 0 ((RETURNVALUE += octet>>8 )) else # octet wasn't numeric, return error return 1 fi done return ${RETURNVALUE} } is_valid_ipv6() { local _ipv6="$1" _regex_ipv6='^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$' if [[ "$_ipv6" =~ ${_regex_ipv6} ]]; then return 0 else return 1 fi } # ---------- # - 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 BATCH_MODE=true fi # - Is 'systemd' supported on this system # - # -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" fi # ---------- # Read Configurations from $conf_file # ---------- if [[ -f "$conf_file" ]]; then source "$conf_file" else warn "No configuration file '$conf_file' present." fi [[ -z "$MUNIN_CONF_FILE" ]] && MUNIN_CONF_FILE="$DEFAULT_MUNIN_CONF_FILE" [[ -z "$IPT_IPV4_CONF_FILE" ]] && IPT_IPV4_CONF_FILE="$DEFAULT_IPT_IPV4_CONF_FILE" [[ -z "$IPT_IPV6_CONF_FILE" ]] && IPT_IPV6_CONF_FILE="$DEFAULT_IPT_IPV6_CONF_FILE" [[ -z "$IPV4_FIREWALL_SCRIPT" ]] && IPV4_FIREWALL_SCRIPT="$DEFAULT_IPV4_FIREWALL_SCRIPT" [[ -z "$IPV6_FIREWALL_SCRIPT" ]] && IPV6_FIREWALL_SCRIPT="$DEFAULT_IPV6_FIREWALL_SCRIPT" # ---------- # - Read commandline parameter # ---------- while getopts 4:6:bh opt ; do case $opt in b) BATCH_MODE=true ;; h) usage ;; 4) new_ipv4=$OPTARG ;; 6) new_ipv6=$OPTARG ;; \?) usage ;; esac done if [[ -n "$new_ipv4" ]] && ! $(is_valid_ipv4 $new_ipv4) ; then if $BATCH_MODE ; then fatal "The given IPv4 address '$new_ipv4' is not a valid!" else warn "The given IPv4 address '$new_ipv4' is not a valid!" new_ipv4="" fi elif ! $BATCH_MODE && [[ -z "$new_ipv4" ]]; then warn "No IPv4 address for new munin server given!" fi if ! $BATCH_MODE && [[ -z "$new_ipv4" ]]; then echo "" echo -e "\033[32m--\033[m" echo "" echo " Insert IPv4 Address of the Munin Server" echo "" echo -e " Type \"\033[33mNone\033[m\" if no IPv4 Address for Munin Server should be assigned" echo "" while [[ -z "$new_ipv4" ]] ; do echononl "IPv4 Munin Server: " read new_ipv4 if [[ -z "$new_ipv4" ]] ; then echo -e "\n \033[33m\033[1mIPv4 Address is required!\033[m\n" continue fi if [[ "${new_ipv4,,}" = "none" ]]; then new_ipv4="" break fi if ! $(is_valid_ipv4 $new_ipv4) ; then echo -e "\n \033[33m\033[1m$new_ipv4 is not a valid IPv4 Address!\033[m\n" new_ipv4="" fi done fi if [[ -n "$new_ipv6" ]] && ! $(is_valid_ipv6 $new_ipv6) ; then if $BATCH_MODE ; then fatal "The given IPv6 address '$new_ipv6' is not a valid!" else warn "The given IPv6 address '$new_ipv6' is not a valid!" new_ipv6="" fi elif ! $BATCH_MODE && [[ -z "$new_ipv6" ]]; then warn "No IPv6 address for new munin server given!" fi if ! $BATCH_MODE && [[ -z "$new_ipv6" ]]; then warn "No IPv6 address for new munin server given!" echo "" echo -e "\033[32m--\033[m" echo "" echo " Insert IPv6 Address of the Munin Server" echo "" echo -e " Type \"\033[33mNone\033[m\" if no IPv6 Address for Munin Server should be assigned" echo "" while [[ -z "$new_ipv6" ]] ; do echononl "IPv6 Munin Server: " read new_ipv6 if [[ -z "$new_ipv6" ]] ; then echo -e "\n \033[33m\033[1mIPv6 Address is required!\033[m\n" continue fi if [[ "${new_ipv6,,}" = "none" ]]; then new_ipv6="" break fi if ! $(is_valid_ipv6 $new_ipv6) ; then echo -e "\n \033[33m\033[1m$new_ipv6 is not a valid IPv6 Address!\033[m\n" new_ipv6="" fi done fi if [[ -z "$new_ipv4" ]] && [[ -z "$new_ipv6" ]] ; then fatal "Neither an IPv4 address nor an IPv6 Address for the new munin server given!" fi if $terminal ; then echo "" echo -e " \033[32m\033[1m----------\033[m" echo "" if [[ -n "$new_ipv4" ]] ; then echo " IPv4 Address of Munin Server.....: $new_ipv4" else echo -e " IPv4 Address of Munin Server.....: \033[33mNone\033[m" fi if [[ -n "$new_ipv6" ]] ; then echo " IPv6 Address of Munin Server.....: $new_ipv6" else echo -e " IPv6 Address of Munin Server.....: \033[33mNone\033[m" fi echo "" echo -e " \033[32m\033[1m----------\033[m" echo "" fi if $terminal && ! $BATCH_MODE ; then echo echo -n " Type upper case 'YES' to start: " read OK if [[ "$OK" != "YES" ]] ; then fatal "Abort by user request - Answer as not 'YES'" fi echo "" fi if [[ -n "$new_ipv4" ]] ; then echononl "Adjust file '$IPT_IPV4_CONF_FILE'.." if [[ ! -f "$IPT_IPV4_CONF_FILE" ]] ; then echo_skipped warn "No IPv4 configuration file '$IPT_IPV4_CONF_FILE' for iptables found." else perl -i.BAK.$backup_date -n -p -e "s/^\s*munin_remote_ip=.*/munin_remote_ip=${new_ipv4}/" $IPT_IPV4_CONF_FILE 2> $log_file if [[ $? -gt 0 ]] ;then echo_falied error "$(cat $log_file)" else echo_ok fi fi fi if [[ -n "$new_ipv6" ]] ; then echononl "Adjust file '$IPT_IPV6_CONF_FILE'.." if [[ ! -f "$IPT_IPV6_CONF_FILE" ]] ; then echo_skipped warn "No IPv6 configuration file '$IPT_IPV6_CONF_FILE' for ip6tables found." else perl -i.BAK.$backup_date -n -p -e "s/^\s*munin_remote_ip=.*/munin_remote_ip=${new_ipv6}/" $IPT_IPV6_CONF_FILE 2> $log_file if [[ $? -gt 0 ]] ;then echo_falied error "$(cat $log_file)" else echo_ok fi fi fi blank_line echononl "Backup existent configuration file '$MUNIN_CONF_FILE'.." if [[ -f "$MUNIN_CONF_FILE" ]]; then mv "$MUNIN_CONF_FILE" "${MUNIN_CONF_FILE}.BAK.${backup_date}" > $log_file 2>&1 if [[ $? -eq 0 ]] ; then echo_ok echononl "Adjust munin configuration file '$MUNIN_CONF_FILE'.." echo_wait _found=false while IFS='' read -r _line || [[ -n $_line ]] ; do if [[ "$_line" =~ ^[[:space:]]*allow[[:space:]]+\^ ]] ; then if ! $_found ; then echo "allow ^127\\.0\\.0\\.1\$" >> "$MUNIN_CONF_FILE" echo "allow ^::1\$" >> "$MUNIN_CONF_FILE" if [[ -n "$new_ipv4" ]] ; then IFS='.' read -r -a ipv4_arr <<< "$new_ipv4" _allow_ipv4_str="allow ^${ipv4_arr[0]}" declare -i i=1 while [[ i -lt ${#ipv4_arr[@]} ]] ; do _allow_ipv4_str="${_allow_ipv4_str}\\.${ipv4_arr[$i]}" ((i++)) done echo "$_allow_ipv4_str\$" >> "$MUNIN_CONF_FILE" fi [[ -n "$new_ipv6" ]] && echo "allow ^$new_ipv6\$" >> "$MUNIN_CONF_FILE" fi _found=true continue fi echo "$_line" >> "$MUNIN_CONF_FILE" done < "${MUNIN_CONF_FILE}.BAK.${backup_date}" echo_ok if $(grep -q -E "^\s*host\s+\*" "$MUNIN_CONF_FILE" 2>/dev/null) ; then primary_inet4_addr="$(ip route get 1 | awk '{print $NF;exit}')" echononl "$MUNIN_CONF_FILE: bind munin to adress '${primary_inet4_addr}'.." perl -i -n -p -e "s/^(\s*host\s+\*.*)/#\1\nhost ${primary_inet4_addr}/" "$MUNIN_CONF_FILE" 2> $log_file if [[ $? -eq 0 ]] ; then echo_ok else echo_failed error "$(cat $log_file)" fi fi else echo_failed error "$(cat $log_file)" fi else echo_skipped warn "No munin configuration file '$MUNIN_CONF_FILE' found." fi # - Restart OpenDKIM # - if $terminal ; then echo "" echo -e " \033[32m-----\033[m" echo "" fi echononl "Restart IPv4 firewall.." echo_wait if $systemd_supported ; then systemctl restart ipt-firewall.service > $log_file 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed error "$(cat $log_file)" fi else $IPV4_FIREWALL_SCRIPT > $log_file 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed error "$(cat $log_file)" fi fi echononl "Restart IPv6 firewall.." echo_wait if $systemd_supported ; then systemctl restart ip6t-firewall.service > $log_file 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed error "$(cat $log_file)" fi else $IPV6_FIREWALL_SCRIPT > $log_file 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed error "$(cat $log_file)" fi fi echononl "Restart munin-node service.." echo_wait if $systemd_supported ; then systemctl restart munin-node > $log_file 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed error "$(cat $log_file)" fi else /etc/init.d/munin-node restart > $log_file 2>&1 if [[ $? -eq 0 ]] ; then echo_ok else echo_failed error "$(cat $log_file)" fi fi blank_line clean_up 0