#!/bin/bash # ==============================================================================# # INSTALADOR INTELIGENTE DO SERVIÇO PROXY-SINC (VERSÃO PROFISSIONAL) # # # # # # Descrição: Instala ou atualiza o serviço de versionamento, guardando as # # configurações de forma persistente. # # ==============================================================================# set -e # --- Variáveis de Configuração --- REPO_DIR="/opt/config_repo" SCRIPT_INSTALL_DIR="/usr/local/sbin" SYSTEMD_DIR="/etc/systemd/system" MAN_DIR="/usr/share/man/man8" CONFIG_DIR="/etc/proxy-sinc" # Ficheiro para guardar as credenciais do Git de forma persistente. CREDENTIALS_FILE="${CONFIG_DIR}/git.conf" PATHS_FILE="${CONFIG_DIR}/paths.conf" UPDATE_SCRIPT_URL="http://git.itguys.com.br/joao.goncalves/NgixProxy_Pathfinder/raw/branch/main/Instal-Proxy-Sinc.sh" # --- Funções de Ajuda --- info() { echo -e "\e[32m[INFO]\e[0m $1"; } error() { echo -e "\e[31m[ERRO]\e[0m $1" >&2; exit 1; } warn() { echo -e "\e[33m[AVISO]\e[0m $1"; } # --- Início da Execução --- info "Iniciando a instalação/atualização do serviço Proxy-Sinc..." if [ "$EUID" -ne 0 ]; then error "Este script precisa de ser executado como root."; fi # --- 1. Verificação de Dependências --- info "A verificar as dependências (git, rsync)..." apt-get update > /dev/null apt-get install -y git rsync > /dev/null if ! command -v man &> /dev/null; then warn "O comando 'man' não foi encontrado. A instalar 'man-db'..." apt-get install -y man-db > /dev/null fi info "Dependências satisfeitas." # --- 2. Lógica de Instalação vs. Atualização --- mkdir -p "$CONFIG_DIR" if [ -f "$CREDENTIALS_FILE" ]; then # MODO DE ATUALIZAÇÃO: Carrega as credenciais existentes. info "Ficheiro de configuração encontrado. A executar em modo de atualização." source "$CREDENTIALS_FILE" read -p "Identificação do Colaborador para o registo de ATUALIZAÇÃO: " DEPLOYER_ID ACTION_TYPE="Atualização Manual" else # MODO DE INSTALAÇÃO: Pede as credenciais pela primeira vez. info "Nenhum ficheiro de configuração encontrado. A executar em modo de instalação inicial." read -p "Por favor, insira a URL HTTP ou HTTPS do seu repositório Gitea: " GIT_URL read -p "Por favor, insira o seu NOME DE UTILIZADOR do Gitea: " GITEA_USERNAME read -s -p "Por favor, insira o seu TOKEN DE ACESSO do Gitea (ficará oculto): " GITEA_TOKEN echo "" read -p "Identificação do Colaborador para o registo de INSTALAÇÃO: " DEPLOYER_ID ACTION_TYPE="Instalação Manual Inicial" if [ -z "$GIT_URL" ] || [ -z "$GITEA_USERNAME" ] || [ -z "$GITEA_TOKEN" ] || [ -z "$DEPLOYER_ID" ]; then error "Todos os campos são obrigatórios." fi # Guarda as credenciais para uso futuro. info "A guardar as credenciais em ${CREDENTIALS_FILE}..." ( echo "GIT_URL=\"$GIT_URL\"" echo "GITEA_USERNAME=\"$GITEA_USERNAME\"" echo "GITEA_TOKEN=\"$GITEA_TOKEN\"" ) > "$CREDENTIALS_FILE" chmod 600 "$CREDENTIALS_FILE" # Torna o ficheiro legível apenas pelo root. fi # --- 3. Configuração do Repositório Git --- GIT_PROTOCOL=$(echo "$GIT_URL" | grep -o '^https\?://') GIT_DOMAIN_PATH=$(echo "$GIT_URL" | sed -e 's|https\?://||') AUTH_GIT_URL="${GIT_PROTOCOL}${GITEA_USERNAME}:${GITEA_TOKEN}@${GIT_DOMAIN_PATH}" SERVER_HOSTNAME=$(hostname -f) GIT_COMMIT_NAME="$SERVER_HOSTNAME" GIT_COMMIT_EMAIL="${SERVER_HOSTNAME%%.*}@itguys.com.br" info "O autor dos commits será definido como: $GIT_COMMIT_NAME <$GIT_COMMIT_EMAIL>" # Testa a conexão SSL de forma inteligente. SSL_VERIFY="true" if ! git -c http.sslVerify=true ls-remote "$GIT_URL" &> /dev/null; then warn "A conexão com verificação SSL falhou. A tentar novamente sem verificação..." if git -c http.sslVerify=false ls-remote "$GIT_URL" &> /dev/null; then warn "Conexão bem-sucedida sem verificação SSL. O repositório será configurado para ignorar os erros de certificado." SSL_VERIFY="false" else error "Não foi possível conectar ao repositório Git." fi else info "Conexão com verificação SSL bem-sucedida." fi # CORREÇÃO DO ERRO: Verifica se o diretório existe ANTES de tentar clonar. if [ -d "$REPO_DIR/.git" ]; then warn "O diretório do repositório $REPO_DIR já existe. A reconfigurar..." cd "$REPO_DIR" git remote set-url origin "$AUTH_GIT_URL" info "URL do remoto 'origin' atualizada." else info "A clonar o repositório para $REPO_DIR..." # Remove o diretório se ele existir mas não for um repo, para evitar o erro. rm -rf "$REPO_DIR" git clone "$GIT_URL" "$REPO_DIR" cd "$REPO_DIR" info "A configurar a URL do remoto com as credenciais..." git remote set-url origin "$AUTH_GIT_URL" fi git config user.name "$GIT_COMMIT_NAME" git config user.email "$GIT_COMMIT_EMAIL" git config http.sslVerify "$SSL_VERIFY" info "Repositório configurado com sucesso." # --- 4. Gerar Ficheiro de Deploy --- DEPLOY_LOG_DIR="$REPO_DIR/_deployment_logs" DEPLOY_LOG_FILE="${DEPLOY_LOG_DIR}/${SERVER_HOSTNAME}.md" info "A criar/atualizar o registo de deploy..." mkdir -p "$DEPLOY_LOG_DIR" if [ ! -f "$DEPLOY_LOG_FILE" ]; then echo "# Registo de Deploy do Proxy-Sinc para ${SERVER_HOSTNAME}" > "$DEPLOY_LOG_FILE" fi echo "" >> "$DEPLOY_LOG_FILE" echo "---" >> "$DEPLOY_LOG_FILE" echo "**Tipo de Ação:** ${ACTION_TYPE}" >> "$DEPLOY_LOG_FILE" echo "**Executado por:** ${DEPLOYER_ID}" >> "$DEPLOY_LOG_FILE" echo "**Data:** $(date)" >> "$DEPLOY_LOG_FILE" git add "$DEPLOY_LOG_FILE" git commit -m "[Deploy] ${ACTION_TYPE} por ${DEPLOYER_ID} em ${SERVER_HOSTNAME}" git push origin main info "Registo de deploy enviado para o Gitea." # --- 5. Gerar os Ficheiros do Serviço --- info "A gerar e a instalar os ficheiros do serviço..." if [ ! -f "$PATHS_FILE" ]; then info "A criar o ficheiro de caminhos padrão em $PATHS_FILE" echo "# Adicione aqui os caminhos completos para os ficheiros e diretórios que deseja versionar." > "$PATHS_FILE" echo "/etc/nginx" >> "$PATHS_FILE" echo "/etc/fail2ban" >> "$PATHS_FILE" fi # Gera o script principal de commit cat > "$SCRIPT_INSTALL_DIR/commit_configs.sh" << 'EOF' #!/bin/bash set -e REPO_PATH="/opt/config_repo" CONFIG_DIR="/etc/proxy-sinc" PATHS_FILE="${CONFIG_DIR}/paths.conf" AUTOMATION_FILES_SOURCE=("/usr/local/sbin/commit_configs.sh" "/usr/local/sbin/proxy-sinc-update" "/etc/systemd/system/proxy-sinc.service" "/etc/systemd/system/proxy-sinc.timer" "/etc/systemd/system/proxy-sinc-update.service" "/etc/systemd/system/proxy-sinc-update.timer" "/usr/share/man/man8/proxy-sinc.8.gz" "${PATHS_FILE}" "${CONFIG_DIR}/git.conf") AUTOMATION_FILES_DEST="$REPO_PATH/_automation_scripts/" log_info() { echo "[INFO] $1"; } log_info "--- Iniciando a verificação de sincronização [$(date)] ---" if [ "$EUID" -ne 0 ]; then echo "[ERRO] O script deve ser executado como root." >&2; exit 1; fi if [ ! -d "$REPO_PATH/.git" ]; then echo "[ERRO] O diretório $REPO_PATH não é um repositório Git válido." >&2; exit 1; fi log_info "Sincronizando ficheiros de configuração definidos em $PATHS_FILE..." if [ ! -f "$PATHS_FILE" ]; then echo "[AVISO] O ficheiro de caminhos $PATHS_FILE não foi encontrado." else while IFS= read -r path_to_sync || [ -n "$path_to_sync" ]; do if [ -z "$path_to_sync" ] || [[ "$path_to_sync" =~ ^# ]]; then continue; fi if [ -e "$path_to_sync" ]; then rsync -avz --delete --exclude='*.swp' --exclude='*.bak' --exclude='sites-enabled/' --exclude='modules-enabled/' --exclude='/var/log/' --exclude='/var/run/' --exclude='/var/cache/' "$path_to_sync" "$REPO_PATH/" else echo "[AVISO] O caminho '$path_to_sync' não existe. A ignorar." fi done < "$PATHS_FILE" fi log_info "Sincronizando ficheiros de automação..." mkdir -p "$AUTOMATION_FILES_DEST" for file in "${AUTOMATION_FILES_SOURCE[@]}"; do if [ -f "$file" ]; then rsync -aR "$file" "$AUTOMATION_FILES_DEST"; fi done cd "$REPO_PATH" # GARANTE A SEGURANÇA: Cria/atualiza o .gitignore para NUNCA versionar o ficheiro de credenciais. echo "_automation_scripts/etc/proxy-sinc/git.conf" > .gitignore log_info "A verificar o status do repositório Git..." if [ -n "$(git status --porcelain)" ]; then log_info "Alterações detetadas." git pull --ff-only git add . COMMIT_MESSAGE="[Auto-Sync] Atualização das configurações em $(hostname -f) - $(date +'%Y-%m-%d %H:%M:%S')" log_info "A fazer o commit com a mensagem: $COMMIT_MESSAGE" git commit -m "$COMMIT_MESSAGE" log_info "A enviar as alterações para o Gitea (git push)..." git push origin main echo "[SUCESSO] As alterações foram enviadas para o repositório remoto!" else log_info "Nenhuma alteração de configuração detetada." fi log_info "--- Verificação de sincronização concluída [$(date)] ---" exit 0 EOF # Gera o script de atualização cat > "$SCRIPT_INSTALL_DIR/proxy-sinc-update" << EOF #!/bin/bash set -e echo "A procurar por atualizações para o serviço Proxy-Sinc..." UPDATE_SCRIPT_URL="${UPDATE_SCRIPT_URL}" TEMP_SCRIPT="/tmp/setup_latest.sh" echo "A baixar a versão mais recente do instalador de: \$UPDATE_SCRIPT_URL" SSL_VERIFY_FLAG="" if [ -f "/etc/proxy-sinc/git.conf" ] && [ -d "/opt/config_repo/.git" ]; then if [ "\$(cd /opt/config_repo && git config --get http.sslVerify)" == "false" ]; then SSL_VERIFY_FLAG="--insecure" fi fi if curl \$SSL_VERIFY_FLAG -L "\$UPDATE_SCRIPT_URL" -o "\$TEMP_SCRIPT"; then chmod +x "\$TEMP_SCRIPT" echo "Instalador baixado com sucesso. A executar a atualização..." sudo "\$TEMP_SCRIPT" rm "\$TEMP_SCRIPT" echo "Atualização concluída!" else echo "ERRO: Falha ao baixar o script de atualização." >&2; exit 1 fi exit 0 EOF # Gera os ficheiros de serviço do systemd cat > "$SYSTEMD_DIR/proxy-sinc.service" << 'EOF' [Unit] Description=Serviço de Sincronização de Configurações do Nginx para o Git [Service] Type=oneshot ExecStart=/usr/local/sbin/commit_configs.sh EOF cat > "$SYSTEMD_DIR/proxy-sinc.timer" << 'EOF' [Unit] Description=Executa o serviço de sincronização de configurações a cada minuto [Timer] OnBootSec=1min OnUnitActiveSec=1min Unit=proxy-sinc.service [Install] WantedBy=timers.target EOF # Gera os ficheiros de serviço para a verificação de atualizações semanal cat > "$SYSTEMD_DIR/proxy-sinc-update.service" << 'EOF' [Unit] Description=Serviço de Verificação Semanal de Atualizações para o Proxy-Sinc [Service] Type=oneshot ExecStart=/usr/local/sbin/proxy-sinc-update EOF cat > "$SYSTEMD_DIR/proxy-sinc-update.timer" << 'EOF' [Unit] Description=Executa a verificação de atualizações do Proxy-Sinc toda Segunda-feira [Timer] OnCalendar=Mon *-*-* 03:00:00 RandomizedDelaySec=1h Unit=proxy-sinc-update.service [Install] WantedBy=timers.target EOF # Gera a nova man page cat > "$MAN_DIR/proxy-sinc.8" << 'EOF' .TH PROXY-SINC 8 "Setembro 2025" "iT Guys - Equipa de Infraestrutura" "Ferramentas de Sistema" .SH NAME proxy-sinc \- Serviço de versionamento automático de configurações de servidor. .SH SYNOPSIS .B systemctl status proxy-sinc.timer .br .B journalctl -u proxy-sinc.service .br .B proxy-sinc-update .br .B man proxy-sinc .SH DESCRIPTION .B proxy-sinc é um serviço de sistema que automatiza o controlo de versões de ficheiros de configuração críticos. A cada minuto, ele executa um script que sincroniza os ficheiros e diretórios definidos em \fI/etc/proxy-sinc/paths.conf\fR para um repositório Git. Se forem detetadas alterações, ele cria um commit e envia as alterações para um repositório Git remoto (Gitea). .PP Esta abordagem garante um histórico completo de todas as alterações, facilita a recuperação de desastres e serve como um backup centralizado. .SH CONFIGURAÇÃO .SS Adicionar/Remover Ficheiros para Sincronização A gestão dos ficheiros e diretórios a serem sincronizados é feita através do ficheiro de texto: .TP \fB/etc/proxy-sinc/paths.conf\fR Adicione um caminho absoluto por linha. Linhas vazias ou que começam com '#' são ignoradas. O script irá sincronizar cada caminho para a raiz do repositório Git. .sp Exemplo de conteúdo para \fI/etc/proxy-sinc/paths.conf\fR: .nf # Ficheiros e diretórios a serem versionados /etc/nginx /etc/fail2ban /etc/zabbix/zabbix_agentd.d/meu_parametro.conf .fi .SS Ver as Credenciais do Repositório As credenciais (URL, Utilizador, Token) usadas para a autenticação com o Gitea são guardadas de forma segura no seguinte ficheiro, que só pode ser lido pelo root: .TP \fB/etc/proxy-sinc/git.conf\fR Para ver o conteúdo, use o comando: \fIsudo cat /etc/proxy-sinc/git.conf\fR .SH AUDITORIA E HISTÓRICO .SS Histórico de Deploy O script regista cada instalação e atualização manual no repositório Git. Para ver quem e quando instalou ou atualizou o serviço neste servidor: .TP \fBcat /opt/config_repo/_deployment_logs/$(hostname -f).md\fR .SS Histórico de Alterações Para ver o histórico completo de todas as alterações de configuração sincronizadas, use os comandos padrão do git dentro do diretório do repositório: .TP \fBcd /opt/config_repo && sudo git log --oneline\fR .SH ATUALIZAÇÃO .SS ATUALIZAÇÃO MANUAL Para forçar uma atualização do serviço e dos seus scripts para a versão mais recente, execute o seguinte comando como root: .sp \fBproxy-sinc-update\fR .sp Este comando irá baixar e executar a versão mais recente do script de instalação. Ele irá ler as suas credenciais guardadas e pedir apenas a sua identificação de colaborador para o registo de deploy. .SS ATUALIZAÇÃO AUTOMÁTICA O sistema inclui um timer (\fIproxy-sinc-update.timer\fR) que executa o comando \fBproxy-sinc-update\fR automaticamente uma vez por semana (toda Segunda-feira às 3 da manhã). .SH DESINSTALAÇÃO Para remover completamente o serviço e os seus componentes, execute o script de instalação original com o argumento 'uninstall': .sp \fB/caminho/para/Instal-Proxy-Sinc.sh uninstall\fR .sp Ele irá parar os serviços, remover todos os ficheiros de sistema e perguntar se deseja apagar o diretório de configuração e o repositório local. .SH FICHEIROS .TP \fB/usr/local/sbin/commit_configs.sh\fR O script principal que executa a sincronização a cada minuto. .TP \fB/usr/local/sbin/proxy-sinc-update\fR O script que gere a auto-atualização do serviço. .TP \fB/etc/systemd/system/proxy-sinc.timer\fR O timer que define a frequência da SINCRONIZAÇÃO (a cada minuto). .TP \fB/etc/systemd/system/proxy-sinc-update.timer\fR O timer que define a frequência da VERIFICAÇÃO DE ATUALIZAÇÕES (semanal). .SH SEE ALSO .BR git (1), .BR rsync (1), .BR systemd.service (5), .BR systemd.timer (5) EOF # --- 6. Ativar os Serviços --- info "A recarregar o systemd e a ativar os timers..." systemctl daemon-reload systemctl enable --now proxy-sinc.timer systemctl enable --now proxy-sinc-update.timer info "Serviços ativados e a correr!" # --- Conclusão --- echo "" info "======================================================================" info " Instalação/Atualização Concluída!" info "======================================================================" info "O serviço 'proxy-sinc' está agora ativo." info "" info "Comandos úteis:" info " Ver o status do timer de sincronização: systemctl status proxy-sinc.timer" info " Ver os logs da última execução: journalctl -u proxy-sinc.service" info " Para forçar uma atualização agora: sudo proxy-sinc-update" info " Ler o manual de ajuda: man proxy-sinc" info " Para adicionar novos ficheiros/pastas, edite: /etc/proxy-sinc/paths.conf" info ""