Update debian/set_mac_wifi.sh
This commit is contained in:
Vendored
+158
-151
@@ -1,132 +1,29 @@
|
||||
#!/bin/bash
|
||||
# Script to set fixed MAC address and disable Wi-Fi if eth0 configuration succeeds
|
||||
# Must be run with sudo!
|
||||
# Update: Agora gera um MAC único automaticamente se nenhum for especificado (resolver problema do DM9601).
|
||||
# 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.
|
||||
|
||||
# --- Configuration ---
|
||||
ETH0_MAC="00:00:00:00:00:00" # Default MAC - será alterado automaticamente se mantiver este valor
|
||||
# WLAN0_MAC="XX:XX:XX:XX:XX:XX" # Uncomment and set if needed
|
||||
# --- Configurações ---
|
||||
LOG_FILE="/var/log/network_config.log"
|
||||
UDEV_RULES_FILE="/etc/udev/rules.d/81-mac-spoof.rules"
|
||||
|
||||
# Verify root privileges
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "This script must be run as root" >&2
|
||||
exit 1
|
||||
fi
|
||||
# --- Funções Auxiliares ---
|
||||
|
||||
# --- Functions ---
|
||||
# Function to set MAC and verify success
|
||||
set_mac() {
|
||||
local interface="$1"
|
||||
local mac="$2"
|
||||
local success=false
|
||||
local log_file="/var/log/set_mac.log"
|
||||
|
||||
# Verifica se a interface existe
|
||||
if ! ip link show "$interface" &> /dev/null; then
|
||||
echo "$(date): Interface $interface não encontrada." | tee -a "$log_file"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verifica se macchanger está instalado
|
||||
if command -v macchanger >/dev/null 2>&1; then
|
||||
echo "$(date): Usando macchanger para definir MAC de $interface para $mac" | tee -a "$log_file"
|
||||
# Tenta usar macchanger
|
||||
if ip link set "$interface" down && \
|
||||
macchanger -m "$mac" "$interface" >/dev/null 2>&1 && \
|
||||
ip link set "$interface" up; then
|
||||
echo "$(date): Sucesso ao definir MAC com macchanger para $interface (novo: $mac)" | tee -a "$log_file"
|
||||
success=true
|
||||
else
|
||||
echo "$(date): Falha ao definir MAC com macchanger para $interface. Tentando fallback com ip link..." | tee -a "$log_file"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fallback para ip link (se macchanger não estiver disponível ou falhar)
|
||||
if [ "$success" = false ]; then
|
||||
# Tenta com ip link diretamente
|
||||
if ip link set "$interface" down && \
|
||||
ip link set dev "$interface" address "$mac" && \
|
||||
ip link set "$interface" up; then
|
||||
echo "$(date): Sucesso ao definir MAC com 'ip link' para $interface (novo: $mac)" | tee -a "$log_file"
|
||||
success=true
|
||||
else
|
||||
echo "$(date): Falha ao definir MAC para $interface com ambos os métodos." | tee -a "$log_file"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Retorna sucesso (0) ou falha (1)
|
||||
return $([ "$success" = true ] && echo 0 || echo 1)
|
||||
# Função de Log
|
||||
log() {
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S'): $1" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
# Function to configure static IP
|
||||
configure_static_ip() {
|
||||
local ip_script="/usr/local/bin/set_static_ip.sh"
|
||||
|
||||
if [ -f "$ip_script" ]; then
|
||||
# Get current IP configuration
|
||||
local interface
|
||||
if interface=$(get_active_interface); then
|
||||
local current_ip=$(ip -4 addr show "$interface" | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
|
||||
if [[ "$current_ip" =~ ^169\.254\. ]]; then
|
||||
# Link-local address, likely no DHCP
|
||||
log "No valid IP address found for $interface, configuring static IP..."
|
||||
IP_ADDRESS_ENV="10.10.0.100/24" bash "$ip_script"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check if interface has IP address
|
||||
has_ip_address() {
|
||||
local interface="$1"
|
||||
# Check if interface is UP and has an IPv4 address
|
||||
if ip link show "$interface" | grep -q "state UP" && \
|
||||
ip -4 addr show "$interface" | grep -q "inet "; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to disable Wi-Fi
|
||||
disable_wifi() {
|
||||
# Create log directory if it doesn't exist
|
||||
mkdir -p /var/log
|
||||
|
||||
# Wait for 1 minute (60 seconds) before disabling Wi-Fi
|
||||
echo "$(date): Waiting 60 seconds before checking eth0 IP and disabling Wi-Fi..." | tee -a /var/log/set_mac.log
|
||||
sleep 60
|
||||
|
||||
# Check if eth0 has an IP address before disabling Wi-Fi
|
||||
if has_ip_address "eth0"; then
|
||||
if ip link show "wlan0" &> /dev/null; then
|
||||
if ip link set "wlan0" down; then
|
||||
echo "$(date): Wi-Fi (wlan0) disabled successfully (eth0 has IP)" | tee -a /var/log/set_mac.log
|
||||
else
|
||||
echo "$(date): Failed to disable Wi-Fi (wlan0)" | tee -a /var/log/set_mac.log
|
||||
fi
|
||||
else
|
||||
echo "$(date): wlan0 interface not found (Wi-Fi already disabled?)" | tee -a /var/log/set_mac.log
|
||||
fi
|
||||
else
|
||||
echo "$(date): eth0 does not have an IP address. Wi-Fi remains active." | tee -a /var/log/set_mac.log
|
||||
fi
|
||||
}
|
||||
|
||||
# --- Novas Funções Complementares (Dinâmicas) ---
|
||||
|
||||
# Função para gerar um MAC único baseado no Serial do Raspberry Pi
|
||||
# Garante que cada dispositivo fica com um MAC diferente mas consistente
|
||||
# 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 caso não encontre serial
|
||||
# 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
|
||||
# Gera hash do serial para criar os octetos
|
||||
local hash
|
||||
hash=$(echo -n "$serial-dm9601" | md5sum | cut -c1-10)
|
||||
# 02 define como Local Admin Address
|
||||
@@ -134,60 +31,170 @@ generate_unique_mac() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Função para criar regra Udev persistente (Best Practice)
|
||||
# Isto faz com que o MAC seja aplicado no boot, evitando erros de "Device Busy"
|
||||
# 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"
|
||||
local log_file="/var/log/set_mac.log"
|
||||
|
||||
# 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 return 1; fi
|
||||
|
||||
local rules_file="/etc/udev/rules.d/81-mac-spoof.rules"
|
||||
|
||||
# Se a regra já existe para este MAC original, não faz nada
|
||||
if grep -q "$original_mac" "$rules_file" 2>/dev/null; then
|
||||
return 0
|
||||
if [ -z "$original_mac" ]; then
|
||||
log "Não foi possível obter o MAC original para criar regra udev."
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "$(date): Criando regra udev persistente para $interface" | tee -a "$log_file"
|
||||
echo "ACTION==\"add\", SUBSYSTEM==\"net\", ATTR{address}==\"$original_mac\", RUN+=\"/usr/bin/ip link set dev \$name address $target_mac\"" >> "$rules_file"
|
||||
# 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 ---
|
||||
|
||||
# LÓGICA COMPLEMENTAR:
|
||||
# Se ETH0_MAC for o valor padrão (00:00...) ou vazio, gera um novo automaticamente.
|
||||
if [ -z "$ETH0_MAC" ] || [ "$ETH0_MAC" == "00:00:00:00:00:00" ]; then
|
||||
echo "$(date): Nenhum MAC específico definido. Gerando MAC único automático..." | tee -a /var/log/set_mac.log
|
||||
ETH0_MAC=$(generate_unique_mac)
|
||||
echo "$(date): Novo MAC gerado: $ETH0_MAC" | tee -a /var/log/set_mac.log
|
||||
# Verificar root
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Este script deve ser executado como root." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Executa a lógica original com o MAC definido (seja o do config ou o gerado)
|
||||
if set_mac "eth0" "$ETH0_MAC"; then
|
||||
# Se definiu o MAC com sucesso, tenta criar persistência via Udev
|
||||
# Isto resolve o problema do adapter mantendo o MAC em futuros boots
|
||||
setup_udev_persistence "eth0" "$ETH0_MAC"
|
||||
# Criar diretório de log se não existir
|
||||
mkdir -p "$(dirname "$LOG_FILE")"
|
||||
|
||||
# Check if disable_wifi is already running
|
||||
if ! pgrep -f "disable_wifi" > /dev/null; then
|
||||
#configure_static_ip
|
||||
disable_wifi &
|
||||
else
|
||||
echo "$(date): disable_wifi is already running" | tee -a /var/log/set_mac.log
|
||||
fi
|
||||
# 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
|
||||
echo "$(date): Could not set MAC for eth0. Wi-Fi remains active" | tee -a /var/log/set_mac.log
|
||||
# 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
|
||||
|
||||
# Uncomment if you want to set MAC for wlan0 (optional)
|
||||
# if [[ -n "$WLAN0_MAC" ]]; then
|
||||
# set_mac "wlan0" "$WLAN0_MAC"
|
||||
# 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
|
||||
Reference in New Issue
Block a user