Update debian/set_mac_wifi.sh

This commit is contained in:
2026-02-15 11:11:18 +00:00
parent 108694bc6e
commit f9ac2891f5
+62 -58
View File
@@ -1,8 +1,6 @@
#!/bin/bash
# Script Dinâmico de Configuração de Rede para Raspberry Pi
# Localização sugerida: /usr/local/bin/configure_network.sh
# Uso: sudo ./configure_network.sh [MAC_ADDRESS]
# Deve ser executado com privilégios de root.
# Localização: /usr/local/bin/configure_network.sh
# --- Configurações ---
LOG_FILE="/var/log/network_config.log"
@@ -21,27 +19,25 @@ generate_unique_mac() {
serial=$(awk '/Serial/ {print $3}' /proc/cpuinfo | tr -d ' ')
if [ -z "$serial" ]; then
# Fallback aleatório
printf '%02X:%02X:%02X:%02X:%02X:%02X' $((0x02 | (RANDOM % 256) & 0xFE)) $((RANDOM % 256)) $((RANDOM % 256)) $((RANDOM % 256)) $((RANDOM % 256)) $((RANDOM % 256))
else
local hash
hash=$(echo -n "$serial-dm9601" | md5sum | cut -c1-10)
# 02 define como Local Admin Address
echo "02:${hash:0:2}:${hash:2:2}:${hash:4:2}:${hash:6:2}:${hash:8:2}"
fi
}
# Função para definir MAC imediatamente (usada apenas na configuração inicial)
# Função para definir MAC imediatamente
set_mac() {
local interface="$1"
local mac="$2"
if ! ip link show "$interface" &> /dev/null; then
log "Interface $interface não encontrada."
log "Interface $interface não encontrada em set_mac."
return 1
fi
log "A definir MAC $mac em $interface imediatamente..."
log "A definir MAC $mac em $interface..."
if ip link set "$interface" down && \
ip link set dev "$interface" address "$mac" && \
ip link set "$interface" up; then
@@ -53,99 +49,112 @@ set_mac() {
fi
}
# Função para criar regra Udev (Persistência)
# Função para criar regra Udev
setup_udev_persistence() {
local interface="$1"
local target_mac="$2"
# Obtém o MAC original (físico) do adaptador
local original_mac
original_mac=$(ip link show "$interface" | awk '/ether/ {print $2}' | tr '[:upper:]' '[:lower:]')
target_mac=$(echo "$target_mac" | tr '[:upper:]' '[:lower:]')
if [ -z "$original_mac" ]; then
log "Não foi possível obter o MAC original para criar regra udev."
log "Erro crítico: Não foi possível obter o MAC original para criar regra udev."
return 1
fi
# Cria a regra: Ao adicionar o dispositivo com o MAC original, define o novo MAC
# Cria o ficheiro de regras
echo "ACTION==\"add\", SUBSYSTEM==\"net\", ATTR{address}==\"$original_mac\", RUN+=\"/usr/bin/ip link set dev \$name address $target_mac\"" > "$UDEV_RULES_FILE"
udevadm control --reload-rules
log "Regra Udev criada em $UDEV_RULES_FILE para persistência."
log "Regra Udev criada/atualizada em $UDEV_RULES_FILE."
return 0
}
# Função para verificar se a persistência já está configurada
# Função robusta para verificar persistência
is_persistence_configured() {
if [ -f "$UDEV_RULES_FILE" ]; then
# Verifica se o ficheiro não está vazio (proteção extra)
if [ -s "$UDEV_RULES_FILE" ]; then
log "Ficheiro de persistência encontrado: $UDEV_RULES_FILE"
return 0
else
log "Ficheiro de persistência existe mas está vazio. Invalidando."
return 1
fi
else
log "Ficheiro de persistência NÃO encontrado."
return 1
fi
}
# Tarefa em Background para monitorizar Ethernet e ativar Wi-Fi
# Tarefa em Background para monitorizar rede
monitor_network_task() {
log "Iniciando tarefa de monitorização de rede (Background)..."
# Espera inicial para o sistema estabilizar
log "Monitor: A iniciar verificação de rede (aguardando 60s)..."
sleep 60
local interface="eth0"
local wlan="wlan0"
# Loop infinito para verificação periódica (opcional, ou apenas uma vez)
# Aqui verificamos uma vez após o boot, conforme lógica original do disable_wifi
if ip link show "$interface" &> /dev/null; then
# Verifica 'NO-CARRIER' (cabo desligado) ou estado DOWN
if ip link show "$interface" | grep -q "NO-CARRIER" || ! ip link show "$interface" | grep -q "state UP"; then
log "Interface $interface sem ligação (cabo desligado?). A ativar Wi-Fi..."
if ip link show "$interface" | grep -q "NO-CARRIER"; then
log "Monitor: Interface $interface sem cabo (NO-CARRIER). A ativar Wi-Fi..."
if ip link show "$wlan" &> /dev/null; then
ip link set "$wlan" up
# Opcional: Pode-se adicionar lógica para reiniciar o wpa_supplicant ou dhclient
# systemctl restart wpa_supplicant
log "Wi-Fi ($wlan) ativado."
log "Monitor: Wi-Fi ($wlan) ativado."
fi
else
log "Interface $interface está ativa com ligação. Wi-Fi mantido inalterado."
log "Monitor: Interface $interface ativa. Nenhuma ação necessária."
fi
else
log "Interface $interface não encontrada para monitorização."
fi
}
# --- Execução Principal ---
# Verificar root
if [ "$(id -u)" -ne 0 ]; then
echo "Este script deve ser executado como root." >&2
exit 1
fi
# Criar diretório de log se não existir
mkdir -p "$(dirname "$LOG_FILE")"
# 1. Verificar se a persistência já está feita
# 1. Verificar Persistência Existente
if is_persistence_configured; then
log "Persistência Udev já configurada. Ignorando configuração de MAC."
# Apenas lança a tarefa de monitorização de rede
log "Configuração já persistida no sistema. A saltar configuração de MAC."
monitor_network_task &
exit 0
fi
# 2. Determinar o MAC Address a utilizar
# 2. Esperar pela Interface de Rede (Importante para boot/curl)
# O script pode correr antes da interface estar pronta.
IFACE="eth0"
log "A aguardar pela interface $IFACE..."
for i in {1..30}; do
if ip link show "$IFACE" &> /dev/null; then
break
fi
sleep 1
done
if ! ip link show "$IFACE" &> /dev/null; then
log "Erro: Interface $IFACE não disponível após 30 segundos. A sair."
exit 1
fi
# 3. Determinar o MAC Address
TARGET_MAC=""
# 2.1. Verificar argumento passado ao script
# Verificar argumento ($1)
if [ -n "$1" ]; then
TARGET_MAC="$1"
log "MAC definido via argumento: $TARGET_MAC"
else
# 2.2. Verificar se é uma execução interativa (terminal)
if [ -t 0 ]; then
# Verificar se é interativo
# IMPORTANTE: Ler de /dev/tty para funcionar com curl | bash
if [ -t 0 ] && [ -e /dev/tty ]; then
# Abre /dev/tty para ler input do utilizador
exec < /dev/tty
echo "Nenhum MAC definido. Deseja:"
echo "1) Gerar um novo MAC único automático"
echo "2) Introduzir um MAC manualmente"
@@ -158,43 +167,38 @@ else
;;
2)
read -p "Introduza o MAC (formato XX:XX:XX:XX:XX:XX): " TARGET_MAC
if [[ ! "$TARGET_MAC" =~ ^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$ ]]; then
log "Formato de MAC inválido."
exit 1
fi
;;
*)
log "Opção inválida. A sair."
log "Opção inválida."
exit 1
;;
esac
# Restaura stdin se necessário (embora geralmente não seja crítico aqui)
else
# 2.3. Execução não interativa (ex: boot) sem argumentos -> Gerar automático
log "Execução não interativa sem argumentos. A gerar MAC único..."
# Modo não interativo (boot/curl) sem argumentos: Gerar automático
log "Execução não interativa. A gerar MAC único..."
TARGET_MAC=$(generate_unique_mac)
log "MAC gerado: $TARGET_MAC"
fi
fi
# 3. Aplicar Configuração (Imediata e Persistente)
# Detectar interface (assumindo eth0 ou primeira USB)
IFACE="eth0"
if ! ip link show "$IFACE" &> /dev/null; then
# Tenta encontrar interface USB alternativa
IFACE=$(ip -o link show | grep -v "wlan0" | grep -v "lo" | awk '{print $2}' | sed 's/://' | head -n 1)
[ -z "$IFACE" ] && { log "Nenhuma interface Ethernet encontrada."; exit 1; }
# Validação simples do MAC
if [[ ! "$TARGET_MAC" =~ ^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$ ]]; then
log "MAC Address inválido ou vazio: $TARGET_MAC"
exit 1
fi
log "Interface detetada: $IFACE"
# 4. Aplicar Configuração
log "A configurar sistema com MAC: $TARGET_MAC"
# Aplicar agora (para a sessão atual) e criar regra para o futuro (udev)
if set_mac "$IFACE" "$TARGET_MAC"; then
setup_udev_persistence "$IFACE" "$TARGET_MAC"
else
log "Erro ao aplicar configuração MAC."
log "Aviso: Falha ao definir MAC em tempo real, mas a tentar criar persistência..."
setup_udev_persistence "$IFACE" "$TARGET_MAC"
fi
# 4. Lançar tarefa de monitorização em Background
# 5. Lançar Monitor de Rede
monitor_network_task &
exit 0