UnifiDDNSWinco/ddns_update_winco.sh

179 lines
5.3 KiB
Bash

#!/bin/bash
# Configurações
# Array associativo com hostname e suas credenciais
# Formato: "hostname:usuario:senha"
DDNS_CONFIGS=(
"subdominio1.ddns.com.br:usuario1:senha1"
"subdominio2.ddns.com.br:usuario2:senha2"
"subdominio3.ddns.com.br:usuario3:senha3"
# Adicione mais conforme necessário
# "meudominio.ddns.com.br:meuusuario:minhasenha"
)
DDNS_URL="http://members.ddns.com.br/nic/update"
LOG_FILE="/tmp/ddns_update.log"
IP_CACHE_FILE="/tmp/last_ip.txt"
# Função para log
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}
# Função para obter IP público
get_public_ip() {
local ip=""
# Lista de serviços para verificar IP público (em ordem de preferência)
local services=(
"https://ifconfig.me/ip"
"https://api.ipify.org"
"https://ipecho.net/plain"
"https://icanhazip.com"
"https://ident.me"
)
for service in "${services[@]}"; do
ip=$(curl -s --connect-timeout 10 --max-time 15 "$service" | tr -d '\n\r ')
# Verifica se o IP é válido (formato IPv4)
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
echo "$ip"
return 0
fi
done
return 1
}
# Função para extrair dados da configuração
parse_config() {
local config="$1"
local field="$2"
# Separa hostname:usuario:senha
local hostname=$(echo "$config" | cut -d':' -f1)
local username=$(echo "$config" | cut -d':' -f2)
local password=$(echo "$config" | cut -d':' -f3-)
case "$field" in
"hostname") echo "$hostname" ;;
"username") echo "$username" ;;
"password") echo "$password" ;;
esac
}
# Função para atualizar DDNS
update_ddns() {
local current_ip="$1"
local config="$2"
local hostname=$(parse_config "$config" "hostname")
local username=$(parse_config "$config" "username")
local password=$(parse_config "$config" "password")
local update_url="${DDNS_URL}?hostname=${hostname}&myip=${current_ip}"
log_message "Atualizando DDNS para $hostname com IP: $current_ip (usuário: $username)"
# Faz a requisição de atualização com autenticação HTTP Basic
local response=$(curl -s --connect-timeout 15 --max-time 30 \
--user "${username}:${password}" \
"$update_url")
local curl_exit_code=$?
if [ $curl_exit_code -eq 0 ]; then
log_message "$hostname atualizado com sucesso. Resposta: $response"
return 0
else
log_message "✗ Erro ao atualizar $hostname (curl exit code: $curl_exit_code)"
return 1
fi
}
# Função principal
main() {
log_message "=== Iniciando verificação de IP público ==="
# Verifica se há configurações
if [ ${#DDNS_CONFIGS[@]} -eq 0 ]; then
log_message "ERRO: Nenhuma configuração definida no array DDNS_CONFIGS"
exit 1
fi
# Valida se as configurações não são os exemplos padrão
local has_default=false
for config in "${DDNS_CONFIGS[@]}"; do
if [[ "$config" =~ ^subdominio[123]\.ddns\.com\.br:usuario[123]:senha[123]$ ]]; then
has_default=true
break
fi
done
if [ "$has_default" = true ]; then
log_message "ERRO: Configurações padrão detectadas! Configure seus domínios e credenciais reais"
exit 1
fi
# Lista os domínios configurados
local hostnames=()
for config in "${DDNS_CONFIGS[@]}"; do
hostnames+=($(parse_config "$config" "hostname"))
done
log_message "Domínios configurados: ${hostnames[*]}"
# Obtém o IP público atual
current_ip=$(get_public_ip)
if [ -z "$current_ip" ]; then
log_message "ERRO: Não foi possível obter o IP público"
exit 1
fi
log_message "IP público detectado: $current_ip"
# Verifica se existe cache do último IP
if [ -f "$IP_CACHE_FILE" ]; then
last_ip=$(cat "$IP_CACHE_FILE" 2>/dev/null)
if [ "$current_ip" = "$last_ip" ]; then
log_message "IP não mudou ($current_ip), não é necessário atualizar"
exit 0
else
log_message "IP mudou de $last_ip para $current_ip"
fi
else
log_message "Primeira execução ou cache não encontrado"
fi
# Contador de sucessos/falhas
local success_count=0
local fail_count=0
# Atualiza cada domínio com suas credenciais
log_message "--- Iniciando atualizações ---"
for config in "${DDNS_CONFIGS[@]}"; do
if update_ddns "$current_ip" "$config"; then
((success_count++))
else
((fail_count++))
fi
# Pequena pausa entre as requisições para não sobrecarregar o servidor
sleep 2
done
# Salva o IP no cache apenas se pelo menos uma atualização foi bem-sucedida
if [ $success_count -gt 0 ]; then
echo "$current_ip" > "$IP_CACHE_FILE"
log_message "=== Resumo: $success_count sucessos, $fail_count falhas ==="
log_message "IP $current_ip salvo no cache"
else
log_message "=== ERRO: Todas as atualizações falharam! ==="
exit 1
fi
log_message "=== Processo concluído ==="
}
# Executa o script principal
main "$@"