#!/bin/bash

set -e

# ============================================================
# CONFIGURAÇÃO DE REDE / GATEWAY - DEBIAN 13
#
# - Detecta interfaces de rede
# - Recria /etc/network/interfaces
# - DHCP / Estático / Não configurar por interface
# - Pergunta se a máquina será gateway
# - Permite selecionar a interface de saída (WAN)
# - Ativa IPv4 forwarding permanentemente
# - Configura nftables
# - Configura masquerade (NAT) permanentemente
#
# Compatível com:
#
# curl -fsSL URL | bash
#
# ============================================================


# ============================================================
# FUNÇÕES
# ============================================================

read_tty() {
    local prompt="$1"
    local varname="$2"

    read -rp "$prompt" "$varname" < /dev/tty
}


valid_ipv4() {
    local ip="$1"
    local IFS=.
    local -a octets

    read -ra octets <<< "$ip"

    [ "${#octets[@]}" -eq 4 ] || return 1

    for octet in "${octets[@]}"; do

        [[ "$octet" =~ ^[0-9]+$ ]] || return 1

        [ "$octet" -ge 0 ] 2>/dev/null || return 1
        [ "$octet" -le 255 ] 2>/dev/null || return 1

    done

    return 0
}


yes_answer() {

    case "$1" in
        s|S|sim|SIM|Sim|y|Y|yes|YES|Yes)
            return 0
            ;;
        *)
            return 1
            ;;
    esac
}


# ============================================================
# ROOT
# ============================================================

if [ "$EUID" -ne 0 ]; then

    echo
    echo "ERRO: execute este script como root."
    echo

    exit 1

fi


# ============================================================
# CABEÇALHO
# ============================================================

clear 2>/dev/null || true

echo
echo "============================================================"
echo " CONFIGURAÇÃO DE REDE - DEBIAN 13"
echo "============================================================"
echo


# ============================================================
# VERIFICA NFTABLES
# ============================================================

if ! command -v nft >/dev/null 2>&1; then

    echo "ERRO: nftables não está instalado."
    echo
    echo "Instale antes com:"
    echo
    echo "  apt update"
    echo "  apt install nftables"
    echo

    exit 1

fi


# ============================================================
# DETECTA INTERFACES
# ============================================================

mapfile -t INTERFACES < <(
    find /sys/class/net \
        -mindepth 1 \
        -maxdepth 1 \
        -printf '%f\n' |
        grep -v '^lo$' |
        grep -Ev '^(docker|br-|veth|virbr|tun|tap)' |
        sort
)


if [ "${#INTERFACES[@]}" -eq 0 ]; then

    echo "ERRO: nenhuma interface de rede encontrada."

    exit 1

fi


echo "Interfaces encontradas:"
echo


for IFACE in "${INTERFACES[@]}"; do

    MAC="desconhecido"
    STATE="desconhecido"

    if [ -f "/sys/class/net/$IFACE/address" ]; then
        MAC=$(cat "/sys/class/net/$IFACE/address")
    fi

    if [ -f "/sys/class/net/$IFACE/operstate" ]; then
        STATE=$(cat "/sys/class/net/$IFACE/operstate")
    fi

    echo "Interface : $IFACE"
    echo "MAC       : $MAC"
    echo "Estado    : $STATE"
    echo

done


# ============================================================
# CONFIRMAÇÃO
# ============================================================

echo "ATENÇÃO:"
echo
echo "O arquivo /etc/network/interfaces será recriado."
echo

read_tty "Deseja continuar? [S/n]: " CONFIRM


case "$CONFIRM" in

    n|N|nao|não|NAO|NÃO)

        echo
        echo "Operação cancelada."
        exit 0
        ;;

esac


# ============================================================
# BACKUP
# ============================================================

BACKUP_DIR="/root/network-backup-$(date +%Y%m%d-%H%M%S)"

mkdir -p "$BACKUP_DIR"


if [ -f /etc/network/interfaces ]; then

    cp -a /etc/network/interfaces \
        "$BACKUP_DIR/interfaces"

fi


if [ -f /etc/nftables.conf ]; then

    cp -a /etc/nftables.conf \
        "$BACKUP_DIR/nftables.conf"

fi


echo
echo "Backup:"
echo "$BACKUP_DIR"
echo


# ============================================================
# CRIA /etc/network/interfaces
# ============================================================

cat > /etc/network/interfaces <<'EOF'
# ============================================================
# Configuração de rede
# Gerada automaticamente
# ============================================================

auto lo
iface lo inet loopback

EOF


# ============================================================
# INTERFACES CONFIGURADAS
# ============================================================

CONFIGURED_INTERFACES=()


# ============================================================
# CONFIGURA CADA INTERFACE
# ============================================================

for IFACE in "${INTERFACES[@]}"; do

    MAC="desconhecido"

    if [ -f "/sys/class/net/$IFACE/address" ]; then
        MAC=$(cat "/sys/class/net/$IFACE/address")
    fi


    echo
    echo "============================================================"
    echo " INTERFACE: $IFACE"
    echo " MAC:       $MAC"
    echo "============================================================"
    echo
    echo "1) DHCP"
    echo "2) IP estático"
    echo "3) Não configurar"
    echo


    while true; do

        read_tty "Escolha [1/2/3]: " OPTION


        case "$OPTION" in

            # ====================================================
            # DHCP
            # ====================================================

            1)

                cat >> /etc/network/interfaces <<EOF

# ------------------------------------------------------------
# Interface $IFACE - DHCP
# ------------------------------------------------------------

auto $IFACE
allow-hotplug $IFACE
iface $IFACE inet dhcp

EOF

                CONFIGURED_INTERFACES+=("$IFACE")

                echo
                echo "$IFACE configurada como DHCP."

                break
                ;;


            # ====================================================
            # ESTÁTICO
            # ====================================================

            2)

                echo
                echo "Configuração estática de $IFACE"
                echo


                # ------------------------------------------------
                # IP
                # ------------------------------------------------

                while true; do

                    read_tty "Endereço IPv4: " IPADDR

                    if valid_ipv4 "$IPADDR"; then
                        break
                    fi

                    echo "Endereço IPv4 inválido."

                done


                # ------------------------------------------------
                # PREFIXO
                # ------------------------------------------------

                while true; do

                    read_tty "Prefixo [ex.: 24]: " PREFIX

                    if [[ "$PREFIX" =~ ^[0-9]+$ ]] &&
                       [ "$PREFIX" -ge 0 ] &&
                       [ "$PREFIX" -le 32 ]; then

                        break

                    fi

                    echo "Prefixo inválido."

                done


                # ------------------------------------------------
                # GATEWAY
                # ------------------------------------------------

                while true; do

                    read_tty "Gateway [ENTER para nenhum]: " GATEWAY

                    if [ -z "$GATEWAY" ]; then
                        break
                    fi

                    if valid_ipv4 "$GATEWAY"; then
                        break
                    fi

                    echo "Gateway inválido."

                done


                # ------------------------------------------------
                # DNS
                # ------------------------------------------------

                while true; do

                    read_tty "DNS [ex.: 172.16.0.2 8.8.8.8] [ENTER para nenhum]: " DNS

                    if [ -z "$DNS" ]; then
                        break
                    fi

                    DNS_VALID=1

                    for DNS_IP in $DNS; do

                        if ! valid_ipv4 "$DNS_IP"; then
                            DNS_VALID=0
                            break
                        fi

                    done


                    if [ "$DNS_VALID" -eq 1 ]; then
                        break
                    fi

                    echo "DNS inválido."

                done


                # ------------------------------------------------
                # DNS SEARCH
                # ------------------------------------------------

                read_tty "Domínio de pesquisa DNS [ENTER para nenhum]: " DNS_SEARCH


                # ------------------------------------------------
                # GRAVA
                # ------------------------------------------------

                cat >> /etc/network/interfaces <<EOF

# ------------------------------------------------------------
# Interface $IFACE - ESTÁTICA
# ------------------------------------------------------------

auto $IFACE
allow-hotplug $IFACE
iface $IFACE inet static
    address $IPADDR/$PREFIX
EOF


                if [ -n "$GATEWAY" ]; then

                    echo "    gateway $GATEWAY" \
                        >> /etc/network/interfaces

                fi


                if [ -n "$DNS" ]; then

                    echo "    dns-nameservers $DNS" \
                        >> /etc/network/interfaces

                fi


                if [ -n "$DNS_SEARCH" ]; then

                    echo "    dns-search $DNS_SEARCH" \
                        >> /etc/network/interfaces

                fi


                CONFIGURED_INTERFACES+=("$IFACE")


                echo
                echo "$IFACE configurada com IP estático."

                break
                ;;


            # ====================================================
            # NÃO CONFIGURAR
            # ====================================================

            3)

                echo
                echo "$IFACE não será configurada."

                break
                ;;


            *)

                echo
                echo "Opção inválida."
                ;;

        esac

    done

done


chmod 644 /etc/network/interfaces


# ============================================================
# GATEWAY
# ============================================================

echo
echo "============================================================"
echo " CONFIGURAÇÃO DE GATEWAY"
echo "============================================================"
echo

read_tty "Esta máquina será gateway para outras redes? [s/N]: " IS_GATEWAY


if yes_answer "$IS_GATEWAY"; then


    # ========================================================
    # VERIFICA INTERFACES CONFIGURADAS
    # ========================================================

    if [ "${#CONFIGURED_INTERFACES[@]}" -lt 2 ]; then

        echo
        echo "ATENÇÃO:"
        echo
        echo "Um gateway normalmente precisa de pelo menos"
        echo "duas interfaces configuradas."
        echo

    fi


    # ========================================================
    # SELEÇÃO DA WAN
    # ========================================================

    echo
    echo "Selecione a interface que possui saída para a Internet:"
    echo


    INDEX=1

    for IFACE in "${CONFIGURED_INTERFACES[@]}"; do

        echo "$INDEX) $IFACE"

        INDEX=$((INDEX + 1))

    done


    echo


    while true; do

        read_tty "Interface de saída: " WAN_OPTION


        if [[ "$WAN_OPTION" =~ ^[0-9]+$ ]] &&
           [ "$WAN_OPTION" -ge 1 ] &&
           [ "$WAN_OPTION" -le "${#CONFIGURED_INTERFACES[@]}" ]; then

            WAN_INTERFACE="${CONFIGURED_INTERFACES[$((WAN_OPTION - 1))]}"

            break

        fi


        echo "Opção inválida."

    done


    echo
    echo "Interface WAN selecionada: $WAN_INTERFACE"
    echo


    # ========================================================
    # FORWARD IPV4 PERMANENTE
    # ========================================================

    echo "Ativando IPv4 forwarding..."


    cat > /etc/sysctl.d/99-ip-forward.conf <<'EOF'
# ============================================================
# IPv4 Forwarding
# ============================================================

net.ipv4.ip_forward = 1
EOF


    sysctl -w net.ipv4.ip_forward=1 >/dev/null


    # ========================================================
    # NFTABLES
    # ========================================================

    echo "Configurando nftables..."


    cat > /etc/nftables.conf <<EOF
#!/usr/sbin/nft -f

# ============================================================
# Firewall / Gateway
# Debian 13
#
# Arquivo gerado automaticamente
# ============================================================

flush ruleset


# ============================================================
# FILTRO
# ============================================================

table inet filter {

    chain input {

        type filter hook input priority filter;
        policy accept;

    }


    chain forward {

        type filter hook forward priority filter;
        policy drop;

        # Permite conexões já estabelecidas
        ct state established,related accept

        # Permite tráfego entrando pelas interfaces internas
        # e saindo pela WAN
EOF


    # ========================================================
    # ADICIONA INTERFACES LAN
    # ========================================================

    for IFACE in "${CONFIGURED_INTERFACES[@]}"; do

        if [ "$IFACE" != "$WAN_INTERFACE" ]; then

            echo "        iifname \"$IFACE\" oifname \"$WAN_INTERFACE\" accept" \
                >> /etc/nftables.conf

        fi

    done


    cat >> /etc/nftables.conf <<EOF

    }

}


# ============================================================
# NAT IPv4
# ============================================================

table ip nat {

    chain postrouting {

        type nat hook postrouting priority srcnat;
        policy accept;

        oifname "$WAN_INTERFACE" masquerade

    }

}
EOF


    # ========================================================
    # TESTA NFTABLES
    # ========================================================

    echo
    echo "Validando regras do nftables..."

    if ! nft -c -f /etc/nftables.conf; then

        echo
        echo "ERRO:"
        echo "A configuração do nftables possui algum problema."
        echo
        echo "O backup está em:"
        echo "$BACKUP_DIR"
        echo

        exit 1

    fi


    # ========================================================
    # ATIVA NFTABLES
    # ========================================================

    echo
    echo "Ativando nftables..."


    systemctl enable nftables >/dev/null 2>&1 || true


    nft -f /etc/nftables.conf


    systemctl restart nftables


    # ========================================================
    # RESULTADO GATEWAY
    # ========================================================

    echo
    echo "============================================================"
    echo " GATEWAY CONFIGURADO"
    echo "============================================================"
    echo
    echo "WAN:"
    echo "  $WAN_INTERFACE"
    echo
    echo "IPv4 Forwarding:"
    echo "  ATIVADO"
    echo
    echo "NAT / Masquerade:"
    echo "  ATIVADO"
    echo


else


    # ========================================================
    # NÃO É GATEWAY
    # ========================================================

    echo
    echo "A máquina não será configurada como gateway."
    echo

fi


# ============================================================
# RESULTADO FINAL
# ============================================================

echo
echo "============================================================"
echo " CONFIGURAÇÃO FINAL"
echo "============================================================"
echo

echo "/etc/network/interfaces:"
echo
echo "------------------------------------------------------------"

cat /etc/network/interfaces

echo "------------------------------------------------------------"


if yes_answer "$IS_GATEWAY"; then

    echo
    echo "IPv4 Forward:"
    echo

    sysctl net.ipv4.ip_forward

    echo
    echo "Regras nftables:"
    echo
    echo "------------------------------------------------------------"

    nft list ruleset

    echo "------------------------------------------------------------"

fi


# ============================================================
# SINCRONIZA
# ============================================================

sync


# ============================================================
# FINALIZAÇÃO
# ============================================================

echo
echo "============================================================"
echo " CONFIGURAÇÃO CONCLUÍDA"
echo "============================================================"
echo
echo "Backup da configuração anterior:"
echo
echo "  $BACKUP_DIR"
echo
echo "Recomenda-se reiniciar a máquina para aplicar"
echo "completamente a nova configuração de interfaces."
echo
echo "Execute:"
echo
echo "  reboot"
echo