857 lines
18 KiB
Bash
857 lines
18 KiB
Bash
#!/bin/bash
|
|
|
|
set -e
|
|
|
|
# ============================================================
|
|
# CONFIGURAÇÃO DE REDE / GATEWAY - DEBIAN 13
|
|
#
|
|
# Funções:
|
|
# - Detecta interfaces de rede
|
|
# - Recria /etc/network/interfaces
|
|
# - DHCP / IP estático / Não configurar
|
|
# - Configura /etc/resolv.conf
|
|
# - Configura gateway IPv4
|
|
# - Ativa ip_forward permanentemente
|
|
# - Configura nftables
|
|
# - Configura masquerade permanente
|
|
#
|
|
# 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 / GATEWAY - DEBIAN 13"
|
|
echo "============================================================"
|
|
echo
|
|
|
|
|
|
# ============================================================
|
|
# 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 "Os seguintes arquivos poderão ser alterados:"
|
|
echo
|
|
echo " /etc/network/interfaces"
|
|
echo " /etc/resolv.conf"
|
|
echo " /etc/sysctl.d/99-ip-forward.conf"
|
|
echo " /etc/nftables.conf"
|
|
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"
|
|
|
|
|
|
for FILE in \
|
|
/etc/network/interfaces \
|
|
/etc/resolv.conf \
|
|
/etc/nftables.conf \
|
|
/etc/sysctl.d/99-ip-forward.conf
|
|
|
|
do
|
|
|
|
if [ -e "$FILE" ]; then
|
|
|
|
cp -a "$FILE" "$BACKUP_DIR/$(basename "$FILE")"
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
echo
|
|
echo "Backup criado em:"
|
|
echo
|
|
echo " $BACKUP_DIR"
|
|
echo
|
|
|
|
|
|
# ============================================================
|
|
# VARIÁVEIS
|
|
# ============================================================
|
|
|
|
CONFIGURED_INTERFACES=()
|
|
|
|
DNS_SERVERS=()
|
|
DNS_SEARCH=""
|
|
|
|
STATIC_INTERFACE_FOUND=0
|
|
|
|
|
|
# ============================================================
|
|
# RECRIA /etc/network/interfaces
|
|
# ============================================================
|
|
|
|
cat > /etc/network/interfaces <<'EOF'
|
|
# ============================================================
|
|
# Configuração de rede
|
|
# Gerada automaticamente
|
|
# ============================================================
|
|
|
|
auto lo
|
|
iface lo inet loopback
|
|
|
|
EOF
|
|
|
|
|
|
# ============================================================
|
|
# CONFIGURA INTERFACES
|
|
# ============================================================
|
|
|
|
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)
|
|
|
|
STATIC_INTERFACE_FOUND=1
|
|
|
|
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 da rede [ex.: 24]: " PREFIX
|
|
|
|
if [[ "$PREFIX" =~ ^[0-9]+$ ]] &&
|
|
[ "$PREFIX" -ge 0 ] &&
|
|
[ "$PREFIX" -le 32 ]; then
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
echo "Prefixo inválido. Informe um valor entre 0 e 32."
|
|
|
|
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.: 8.8.8.8 1.1.1.1] [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 "Um ou mais servidores DNS são inválidos."
|
|
|
|
done
|
|
|
|
|
|
# ------------------------------------------------
|
|
# DNS SEARCH
|
|
# ------------------------------------------------
|
|
|
|
read_tty "Domínio de pesquisa DNS [ENTER para nenhum]: " CURRENT_DNS_SEARCH
|
|
|
|
|
|
# ------------------------------------------------
|
|
# GRAVA INTERFACE
|
|
# ------------------------------------------------
|
|
|
|
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
|
|
|
|
for DNS_IP in $DNS; do
|
|
DNS_SERVERS+=("$DNS_IP")
|
|
done
|
|
fi
|
|
|
|
|
|
if [ -n "$CURRENT_DNS_SEARCH" ]; then
|
|
|
|
echo " dns-search $CURRENT_DNS_SEARCH" \
|
|
>> /etc/network/interfaces
|
|
|
|
DNS_SEARCH="$CURRENT_DNS_SEARCH"
|
|
|
|
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. Escolha 1, 2 ou 3."
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
done
|
|
|
|
|
|
chmod 644 /etc/network/interfaces
|
|
|
|
|
|
# ============================================================
|
|
# CONFIGURA /etc/resolv.conf
|
|
# ============================================================
|
|
|
|
if [ "${#DNS_SERVERS[@]}" -gt 0 ]; then
|
|
|
|
echo
|
|
echo "Configurando /etc/resolv.conf..."
|
|
|
|
|
|
cat > /etc/resolv.conf <<'EOF'
|
|
# ============================================================
|
|
# Configuração DNS
|
|
# Gerada automaticamente
|
|
# ============================================================
|
|
|
|
EOF
|
|
|
|
|
|
if [ -n "$DNS_SEARCH" ]; then
|
|
|
|
echo "search $DNS_SEARCH" >> /etc/resolv.conf
|
|
|
|
fi
|
|
|
|
|
|
# Remove duplicatas
|
|
mapfile -t UNIQUE_DNS < <(
|
|
printf "%s\n" "${DNS_SERVERS[@]}" |
|
|
awk '!seen[$0]++'
|
|
)
|
|
|
|
|
|
for DNS_IP in "${UNIQUE_DNS[@]}"; do
|
|
|
|
echo "nameserver $DNS_IP" >> /etc/resolv.conf
|
|
|
|
done
|
|
|
|
|
|
chmod 644 /etc/resolv.conf
|
|
|
|
fi
|
|
|
|
|
|
# ============================================================
|
|
# GATEWAY
|
|
# ============================================================
|
|
|
|
echo
|
|
echo "============================================================"
|
|
echo " CONFIGURAÇÃO DE GATEWAY"
|
|
echo "============================================================"
|
|
echo
|
|
|
|
read_tty "Esta máquina será gateway para outras máquinas/redes? [s/N]: " IS_GATEWAY
|
|
|
|
|
|
if yes_answer "$IS_GATEWAY"; then
|
|
|
|
|
|
# ========================================================
|
|
# NFTABLES
|
|
# ========================================================
|
|
|
|
if ! command -v nft >/dev/null 2>&1; then
|
|
|
|
echo
|
|
echo "ERRO: nftables não está instalado."
|
|
echo
|
|
echo "Instale com:"
|
|
echo
|
|
echo " apt update"
|
|
echo " apt install nftables"
|
|
echo
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
if [ "${#CONFIGURED_INTERFACES[@]}" -lt 2 ]; then
|
|
|
|
echo
|
|
echo "ATENÇÃO:"
|
|
echo
|
|
echo "Foram configuradas menos de duas interfaces."
|
|
echo "Um gateway normalmente utiliza pelo menos uma WAN e uma LAN."
|
|
echo
|
|
|
|
fi
|
|
|
|
|
|
# ========================================================
|
|
# SELECIONA 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:"
|
|
echo
|
|
echo " $WAN_INTERFACE"
|
|
echo
|
|
|
|
|
|
# ========================================================
|
|
# INTERFACES LAN
|
|
# ========================================================
|
|
|
|
LAN_INTERFACES=()
|
|
|
|
for IFACE in "${CONFIGURED_INTERFACES[@]}"; do
|
|
|
|
if [ "$IFACE" != "$WAN_INTERFACE" ]; then
|
|
|
|
LAN_INTERFACES+=("$IFACE")
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
# ========================================================
|
|
# IP FORWARD
|
|
# ========================================================
|
|
|
|
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 "Criando configuração do nftables..."
|
|
|
|
|
|
cat > /etc/nftables.conf <<EOF
|
|
#!/usr/sbin/nft -f
|
|
|
|
# ============================================================
|
|
# NFTABLES - GATEWAY IPV4
|
|
# Gerado automaticamente
|
|
# ============================================================
|
|
|
|
flush ruleset
|
|
|
|
|
|
# ============================================================
|
|
# FILTER
|
|
# ============================================================
|
|
|
|
table inet filter {
|
|
|
|
chain input {
|
|
|
|
type filter hook input priority filter;
|
|
policy accept;
|
|
|
|
}
|
|
|
|
|
|
chain forward {
|
|
|
|
type filter hook forward priority filter;
|
|
policy drop;
|
|
|
|
# Tráfego já estabelecido
|
|
ct state established,related accept
|
|
|
|
EOF
|
|
|
|
|
|
# ========================================================
|
|
# REGRAS LAN -> WAN
|
|
# ========================================================
|
|
|
|
for LAN_INTERFACE in "${LAN_INTERFACES[@]}"; do
|
|
|
|
echo " iifname \"$LAN_INTERFACE\" oifname \"$WAN_INTERFACE\" accept" \
|
|
>> /etc/nftables.conf
|
|
|
|
done
|
|
|
|
|
|
cat >> /etc/nftables.conf <<EOF
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
# ============================================================
|
|
# NAT
|
|
# ============================================================
|
|
|
|
table ip nat {
|
|
|
|
chain postrouting {
|
|
|
|
type nat hook postrouting priority srcnat;
|
|
policy accept;
|
|
|
|
oifname "$WAN_INTERFACE" masquerade
|
|
|
|
}
|
|
|
|
}
|
|
EOF
|
|
|
|
|
|
# ========================================================
|
|
# VALIDA NFTABLES
|
|
# ========================================================
|
|
|
|
echo
|
|
echo "Validando regras do nftables..."
|
|
|
|
|
|
if ! nft -c -f /etc/nftables.conf; then
|
|
|
|
echo
|
|
echo "ERRO: configuração inválida do nftables."
|
|
echo
|
|
echo "Backup disponível em:"
|
|
echo
|
|
echo " $BACKUP_DIR"
|
|
echo
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
# ========================================================
|
|
# ATIVA
|
|
# ========================================================
|
|
|
|
echo
|
|
echo "Ativando nftables..."
|
|
|
|
|
|
systemctl enable nftables >/dev/null 2>&1 || true
|
|
|
|
|
|
nft -f /etc/nftables.conf
|
|
|
|
|
|
systemctl restart nftables
|
|
|
|
|
|
fi
|
|
|
|
|
|
# ============================================================
|
|
# RESULTADO FINAL
|
|
# ============================================================
|
|
|
|
echo
|
|
echo "============================================================"
|
|
echo " CONFIGURAÇÃO FINAL"
|
|
echo "============================================================"
|
|
echo
|
|
|
|
|
|
echo "Arquivo de interfaces:"
|
|
echo
|
|
echo "------------------------------------------------------------"
|
|
cat /etc/network/interfaces
|
|
echo "------------------------------------------------------------"
|
|
|
|
|
|
echo
|
|
echo "DNS:"
|
|
echo
|
|
echo "------------------------------------------------------------"
|
|
cat /etc/resolv.conf
|
|
echo "------------------------------------------------------------"
|
|
|
|
|
|
if yes_answer "$IS_GATEWAY"; then
|
|
|
|
echo
|
|
echo "Gateway:"
|
|
echo
|
|
echo "WAN : $WAN_INTERFACE"
|
|
|
|
if [ "${#LAN_INTERFACES[@]}" -gt 0 ]; then
|
|
|
|
echo "LAN : ${LAN_INTERFACES[*]}"
|
|
|
|
fi
|
|
|
|
echo "IPv4 Forward : $(sysctl -n net.ipv4.ip_forward)"
|
|
echo "Masquerade : ativado"
|
|
echo
|
|
|
|
echo "------------------------------------------------------------"
|
|
echo "NFTABLES"
|
|
echo "------------------------------------------------------------"
|
|
|
|
nft list ruleset
|
|
|
|
echo "------------------------------------------------------------"
|
|
|
|
fi
|
|
|
|
|
|
# ============================================================
|
|
# SINCRONIZA
|
|
# ============================================================
|
|
|
|
sync
|
|
|
|
|
|
# ============================================================
|
|
# FINALIZA
|
|
# ============================================================
|
|
|
|
echo
|
|
echo "============================================================"
|
|
echo " CONFIGURAÇÃO CONCLUÍDA"
|
|
echo "============================================================"
|
|
echo
|
|
echo "Backup:"
|
|
echo
|
|
echo " $BACKUP_DIR"
|
|
echo
|
|
echo "A configuração foi gravada."
|
|
echo
|
|
echo "Recomenda-se reiniciar a máquina:"
|
|
echo
|
|
echo " reboot"
|
|
echo |