#!/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. # --- Configurações --- LOG_FILE="/var/log/network_config.log" UDEV_RULES_FILE="/etc/udev/rules.d/81-mac-spoof.rules" # --- Funções Auxiliares --- # Função de Log log() { echo "$(date '+%Y-%m-%d %H:%M:%S'): $1" | tee -a "$LOG_FILE" } # Função para gerar MAC único baseado no Serial do CPU generate_unique_mac() { local serial 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) set_mac() { local interface="$1" local mac="$2" if ! ip link show "$interface" &> /dev/null; then log "Interface $interface não encontrada." return 1 fi log "A definir MAC $mac em $interface imediatamente..." if ip link set "$interface" down && \ ip link set dev "$interface" address "$mac" && \ ip link set "$interface" up; then log "MAC alterado com sucesso na sessão atual." return 0 else log "Falha ao alterar MAC na sessão atual." return 1 fi } # Função para criar regra Udev (Persistência) 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." return 1 fi # Cria a regra: Ao adicionar o dispositivo com o MAC original, define o novo MAC 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." return 0 } # Função para verificar se a persistência já está configurada is_persistence_configured() { if [ -f "$UDEV_RULES_FILE" ]; then return 0 else return 1 fi } # Tarefa em Background para monitorizar Ethernet e ativar Wi-Fi monitor_network_task() { log "Iniciando tarefa de monitorização de rede (Background)..." # Espera inicial para o sistema estabilizar 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 "$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." fi else log "Interface $interface está ativa com ligação. Wi-Fi mantido inalterado." 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 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 monitor_network_task & exit 0 fi # 2. Determinar o MAC Address a utilizar TARGET_MAC="" # 2.1. Verificar argumento passado ao script 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 echo "Nenhum MAC definido. Deseja:" echo "1) Gerar um novo MAC único automático" echo "2) Introduzir um MAC manualmente" read -p "Opção [1/2]: " choice case "$choice" in 1) TARGET_MAC=$(generate_unique_mac) log "MAC gerado automaticamente: $TARGET_MAC" ;; 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." exit 1 ;; esac 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..." 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; } fi log "Interface detetada: $IFACE" # 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." fi # 4. Lançar tarefa de monitorização em Background monitor_network_task & exit 0