#!/bin/bash

list_interfaces()
{
    interfaces=$(ls /sys/class/net/ | grep -v lo)
}
num_interfaces()
{
    list_interfaces
    interfaceArray=()
        while read -r name; do
            interfaceArray+=($name)
    done <<< "$interfaces"
    echo ${#interfaceArray[@]}
}
get_if_address()
{
    ip a show $1 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1
}
get_if_netmask()
{
    ip a show $1 | grep "inet\b" | awk '{print $2}' | cut -d/ -f2
}
get_if_gateway()
{
    ip r show | grep -o 'default via [0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+' | grep -o '[0-9].*'
}
get_if_hwaddress()
{
    cat /sys/class/net/$1/address
}
get_dns()
{
    cat /etc/resolv.conf | grep -o 'nameserver [0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+' | grep -o '[0-9].*' | sed ':a;N;$!ba;s/\n/ /g'
}
get_domain()
{
    cat /etc/resolv.conf | grep -o 'search .*' | sed 's/search //'
}
set_hostname()
{
    hostname=$(dialog	--stdout \
			--title "Имя сервера" \
			--backtitle "Настройка параметров сервера" \
			--ok-label "Далее" \
            --no-cancel \
			--inputbox "Введите имя сервера" 15 30 $(hostname))
    echo $hostname
}
netmask_to_prefix()
{
   c=0 x=0$( printf '%o' ${1//./ } )
   while [ $x -gt 0 ]; do
       let c+=$((x%2)) 'x>>=1'
   done
   echo $c
}
valid_ip()
{
    local  ip=$1
    local  stat=1

    if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        OIFS=$IFS
        IFS='.'
        ip=($ip)
        IFS=$OIFS
        [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
            && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
        stat=$?
    fi
    return $stat
}
select_interface()
{
    list_interfaces
    interfaceArray=()
        while read -r name; do
            interfaceArray+=($name "")
    done <<< "$interfaces"
    if [ ${#interfaceArray[@]} -eq 2 ]; then
        interface=${interfaceArray:0}
    else
        interface=$(dialog    --stdout \
                              --title "Сетевые интерфейсы" \
                              --backtitle "Настройка параметров сервера" \
                              --ok-label "Далее" \
                              --no-cancel \
                              --menu "Выберите интерфейс:" \
                              20 30 30 \
                              "${interfaceArray[@]}")
    fi
    echo $interface
}
create_interface_file()
{
cat << EOF >  $1
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback
EOF
}
write_interface_file()
{
#    if [ ! -f $1 ]; then
    cp $1 $1.bak
    create_interface_file $1
#        else
#            cp $1 $1.bak
#    fi
    echo "" >> $1
    echo "$2" >> $1
}
create_astra_routes_file()
{
printf "#!/bin/bash\n# Adding additional routes on connection" > "$1"
chmod +x "$1"
}
create_astra_iptables_files()
{
cat <<EOF > /etc/network/if-post-down.d/iptables
#!/bin/sh
touch /etc/iptables/rules.v4
chmod 640 /etc/iptables/rules.v4
iptables-save > /etc/iptables/rules.v4
exit 0
EOF
chmod +x /etc/network/if-post-down.d/iptables
cat <<EOF > /etc/network/if-pre-up.d/iptables
#!/bin/sh
iptables-restore < /etc/iptables/rules.v4
exit 0
EOF
chmod +x /etc/network/if-pre-up.d/iptables
}
static_route()
{
    if [ $os == "AstraLinux" ]; then
        r_file="/etc/network/if-up.d/routes"
        if [ ! -f $r_file ]; then
            create_astra_routes_file $r_file
        fi
    fi
    out_r=""
    if (dialog  --title "Настройка интерфейса $if" \
                --backtitle "Настройка параметров сервера" \
                --defaultno \
                --yesno "Добавить статические маршруты для этого интерфейса?" 10 60) then
        n=$(dialog --stdout \
            --backtitle "Настройка параметров сервера" \
            --title "Статические маршруты" \
            --inputbox "Количество добавляемых маршрутов" 10 30 )
        for i in $(seq $n); do
            IFS=$'\n' read -r -d '' route gw < <(dialog	--stdout \
                --title "Настройка интерфейса $if" \
                --backtitle "Настройка параметров сервера" \
                --ok-label "Да" \
                --form "Параметры" 15 65 0 \
                "Сеть назначения:" 1 1	"" 	1 17 20 0 \
                "Шлюз:"    1 38	""  	1 44 17 0 \
                )
            IFS=$'/' r_parts=($route)
            if valid_ip $gw && valid_ip ${r_parts[0]} && [ ${r_parts[1]} -le 32 ]; then
                if [ $os == "Debian" ]; then
                    out_r+=$(printf "\n\tpost-up ip route add $route via $gw dev $if\n\tpost-down ip route del $route via $gw dev $if")
                else
                    printf "\nroute add -net $route gw $gw dev $if" >> "$r_file"
                fi
            else
                error_dialog
            fi
        done
        result_if+=$out_r
    fi
}
error_dialog()
{
    dialog  --backtitle "Настройка параметров сервера" \
            --title "Настройка интерфейса $if" \
            --msgbox  "Ошибка во введённых данных" 10 35
}
config_interface()
{
    error=false
    if="$1"
    result_rc=""
    if (dialog  --backtitle "Настройка параметров сервера" \
                --yesno "Интерфейс $if будет получать настройки по DHCP?" 10 60) then
        result_if=$(printf "\nauto $if\nallow-hotplug $if\niface $if inet dhcp")
        #static_route
        write_interface_file $if_file "$result_if"
    else
        address="$2"
        netmask="$3"
        gateway="$4"
        hwaddress="$5"
        dns_serv=($6)
        domain="$7"
        sed -i "/$address/d" /etc/hosts
        IFS=$'\n' read -r -d '' address netmask gateway n_hwaddress domain ns_serv0 ns_serv1 ns_serv2  < <(dialog	--stdout \
			--title "Настройка интерфейса $if" \
			--backtitle "Настройка параметров сервера" \
			--ok-label "Да" \
            --form "Параметры" 15 70 0 \
            "Адрес:"      1 1     "$address"      1 24 16 0 \
            "Маска сети или префикс:" 2 1	  "$netmask"      2 24 16 0 \
            "Шлюз:"      3 1	    "$gateway"      3 24 16 0 \
            "MAC адрес:"    4 1     "$hwaddress"    4 24 18 0 \
            "Домен:"	    5 1     "$domain"	    5 24 32 0 \
            "DNS сервер 1:"  6 1     "${dns_serv[0]}"     6 24 16 0 \
            "DNS сервер 2:"  7 1     "${dns_serv[1]}"     7 24 16 0 \
            "DNS сервер 3:"  8 1     "${dns_serv[2]}"     8 24 16 0 \
            )
        if valid_ip $address; then
            result_if=$(printf "\nallow-hotplug $if \niface $if inet static\n\taddress $address")
            ipaddr=$address
            sed -i "/127.0.0.1/a $address $h_name" /etc/hosts
        else
            error=true
        fi
        if [[ "$netmask" =~ ^(((255\.){3}(255|254|252|248|240|224|192|128|0+))|((255\.){2}(255|254|252|248|240|224|192|128|0+)\.0)|((255\.)(255|254|252|248|240|224|192|128|0+)(\.0+){2})|((255|254|252|248|240|224|192|128|0+)(\.0+){3}))$ ]]; then
            prefix=$(netmask_to_prefix $netmask)
            ipaddr+=$(printf "/$prefix")
            result_if+=$(printf "/$prefix")
        elif [ "$netmask" -le 32 ]; then
            result_if+=$(printf "/$netmask")
            ipaddr+=$(printf "/$netmask")
        else
            error=true
        fi
        if [ -n "$gateway" ] && valid_ip $gateway ; then
            result_if+=$(printf "\n\tgateway $gateway")
        fi
        if [ -n "$hwaddress" ] && [ "$hwaddress" != "$n_hwaddress" ]; then
            result_if+=$(printf "\n\thwaddress $n_hwaddress")
        fi
        if [ $os == "Debian" ]; then
            if [ -n "$domain" ]; then
                result_rc+=$(printf "search $domain")
            fi
            if [ -n "$ns_serv0" ] && valid_ip $ns_serv0; then
                result_rc+=$(printf "\nnameserver $ns_serv0")
            fi
            if [ -n "$ns_serv1" ] && valid_ip $ns_serv1; then
                result_rc+=$(printf "\nnameserver $ns_serv1")
            fi
            if [ -n "$ns_serv2" ] && valid_ip $ns_serv2; then
                result_rc+=$(printf "\nnameserver $ns_serv2")
            fi
            echo "$result_rc" > "$resolvconf"
        else
            if [ -n "$ns_serv0" ] && valid_ip $ns_serv0; then
                result_if+=$(printf "\n\tdns-nameservers $ns_serv0")
            fi
            if [ -n "$ns_serv1" ] && valid_ip $ns_serv1; then
                result_if+=$(printf " $ns_serv1")
            fi
            if [ -n "$ns_serv2" ] && valid_ip $ns_serv2; then
                result_if+=$(printf " $ns_serv2")
            fi
            if [ -n "$domain" ]; then
                result_if+=$(printf "\n\tdns-search $domain")
            fi
        fi
        if $error; then
            error_dialog
        else
            static_route
            echo "$result_if" >> "$if_file"
            ip addr add $(printf "$ipaddr dev $if")
        fi
    fi
}
config_ntp()
{
    ntp_srv=$(dialog	--stdout \
			--title "NTP сервер" \
			--backtitle "Настройка параметров сервера" \
			--ok-label "Далее" \
			--inputbox "Введите IP или доменное имя NTP сервера" 15 30 )
    echo $ntp_srv
}

if [ -f .bash_login ]; then
    rm -f .bash_login
fi
if ! which dialog > /dev/null; then
    apt update
    apt -y install dialog
fi
h_name=$(set_hostname)
hostnamectl set-hostname $h_name
ntpconf="/etc/systemd/timesyncd.conf"
if (dialog  --title "NTP сервер" \
            --backtitle "Настройка параметров сервера" \
            --yesno "Вы хотите синхронизировать время с собственным NTP сервером?" 10 60) then
    if [ -f /usr/sbin/ntpd ]; then
        apt -y purge ntp
    fi
    ntp="$(config_ntp)"
    if grep $ntp $ntpconf
    then
        dialog  --backtitle "Настройка параметров сервера" \
                --title "NTP сервер" \
                --msgbox  "Этот сервер уже присутствует в конфигурации" 10 25
    else
        printf "NTP=$ntp\n" >> $ntpconf
    fi
fi
if_file="/etc/network/interfaces"
cp $if_file $if_file.bak
create_interface_file "$if_file"
os=$(lsb_release -si)
tcp_ports=(22 53 80 88 137 443 445 9092 9093)
udp_ports=(53 123 137 1812 1813 2000)

while : ; do
    resolvconf="/etc/resolv.conf"
    if="$(select_interface)"
#    if grep $if $if_file
#        then
#            dialog  --backtitle "Настройка параметров сервера" \
#                    --title "Настройка интерфейса $if" \
#                    --msgbox  "Этот интерфейс уже настроен" 10 25
#        else
            config_interface "$if" "$(get_if_address $if)" "$(get_if_netmask $if)" "$(get_if_gateway)" "$(get_if_hwaddress $if)" "$(get_dns)" "$(get_domain)"
#    fi
    if [ $(num_interfaces) -eq 1 ]; then
        break
    fi
    if (dialog  --title "Конец" \
                --backtitle "Настройка параметров сервера" \
                --yesno "Вы хотите настроить другой интерфейс?" 10 60) then
        continue
    else
        break
    fi
done
if (dialog --title "Настройка фаерволла" \
        --backtitle "Настройка параметров сервера" \
        --defaultno \
        --yesno "Вы хотите применть стандартные правила фаерволла(будут открыты порты tcp ${tcp_ports[*]} и udp ${udp_ports[*]})?" 10 60) then
    if [[ -z $(which iptables) ]]; then
        if (dialog --title "Настройка фаерволла" \
                --backtitle "Настройка параметров сервера" \
                --yesno "Iptables не найден в системе. Установить?\nNFTables будет удалён." 10 60) then
                clear
                apt -y remove --auto-remove nftables
                apt -y purge nftables
                apt update
                apt -y install iptables iptables-persistent
        fi
    fi
    if [ ! -d /etc/iptables ]; then
        mkdir /etc/iptables
    fi
    iptables -F
    iptables -A INPUT -i lo -j ACCEPT
    iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
    for port in ${tcp_ports[@]}
    do
    iptables -A INPUT -p tcp --dport $port -j ACCEPT
    done
    for port in ${udp_ports[@]}
    do
    iptables -A INPUT -p udp --dport $port -j ACCEPT
    done
    iptables -P INPUT DROP
    iptables-save > /etc/iptables/rules.v4
    if [ $os == "AstraLinux" ] && [ ! -f /etc/network/if-post-down.d/iptables ]; then
        create_astra_iptables_files
    fi
fi
if (dialog  --title "Корпоративная авторизация" \
        --backtitle "Настройка параметров сервера" \
        --yesno "Вы будете использовать корпоративную авторизацию (Active Directory, FreeIPA)?" 10 60) then
    systemctl enable adctool
else
    systemctl disable adctool
fi
if (dialog --title "Настройка кластера" \
        --backtitle "Настройка параметров сервера" \
        --yesno "Вы хотите настроить кластеризацию?" 10 60) then
    ./wnam-cluster-config.sh
fi
dialog  --backtitle "Настройка параметров сервера" \
        --title "Скрипты" \
        --msgbox  "Для удобства обслуживания системы в каталоге /home/sysadmin находятся следующие скрипты:\n\n
        srvconfig.sh - этот скрипт                     \n
        upgrade-adctool.sh - скрипт обновления службы интеграции с MS Active Directory\n
        upgrade-wnam.sh - скрипт обновления службы WNAM                  \n
        wnam-cluster-config.sh - скрипт настройки кластера               " 11 95
if (dialog  --title "Настройка завершена" \
        --backtitle "Настройка параметров сервера" \
        --yesno "Вы хотите перезагрузить сервер?" 10 60) then
    clear
    killall java
    reboot
else
    clear
fi
