#!/bin/bash # ============================================================================ # DNSBlock Agent - Script de Instalação e Desinstalação # ============================================================================ # Este script realiza a instalação ou desinstalação completa do DNSBlock Agent # Requer privilégios de root para execução # # Uso: # ./install.sh Instalação interativa # ./install.sh uninstall Desinstalação # ============================================================================ set -e # Diretórios e arquivos INSTALL_DIR="/opt/dnsblock" RPZ_DIR="$INSTALL_DIR/rpz" SERVICE_FILE="/etc/systemd/system/dnsblock-agent.service" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # Configurações do Unbound UNBOUND_CONF_DIR="/etc/unbound/unbound.conf.d" UNBOUND_MAIN_CONF="/etc/unbound/unbound.conf" DNSBLOCK_CONF="$UNBOUND_CONF_DIR/dnsblock.conf" DNSBLOCK_INCLUDE='include: "/etc/unbound/unbound.conf.d/dnsblock.conf"' # Variáveis globais SERIAL="" NO_SERIAL=false # ============================================================================ # FUNÇÕES UTILITÁRIAS # ============================================================================ # Verificar se está executando como root verificar_root() { if [ "$(id -u)" -ne 0 ]; then whiptail --title "Erro" --msgbox "Este script deve ser executado como root.\n\nExecute novamente com sudo." 10 50 exit 1 fi } # Verificar dependências verificar_dependencias() { local deps_faltando="" if ! command -v whiptail &> /dev/null; then echo "Erro: whiptail não encontrado. Instale-o antes de continuar." exit 1 fi if ! command -v unbound-checkconf &> /dev/null; then deps_faltando="$deps_faltando unbound-checkconf" fi if [ -n "$deps_faltando" ]; then whiptail --title "Dependências Faltando" \ --msgbox "As seguintes dependências não foram encontradas:\n$deps_faltando\n\nPor favor, instale-as antes de continuar." 12 55 exit 1 fi } # ============================================================================ # FUNÇÕES DE SERIAL # ============================================================================ # Solicitar o serial via whiptail solicitar_serial() { local serial="" serial=$(whiptail --title "DNSBlock Agent - Ativação" \ --inputbox "Digite o serial de ativação do agente:\n\n(Deixe em branco para instalar sem serial)" \ 12 60 3>&1 1>&2 2>&3) local status=$? if [ $status -ne 0 ]; then # Usuário cancelou com ESC ou Cancel whiptail --title "Instalação Cancelada" \ --msgbox "A instalação foi cancelada pelo usuário." 8 45 exit 0 fi if [ -z "$serial" ]; then # Serial em branco - perguntar se deseja continuar if whiptail --title "Instalação sem Serial" \ --yesno "Você não informou um serial.\n\nDeseja instalar sem serial?\n\n(O serviço será ativado mas não inicializado)\n\nVocê pode obter seu serial em:\nhttp://painel.dnsblock.com.br" \ 14 55; then NO_SERIAL=true echo "" else whiptail --title "Instalação Cancelada" \ --msgbox "A instalação foi cancelada pelo usuário." 8 45 exit 0 fi else echo "$serial" fi } # Atualizar o serial no config.json atualizar_config_serial() { local serial="$1" local config_file="$INSTALL_DIR/config.json" if [ -f "$config_file" ]; then sed -i "s/\"serial_key\":[[:space:]]*\"[^\"]*\"/\"serial_key\": \"$serial\"/" "$config_file" fi } # ============================================================================ # FUNÇÕES DE CONFIGURAÇÃO DO UNBOUND # ============================================================================ # Encontrar o arquivo de configuração apropriado do Unbound encontrar_arquivo_config_unbound() { local config_file="" # Verificar se existe algum arquivo com configuração RPZ for conf in "$UNBOUND_CONF_DIR"/*.conf; do if [ -f "$conf" ] && grep -q "rpz:" "$conf" 2>/dev/null; then config_file="$conf" break fi done # Se não encontrou arquivo com RPZ, usar local.conf se existir if [ -z "$config_file" ]; then if [ -f "$UNBOUND_CONF_DIR/local.conf" ]; then config_file="$UNBOUND_CONF_DIR/local.conf" elif [ -f "$UNBOUND_MAIN_CONF" ]; then config_file="$UNBOUND_MAIN_CONF" fi fi echo "$config_file" } # Verificar se o include já existe verificar_include_existente() { local include_pattern='include:[[:space:]]*"/etc/unbound/unbound.conf.d/dnsblock.conf"' if [ -f "$UNBOUND_MAIN_CONF" ] && grep -qE "$include_pattern" "$UNBOUND_MAIN_CONF" 2>/dev/null; then return 0 fi for conf in "$UNBOUND_CONF_DIR"/*.conf; do if [ -f "$conf" ] && grep -qE "$include_pattern" "$conf" 2>/dev/null; then return 0 fi done return 1 } # Configurar o Unbound para usar o DNSBlock configurar_unbound() { # Criar diretório de configuração do Unbound se não existir if [ ! -d "$UNBOUND_CONF_DIR" ]; then mkdir -p "$UNBOUND_CONF_DIR" chown unbound:unbound "$UNBOUND_CONF_DIR" fi # Criar o diretório RPZ mkdir -p "$RPZ_DIR" chown unbound:unbound "$RPZ_DIR" # Criar arquivo de configuração do DNSBlock para o Unbound cat > "$DNSBLOCK_CONF" << 'EOF' rpz: name: rpz.dnsblock.zone zonefile: /opt/dnsblock/rpz/rpz.dnsblock.zone rpz-action-override: nxdomain EOF chown unbound:unbound "$DNSBLOCK_CONF" chmod 644 "$DNSBLOCK_CONF" # Adicionar include se não existir if ! verificar_include_existente; then local config_file=$(encontrar_arquivo_config_unbound) if [ -z "$config_file" ]; then return 1 fi if grep -q "rpz:" "$config_file" 2>/dev/null; then sed -i "/rpz:/i # DNSBlock\n$DNSBLOCK_INCLUDE\n" "$config_file" else echo "" >> "$config_file" echo "# DNSBlock" >> "$config_file" echo "$DNSBLOCK_INCLUDE" >> "$config_file" fi fi # Criar arquivo RPZ vazio se não existir local rpz_file="$RPZ_DIR/rpz.dnsblock.zone" if [ ! -f "$rpz_file" ]; then cat > "$rpz_file" << 'EOF' $TTL 1H @ SOA localhost. hostmaster.localhost. ( 1 ; Serial 1h ; Refresh 15m ; Retry 30d ; Expire 2h ; Negative Cache TTL ) NS localhost. ; RPZ block hosts EOF chown unbound:unbound "$rpz_file" chmod 644 "$rpz_file" fi # Verificar configuração do Unbound if ! unbound-checkconf &>/dev/null; then rm -f "$DNSBLOCK_CONF" remover_include_unbound return 1 fi # Reiniciar o Unbound systemctl restart unbound 2>/dev/null || true return 0 } # Remover o include do DNSBlock dos arquivos de configuração remover_include_unbound() { local include_pattern='include:[[:space:]]*"/etc/unbound/unbound.conf.d/dnsblock.conf"' local comment_pattern='#[[:space:]]*DNSBlock' if [ -f "$UNBOUND_MAIN_CONF" ]; then sed -i "/$include_pattern/d" "$UNBOUND_MAIN_CONF" sed -i "/$comment_pattern/d" "$UNBOUND_MAIN_CONF" fi for conf in "$UNBOUND_CONF_DIR"/*.conf; do if [ -f "$conf" ] && [ "$conf" != "$DNSBLOCK_CONF" ]; then sed -i "/$include_pattern/d" "$conf" sed -i "/$comment_pattern/d" "$conf" fi done } # Remover configuração do Unbound remover_configuracao_unbound() { remover_include_unbound if [ -f "$DNSBLOCK_CONF" ]; then rm -f "$DNSBLOCK_CONF" fi if unbound-checkconf &>/dev/null; then systemctl restart unbound 2>/dev/null || true fi } # ============================================================================ # FUNÇÃO DE INSTALAÇÃO # ============================================================================ instalar() { # Verificar dependências verificar_dependencias # Verificar se já está instalado if [ -d "$INSTALL_DIR" ]; then if ! whiptail --title "DNSBlock já instalado" \ --yesno "O DNSBlock Agent já está instalado.\n\nDeseja reinstalar?" 10 50; then exit 0 fi # Parar serviço se estiver rodando systemctl stop dnsblock-agent 2>/dev/null || true systemctl disable dnsblock-agent 2>/dev/null || true rm -rf "$INSTALL_DIR" rm -f "$SERVICE_FILE" fi # Exibir progresso - Fase 1: Criar diretórios e copiar arquivos { echo "5"; echo "# Criando diretórios..." mkdir -p "$INSTALL_DIR" mkdir -p "$INSTALL_DIR/logs" mkdir -p "$INSTALL_DIR/rpz" sleep 0.2 echo "15"; echo "# Copiando binário..." # Copiar o binário if [ -f "$SCRIPT_DIR/dnsblock-agent" ]; then cp "$SCRIPT_DIR/dnsblock-agent" "$INSTALL_DIR/" chmod +x "$INSTALL_DIR/dnsblock-agent" else echo "ERRO: dnsblock-agent não encontrado!" >&2 exit 1 fi sleep 0.2 echo "25"; echo "# Criando config.json..." # Criar config.json a partir do exemplo if [ -f "$SCRIPT_DIR/config.json.example" ]; then cp "$SCRIPT_DIR/config.json.example" "$INSTALL_DIR/config.json" else echo "ERRO: config.json.example não encontrado!" >&2 exit 1 fi sleep 0.2 echo "35"; echo "# Configurando permissões..." touch "$INSTALL_DIR/logs/agent.log" chown -R unbound:unbound "$INSTALL_DIR" chmod 755 "$INSTALL_DIR" sleep 0.2 echo "40"; echo "# Aguardando..." } | whiptail --title "DNSBlock Agent - Instalação" --gauge "Preparando arquivos..." 8 60 0 # Solicitar serial (fora do gauge para funcionar corretamente) SERIAL=$(solicitar_serial) # Exibir progresso - Fase 2: Configurar serial e serviço { echo "45"; echo "# Configurando serial..." if [ -n "$SERIAL" ]; then atualizar_config_serial "$SERIAL" fi sleep 0.2 echo "55"; echo "# Instalando serviço systemd..." if [ -f "$SCRIPT_DIR/dnsblock-agent.service" ]; then cp "$SCRIPT_DIR/dnsblock-agent.service" "$SERVICE_FILE" else echo "ERRO: dnsblock-agent.service não encontrado!" >&2 exit 1 fi sleep 0.2 echo "65"; echo "# Habilitando serviço..." systemctl daemon-reload systemctl enable dnsblock-agent 2>/dev/null || true sleep 0.2 echo "75"; echo "# Configurando Unbound..." configurar_unbound || true sleep 0.2 echo "90"; echo "# Finalizando..." if [ -n "$SERIAL" ]; then systemctl start dnsblock-agent 2>/dev/null || true fi sleep 0.2 echo "100"; echo "# Concluído!" } | whiptail --title "DNSBlock Agent - Instalação" --gauge "Configurando sistema..." 8 60 45 # Exibir mensagem final if [ -n "$SERIAL" ]; then whiptail --title "Instalação Concluída" \ --msgbox "O DNSBlock Agent foi instalado e iniciado com sucesso!\n\nComandos úteis:\n • Status: systemctl status dnsblock-agent\n • Logs: journalctl -u dnsblock-agent -f\n • Reiniciar: systemctl restart dnsblock-agent" 14 60 else whiptail --title "Instalação Concluída (sem serial)" \ --msgbox "O DNSBlock Agent foi instalado mas NÃO foi iniciado.\n\nPara ativar o agente:\n\n1. Obtenha seu serial em:\n http://painel.dnsblock.com.br\n\n2. Edite o arquivo:\n $INSTALL_DIR/config.json\n\n3. Inicie o serviço:\n systemctl start dnsblock-agent" 18 60 fi } # ============================================================================ # FUNÇÃO DE DESINSTALAÇÃO # ============================================================================ desinstalar() { if [ ! -d "$INSTALL_DIR" ] && [ ! -f "$SERVICE_FILE" ] && [ ! -f "$DNSBLOCK_CONF" ]; then whiptail --title "Não Instalado" \ --msgbox "O DNSBlock Agent não parece estar instalado." 8 50 exit 0 fi if ! whiptail --title "Confirmar Desinstalação" \ --yesno "Você está prestes a desinstalar o DNSBlock Agent.\n\nTodos os arquivos e configurações serão removidos.\n\nDeseja continuar?" 12 55; then exit 0 fi # Exibir progresso { echo "10"; echo "# Parando serviço..." systemctl stop dnsblock-agent 2>/dev/null || true sleep 0.3 echo "30"; echo "# Desabilitando serviço..." systemctl disable dnsblock-agent 2>/dev/null || true sleep 0.3 echo "50"; echo "# Removendo arquivo de serviço..." rm -f "$SERVICE_FILE" systemctl daemon-reload sleep 0.3 echo "70"; echo "# Removendo configuração do Unbound..." remover_configuracao_unbound sleep 0.3 echo "90"; echo "# Removendo arquivos..." rm -rf "$INSTALL_DIR" sleep 0.3 echo "100"; echo "# Concluído!" } | whiptail --title "DNSBlock Agent - Desinstalação" --gauge "Removendo DNSBlock Agent..." 8 60 0 whiptail --title "Desinstalação Concluída" \ --msgbox "O DNSBlock Agent foi completamente removido do sistema." 8 55 } # ============================================================================ # MENU PRINCIPAL # ============================================================================ menu_principal() { local opcao opcao=$(whiptail --title "DNSBlock Agent" \ --menu "Selecione uma opção:" 15 60 4 \ "1" "Instalar DNSBlock Agent" \ "2" "Desinstalar DNSBlock Agent" \ "3" "Sair" \ 3>&1 1>&2 2>&3) local status=$? if [ $status -ne 0 ] || [ "$opcao" = "3" ]; then exit 0 fi case "$opcao" in 1) instalar ;; 2) desinstalar ;; esac } # ============================================================================ # INÍCIO DO SCRIPT # ============================================================================ # Verificar root verificar_root # Processar argumentos case "${1:-}" in install) instalar ;; uninstall|remove) desinstalar ;; --help|-h) echo "" echo "DNSBlock Agent - Script de Instalação" echo "" echo "Uso: $0 [install|uninstall]" echo "" echo "Opções:" echo " install Instalar o DNSBlock Agent" echo " uninstall Desinstalar o DNSBlock Agent" echo " --help Exibir esta mensagem" echo "" echo "Se executado sem argumentos, exibe o menu interativo." echo "" ;; "") menu_principal ;; *) echo "Opção inválida: $1" echo "Use --help para ver as opções disponíveis." exit 1 ;; esac